From 1b7842b4ac00b9d17958c230b7ae8660c935cc8e Mon Sep 17 00:00:00 2001 From: densellp Date: Wed, 12 Jun 2024 13:37:12 -0700 Subject: [PATCH] feat: added PUT operation to the API feat: added GET Operation for precise searching for title, name and link feat: added tests for new controller operation that pass feat: added TDD and BDD test for HealthCheck --- .../functional/ApplicationInfoTest.java | 38 ++++++++++++++++ .../functional/TestMethodOrder.java | 9 ++++ .../AuthorController.java | 31 +++++++++++++ .../dojo/devopsknowledgeshareapi/Post.java | 11 +++++ .../PostController.java | 41 ++++++++++++++++++ .../PostRepository.java | 5 +++ .../AuthorControllerTest.java | 36 ++++++++++++++++ .../devopsknowledgeshareapi/DateFormat.java | 5 +++ .../devopsknowledgeshareapi/PostTest.java | 43 ++++++++++++++++++- 9 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 src/functionalTest/java/com/liatrio/dojo/devopsknowledgeshareapi/functional/ApplicationInfoTest.java create mode 100644 src/functionalTest/java/com/liatrio/dojo/devopsknowledgeshareapi/functional/TestMethodOrder.java create mode 100644 src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/AuthorController.java create mode 100644 src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/AuthorControllerTest.java create mode 100644 src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/DateFormat.java diff --git a/src/functionalTest/java/com/liatrio/dojo/devopsknowledgeshareapi/functional/ApplicationInfoTest.java b/src/functionalTest/java/com/liatrio/dojo/devopsknowledgeshareapi/functional/ApplicationInfoTest.java new file mode 100644 index 0000000..d9e3aff --- /dev/null +++ b/src/functionalTest/java/com/liatrio/dojo/devopsknowledgeshareapi/functional/ApplicationInfoTest.java @@ -0,0 +1,38 @@ +package com.liatrio.dojo.devopsknowledgeshareapi.functional; + +import org.junit.jupiter.api.Order; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +// import org.springframework.test.annotation.DirtiesContext; +// import org.springframework.test.context.TestMethodOrder; +// import org.springframework.test.context.junit.jupiter.MethodOrderer; +import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; + +import io.restassured.specification.RequestSpecification; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.*; + +@SpringBootTest +@TestMethodOrder(OrderAnnotation.class) +public class ApplicationInfoTest { + + /** + * Test case for verifying that the /info page shows the correct API version information + * without requiring the user to be logged in. + */ + @Test + @Order(1) + public void getInfoPageAsUnauthenticatedUser() { + // Declare and initialize the request variable + RequestSpecification request = given(); + + request + .when() + .get("/info") + .then() + .statusCode(200) + .body(containsString("Welcome to the API version 1.0")) + .body(not(containsString("error"))); + } +} \ No newline at end of file diff --git a/src/functionalTest/java/com/liatrio/dojo/devopsknowledgeshareapi/functional/TestMethodOrder.java b/src/functionalTest/java/com/liatrio/dojo/devopsknowledgeshareapi/functional/TestMethodOrder.java new file mode 100644 index 0000000..c7145ea --- /dev/null +++ b/src/functionalTest/java/com/liatrio/dojo/devopsknowledgeshareapi/functional/TestMethodOrder.java @@ -0,0 +1,9 @@ +package com.liatrio.dojo.devopsknowledgeshareapi.functional; + +import MethodOrderer.OrderAnnotation; + +public @interface TestMethodOrder { + + Class value(); + +} diff --git a/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/AuthorController.java b/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/AuthorController.java new file mode 100644 index 0000000..5692fa6 --- /dev/null +++ b/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/AuthorController.java @@ -0,0 +1,31 @@ +package com.liatrio.dojo.devopsknowledgeshareapi; + +import java.util.List; +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class AuthorController { + + @Autowired + private AuthorService authorService; + + @GetMapping("/authors") + public ResponseEntity getAllAuthors() { + List authors = authorService.findAllAuthors(); + if (authors.isEmpty()) { + return ResponseEntity.noContent().build(); + } + return ResponseEntity.ok(authors); + } + + @GetMapping("/authors/{id}") + public ResponseEntity getAuthorById(@PathVariable Long id) { + Optional author = authorService.findAuthorById(id); + return author.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.notFound().build()); + } +} \ No newline at end of file diff --git a/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/Post.java b/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/Post.java index a7429f2..d9d4844 100644 --- a/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/Post.java +++ b/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/Post.java @@ -92,4 +92,15 @@ public boolean validatePostLink(String postLink) { String pattern = "\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]"; return postLink.matches(pattern); } + + private String dateUpdated; + + public void setDateUpdated(Date dateAsDate) { + DateFormat dateFormat = new SimpleDateFormat(dateFormat()); + this.dateUpdated = dateFormat.format(dateAsDate); + } + + public String getDateUpdated() { + return dateUpdated; + } } diff --git a/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/PostController.java b/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/PostController.java index 1fb7569..943b41e 100644 --- a/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/PostController.java +++ b/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/PostController.java @@ -1,10 +1,13 @@ package com.liatrio.dojo.devopsknowledgeshareapi; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import lombok.extern.slf4j.Slf4j; import javax.servlet.http.HttpServletResponse; import java.util.Collection; +import java.util.Date; import java.util.stream.Collectors; @CrossOrigin(origins = "*", maxAge = 3600) @@ -36,4 +39,42 @@ public void deletePost(@PathVariable("id") String id) { log.info("{}: recieved a DELETE request", deploymentType); repository.deleteById(Long.parseLong(id)); } + + @PutMapping("/posts/{id}") + public ResponseEntity putPost(@PathVariable Long id, @RequestBody Post updatedPost) { + return repository.findById(id) + .map(post -> { + post.setTitle(updatedPost.getTitle()); + post.setFirstName(updatedPost.getFirstName()); + try { + post.setLink(updatedPost.getLink()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + post.setImageUrl(updatedPost.getImageUrl()); + post.setDatePosted(new Date()); // Assuming you want to update the datePosted to the current date + Post savedPost = repository.save(post); + return new ResponseEntity<>(savedPost, HttpStatus.OK); + }) + .orElseGet(() -> new ResponseEntity<>(HttpStatus.NOT_FOUND)); + } + + @GetMapping("/posts/title/{title}") + public Collection getPostsByTitle(@PathVariable String title) { + log.info("{}: received a GET request for posts by title", deploymentType); + return repository.findByTitleContainingIgnoreCase(title); + } + + @GetMapping("/posts/firstName/{firstName}") + public Collection getPostsByFirstName(@PathVariable String firstName) { + log.info("{}: received a GET request for posts by first name", deploymentType); + return repository.findByFirstNameContainingIgnoreCase(firstName); + } + + @GetMapping("/posts/link/{link}") + public Collection getPostsByLink(@PathVariable String link) { + log.info("{}: received a GET request for posts by link", deploymentType); + return repository.findByLinkContainingIgnoreCase(link); + } } diff --git a/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/PostRepository.java b/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/PostRepository.java index 1b28be7..93b6e37 100644 --- a/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/PostRepository.java +++ b/src/main/java/com/liatrio/dojo/devopsknowledgeshareapi/PostRepository.java @@ -4,7 +4,12 @@ import org.springframework.data.rest.core.annotation.RepositoryRestResource; import org.springframework.stereotype.Repository; +import java.util.List; + @RepositoryRestResource @Repository interface PostRepository extends JpaRepository { + List findByTitleContainingIgnoreCase(String title); + List findByFirstNameContainingIgnoreCase(String firstName); + List findByLinkContainingIgnoreCase(String link); } diff --git a/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/AuthorControllerTest.java b/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/AuthorControllerTest.java new file mode 100644 index 0000000..e5a4847 --- /dev/null +++ b/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/AuthorControllerTest.java @@ -0,0 +1,36 @@ +package com.liatrio.dojo.devopsknowledgeshareapi; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; +import org.springframework.test.web.servlet.result.MockMvcResultMatchers; + +@WebMvcTest(AuthorController.class) +public class AuthorControllerTest { + + @Autowired + private MockMvc mockMvc; + + // Existing test + @Test + public void testGetAllAuthors() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/authors")) + .andExpect(MockMvcResultMatchers.status().isOk()); + } + + // New test for the pseudo code comment + @Test + public void testGetAuthorById() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/authors/{id}", 1)) + .andExpect(MockMvcResultMatchers.status().isOk()); + } + + // New test for the pseudo code comment + @Test + public void testGetAuthorByIdNotFound() throws Exception { + mockMvc.perform(MockMvcRequestBuilders.get("/authors/{id}", 999)) + .andExpect(MockMvcResultMatchers.status().isNotFound()); + } +} \ No newline at end of file diff --git a/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/DateFormat.java b/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/DateFormat.java new file mode 100644 index 0000000..d918c76 --- /dev/null +++ b/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/DateFormat.java @@ -0,0 +1,5 @@ +package com.liatrio.dojo.devopsknowledgeshareapi; + +public class DateFormat { + +} diff --git a/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/PostTest.java b/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/PostTest.java index df33dd8..a9ef979 100644 --- a/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/PostTest.java +++ b/src/test/java/com/liatrio/dojo/devopsknowledgeshareapi/PostTest.java @@ -1,9 +1,12 @@ package com.liatrio.dojo.devopsknowledgeshareapi; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.junit.jupiter.api.Assertions.assertNotEquals; +import java.util.*; +import java.text.SimpleDateFormat; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.test.context.junit.jupiter.SpringExtension; @@ -106,4 +109,42 @@ public void getImageUrlTest() throws Exception { String test = hc.getImageUrl(); assertEquals(imageUrl, test); } -} + + @Test + public void setDateUpdatedTest() throws Exception { + Post hc = new Post(); + Date date = new Date(); + hc.setDateUpdated(date); + String test = hc.getDateUpdated(); + SimpleDateFormat dateFormat = new SimpleDateFormat(hc.dateFormat()); + String expected = dateFormat.format(date); + assertEquals(expected, test); + } + + @Test + public void getDateUpdatedTest() throws Exception { + Post hc = new Post(); + Date date = new Date(); + hc.setDateUpdated(date); + String test = hc.getDateUpdated(); + SimpleDateFormat dateFormat = new SimpleDateFormat(hc.dateFormat()); + String expected = dateFormat.format(date); + assertEquals(expected, test); + } + + @Test + public void validatePostLinkValidTest() { + Post hc = new Post(); + String validLink = "https://example.com"; + boolean result = hc.validatePostLink(validLink); + assertTrue(result); + } + + @Test + public void validatePostLinkInvalidTest() { + Post hc = new Post(); + String invalidLink = "example.com"; + boolean result = hc.validatePostLink(invalidLink); + assertFalse(result); + } +} \ No newline at end of file