diff --git a/pom.xml b/pom.xml
index 67931c2..f502e59 100644
--- a/pom.xml
+++ b/pom.xml
@@ -5,7 +5,7 @@
org.springframework.boot
spring-boot-starter-parent
- 3.1.6
+ 3.2.0
diff --git a/src/main/java/com/alura/aluraflixapi/controller/VideoController.java b/src/main/java/com/alura/aluraflixapi/controller/VideoController.java
index 552bf6d..57f7157 100644
--- a/src/main/java/com/alura/aluraflixapi/controller/VideoController.java
+++ b/src/main/java/com/alura/aluraflixapi/controller/VideoController.java
@@ -12,8 +12,6 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
@@ -36,7 +34,7 @@
@SecurityRequirement(name = "bearer-key")
public class VideoController {
- private static final String LOGGIN_PREFIX = "[VideoController]";
+ private static final String LOGGING_PREFIX = "[VideoController]";
private final VideoService service;
@@ -47,10 +45,10 @@ public VideoController(final VideoService service) {
@GetMapping(produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity> getVideos(Pageable pageable) {
- log.info("{} Request to get All videos", LOGGIN_PREFIX);
+ log.info("{} Request to get All videos", LOGGING_PREFIX);
final Page videos = this.service.getVideos(pageable);
if (videos.hasContent()) {
- log.info("{} Response {}: ", LOGGIN_PREFIX, videos);
+ log.info("{} Response {}: ", LOGGING_PREFIX, videos);
return ResponseEntity.ok().body(videos);
} else {
return ResponseEntity.noContent().build();
@@ -60,7 +58,7 @@ public ResponseEntity> getVideos(Pageable pageable) {
@GetMapping("/{id}")
public ResponseEntity getById(@NotBlank @PathVariable final String id) {
- log.info("{} Request to get a video by ID: {}", LOGGIN_PREFIX, id);
+ log.info("{} Request to get a video by ID: {}", LOGGING_PREFIX, id);
return Optional.ofNullable(service.getById(id))
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
@@ -70,7 +68,7 @@ public ResponseEntity getById(@NotBlank @PathVariable final String id)
@PostMapping
public ResponseEntity save(@Valid @RequestBody final VideoDto dto,
final UriComponentsBuilder uriBuilder) {
- log.info("{} Request to Save a new video: {}", LOGGIN_PREFIX, dto);
+ log.info("{} Request to Save a new video: {}", LOGGING_PREFIX, dto);
final VideoDto videoDto = this.service.save(dto);
//good practices to return the Location in the Header to be search by Id
//return Http code 201 and Localtion with Id
@@ -81,10 +79,10 @@ public ResponseEntity save(@Valid @RequestBody final VideoDto dto,
@PutMapping
public ResponseEntity update(@Valid @RequestBody final UpdateVideoDto dto,
final UriComponentsBuilder uriBuilder) {
- log.info("{} Request to update a video: {}", LOGGIN_PREFIX, dto);
+ log.info("{} Request to update a video: {}", LOGGING_PREFIX, dto);
final var videoDto = this.service.updateMovie(dto);
//good practices to return the Location in the Header to be search by Id
- //return Http code 201 and Localtion with Id
+ //return Http code 201 and Location with Id
return ResponseEntity.created(uriBuilder.path("/videos/{id}")
.buildAndExpand(videoDto.id())
.toUri()).body(videoDto);
@@ -93,16 +91,16 @@ public ResponseEntity update(@Valid @RequestBody final UpdateVid
@DeleteMapping("/{id}")
@Secured("ROLE_ADMIN")
public ResponseEntity delete(@NotBlank @PathVariable final String id) {
- log.info("{} Request to Delete a video by ID: {}", LOGGIN_PREFIX, id);
+ log.info("{} Request to Delete a video by ID: {}", LOGGING_PREFIX, id);
final Optional dto = this.service.delete(id);
return dto.map(videoDto -> ResponseEntity.status(HttpStatus.NO_CONTENT).body(videoDto))
.orElseGet(() -> ResponseEntity.noContent().build());
}
- @GetMapping("/search")
+ @GetMapping("/title")
public ResponseEntity> getVideosByTitle(
@NotBlank @RequestParam("title") final String title) {
- log.info("{} Request to get a video by title: {}", LOGGIN_PREFIX, title);
+ log.info("{} Request to get a video by title: {}", LOGGING_PREFIX, title);
final var videosByTitle = this.service.getVideosByTitle(title);
if (videosByTitle.isEmpty()) {
return ResponseEntity.noContent().build();
diff --git a/src/test/java/com/alura/aluraflixapi/controller/CategoryControllerTest.java b/src/test/java/com/alura/aluraflixapi/controller/CategoryControllerTest.java
index fa343c1..aed72f2 100644
--- a/src/test/java/com/alura/aluraflixapi/controller/CategoryControllerTest.java
+++ b/src/test/java/com/alura/aluraflixapi/controller/CategoryControllerTest.java
@@ -25,7 +25,6 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
-import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import java.util.Arrays;
import java.util.List;
diff --git a/src/test/java/com/alura/aluraflixapi/controller/VideoControllerTest.java b/src/test/java/com/alura/aluraflixapi/controller/VideoControllerTest.java
index 277c677..2c948c2 100644
--- a/src/test/java/com/alura/aluraflixapi/controller/VideoControllerTest.java
+++ b/src/test/java/com/alura/aluraflixapi/controller/VideoControllerTest.java
@@ -1,12 +1,5 @@
package com.alura.aluraflixapi.controller;
-import static org.junit.jupiter.api.Assertions.assertAll;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
-import static org.mockito.Mockito.when;
-import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
-import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
-
import com.alura.aluraflixapi.domain.category.Rating;
import com.alura.aluraflixapi.domain.category.dto.CategoryDto;
import com.alura.aluraflixapi.domain.video.dto.UpdateVideoDto;
@@ -19,16 +12,12 @@
import com.alura.aluraflixapi.infraestructure.service.CategoryService;
import com.alura.aluraflixapi.infraestructure.service.UserService;
import com.alura.aluraflixapi.infraestructure.service.VideoServiceImpl;
+import com.alura.aluraflixapi.jsonutils.ParseJson;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
-
-import java.util.Arrays;
-import java.util.List;
-import java.util.Optional;
-import java.util.UUID;
-
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mockito;
@@ -36,9 +25,7 @@
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.boot.test.mock.mockito.SpyBean;
-import org.springframework.data.domain.PageImpl;
-import org.springframework.data.domain.PageRequest;
-import org.springframework.data.domain.Pageable;
+import org.springframework.data.domain.*;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors;
@@ -46,8 +33,16 @@
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
-import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
-import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import static org.junit.jupiter.api.Assertions.*;
+import static org.mockito.Mockito.when;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(SpringExtension.class)
@@ -55,7 +50,9 @@
@WebMvcTest
//this annotation can be replaced at each test method scope
@WithMockUser(value = "admin", username = "admin", password = "admin", roles = "ADMIN")
-class VideoControllerTest {
+class VideoControllerTest extends ParseJson {
+
+ private static final String PREFIX_PATH = "/video/";
private static ObjectMapper mapper;
@@ -105,13 +102,15 @@ static void setup() {
}
@Test
+ @DisplayName("Should return all videos and response 200 OK")
void get_all_videos_test() throws Exception {
//Given
- final List videos = buildVideosDto();
+ final var jsonFile = getJsonFile(PREFIX_PATH + "getAllVideos_response_ok.json");
+ final var videosExpect = Arrays.stream(parseToJavaObject(jsonFile, VideoDto[].class)).toList();
//Workaround to fix JsonSerialize on Spring boot version 3.2.0
final var pageable = PageRequest.of(0, 10);
when(this.videoService.getVideos(Mockito.any()))
- .thenReturn(new PageImpl<>(videos, pageable, videos.size()));
+ .thenReturn(new PageImpl<>(videosExpect, pageable, videosExpect.size()));
final MvcResult response = this.mockMvc.perform(MockMvcRequestBuilders.get("/videos")
.contentType(MediaType.APPLICATION_JSON))
@@ -124,38 +123,54 @@ void get_all_videos_test() throws Exception {
class));
//Then
assertNotNull(videosDtos);
- assertEquals(4, videosDtos.size());
+ assertEquals(videosExpect.size(), videosDtos.size());
}
@Test
+ @DisplayName("Should not return all videos and response No Content")
+ void get_all_videos_response_no_content_test() throws Exception {
+ //Given
+ when(this.videoService.getVideos(Mockito.any()))
+ .thenReturn(Page.empty());
+
+ //Then
+ this.mockMvc.perform(MockMvcRequestBuilders.get("/videos")
+ .contentType(MediaType.APPLICATION_JSON))
+ .andDo(print())
+ .andExpect(status().is2xxSuccessful());
+ }
+
+ @Test
+ @DisplayName("Should return a video by Id and response 200 OK")
void get_video_by_id() throws Exception {
//Given
- final VideoDto request = buildVideosDto().get(0);
-
+ final var jsonFile = getJsonFile(PREFIX_PATH + "getById_video_response_ok.json");
+ final var videoDto = parseToJavaObject(jsonFile, VideoDto.class);
when(this.videoService.getById(Mockito.anyString()))
- .thenReturn(request);
+ .thenReturn(videoDto);
//When
- final MvcResult mvcResult = this.mockMvc.perform(MockMvcRequestBuilders.get("/videos/{id}", "1")
+ final MvcResult mvcResult = this.mockMvc.perform(MockMvcRequestBuilders.get("/videos/{id}", "63680c011892283477b3e9b9")
.contentType(MediaType.APPLICATION_JSON))
.andDo(print())
.andExpect(status().is2xxSuccessful())
.andReturn();
//Then
- VideoDto videoDto = mapper.readValue(mvcResult.getResponse().getContentAsString(),
+ VideoDto response = mapper.readValue(mvcResult.getResponse().getContentAsString(),
VideoDto.class);
assertNotNull(videoDto);
- assertAll(() -> assertEquals(request.id(), videoDto.id()),
- () -> Assertions.assertEquals(request.url(), videoDto.url()),
- () -> Assertions.assertEquals(request.description(), videoDto.description()),
- () -> Assertions.assertEquals(request.title(), videoDto.title())
+ assertAll(() -> assertEquals(response.id(), videoDto.id()),
+ () -> Assertions.assertEquals(response.url(), videoDto.url()),
+ () -> Assertions.assertEquals(response.description(), videoDto.description()),
+ () -> Assertions.assertEquals(response.title(), videoDto.title())
);
}
@Test
+ @DisplayName("Should create a new Video and response 200 OK")
void save_a_new_video_test() throws Exception {
//Given
@@ -189,15 +204,11 @@ void save_a_new_video_test() throws Exception {
}
@Test
+ @DisplayName("Should update a video by Id and return 200 OK")
void update_video_by_id_test() throws Exception {
-
//Given
- final var videoToUpdate =
- new UpdateVideoDto(UUID.randomUUID().toString(),
- "Hobbit: La batalla de los cincos ejercitos", "La batalla de los cincos ejercitos",
- "www.thehobbit2.com",
- new CategoryDto(UUID.randomUUID().toString(), Rating.FANTASY.name(), "Fantasy",
- "#FFD700"));
+ final var jsonFile = getJsonFile(PREFIX_PATH + "getById_video_response_ok.json");
+ final var videoToUpdate = parseToJavaObject(jsonFile, UpdateVideoDto.class);
when(this.videoService.updateMovie(Mockito.any()))
.thenReturn(videoToUpdate);
@@ -229,6 +240,7 @@ void update_video_by_id_test() throws Exception {
}
@Test
+ @DisplayName("Should allow delete a video by id and response No Content")
void delete_video_by_id_test() throws Exception {
//Given
@@ -241,38 +253,42 @@ void delete_video_by_id_test() throws Exception {
.andExpect(status().isNoContent());
}
+ @Test
+ @DisplayName("Should return a list of videos searched by title response OK")
+ void getVideosByTitle_test() throws Exception {
+ //Given
+ final var jsonFile = getJsonFile(PREFIX_PATH + "getVideoByTitle_response_ok.json");
+ final var videosByTitleExpected = Arrays.stream(parseToJavaObject(jsonFile, VideoDto[].class)).toList();
+ when(this.videoService.getVideosByTitle(Mockito.anyString()))
+ .thenReturn(videosByTitleExpected);
+
+ final MvcResult response = this.mockMvc.perform(MockMvcRequestBuilders.get("/videos/title")
+ .param("title", "The Hobbit - The battle of five armies")
+ .accept(MediaType.APPLICATION_JSON))
+ .andDo(print())
+ .andExpect(status().isFound())
+ .andReturn();
+
+ //Then
+ assertNotNull(response);
+ final var videosByTitleResponse = Arrays.stream(mapper.readValue(response.getResponse().getContentAsString(),
+ VideoDto[].class)).toList();
+ org.assertj.core.api.Assertions.assertThat(videosByTitleResponse).usingRecursiveComparison()
+ .isEqualTo(videosByTitleExpected);
+ }
+
+ @Test
+ @DisplayName("Should not return a list of videos searched by title response No Content")
+ void getVideosByTitle_response_no_content_test() throws Exception {
+ //Given
+ when(this.videoService.getVideosByTitle(Mockito.anyString()))
+ .thenReturn(List.of());
- private static List buildVideosDto() {
- final var categoryDto = new CategoryDto(UUID.randomUUID().toString(), Rating.FREE.name(),
- "Fantasy", "#FFD700");
- return List.of(VideoDto.builder()
- .id(UUID.randomUUID().toString())
- .title("Lord of the rings - fellowship of the ring")
- .description("Lord of the rings - fellowship of the ring")
- .url("http://www.lordoftherings.com")
- .category(categoryDto)
- .build(),
- VideoDto.builder()
- .id(UUID.randomUUID().toString())
- .title("Lord of the rings - return of the king")
- .description("Lord of the rings - return of the king")
- .url("http://www.lordoftherings.com")
- .category(categoryDto)
- .build(),
- VideoDto.builder()
- .id(UUID.randomUUID().toString())
- .title("Lord of the rings - The Two towers")
- .description("Lord of the rings - The Two towers")
- .url("http://www.lordoftherings.com")
- .category(categoryDto)
- .build(),
- VideoDto.builder()
- .id(UUID.randomUUID().toString())
- .title("The hobbit - unnespect adventure")
- .description("The hobbit - unnespect adventure")
- .url("http://www.thehobbit.com")
- .category(categoryDto)
- .build()
- );
+ final MvcResult response = this.mockMvc.perform(MockMvcRequestBuilders.get("/videos/title")
+ .param("title", "The Hobbit - The battle of five armies")
+ .accept(MediaType.APPLICATION_JSON))
+ .andDo(print())
+ .andExpect(status().isNoContent())
+ .andReturn();
}
}
\ No newline at end of file
diff --git a/src/test/resources/json/video/getVideoByTitle_response_ok.json b/src/test/resources/json/video/getVideoByTitle_response_ok.json
new file mode 100644
index 0000000..78ae321
--- /dev/null
+++ b/src/test/resources/json/video/getVideoByTitle_response_ok.json
@@ -0,0 +1,14 @@
+[
+ {
+ "id": "63680c011892283477b3e9b9",
+ "title": "The Hobbit - The battle of Five armies",
+ "description": "best movie ever",
+ "url": "https://theHobbitThebattleofivearmies.com",
+ "category": {
+ "id": "63f67ec16295ed744dd460cd",
+ "rating": "FREE",
+ "title": "Fantasy",
+ "colorHex": "#ffff83"
+ }
+ }
+]
\ No newline at end of file