From 0f9084100bacef839da6872d183a5b3db3225873 Mon Sep 17 00:00:00 2001 From: Pavlo Bystrytskyi Date: Thu, 17 Oct 2024 11:57:04 +0200 Subject: [PATCH] ISSUE-12: Create a POST create new relation actor-movie-relation endpoint and cover it with tests. --- ...troller.java => MovieActorController.java} | 18 +++--- .../com/example/backend/dto/IdRequest.java | 6 -- .../backend/dto/MovieActorRequest.java | 6 ++ ...eRelation.java => MovieActorRelation.java} | 2 +- ...java => MovieActorRelationRepository.java} | 4 +- .../example/backend/service/ActorService.java | 2 - ...vieService.java => MovieActorService.java} | 10 +-- .../controller/ActorControllerTest.java | 2 +- ...est.java => MovieActorControllerTest.java} | 61 ++++++++++--------- 9 files changed, 57 insertions(+), 54 deletions(-) rename backend/src/main/java/com/example/backend/controller/{ActorMovieController.java => MovieActorController.java} (64%) delete mode 100644 backend/src/main/java/com/example/backend/dto/IdRequest.java create mode 100644 backend/src/main/java/com/example/backend/dto/MovieActorRequest.java rename backend/src/main/java/com/example/backend/model/{ActorMovieRelation.java => MovieActorRelation.java} (94%) rename backend/src/main/java/com/example/backend/model/{ActorMovieRelationRepository.java => MovieActorRelationRepository.java} (54%) rename backend/src/main/java/com/example/backend/service/{ActorMovieService.java => MovieActorService.java} (72%) rename backend/src/test/java/com/example/backend/controller/{ActorMovieControllerTest.java => MovieActorControllerTest.java} (78%) diff --git a/backend/src/main/java/com/example/backend/controller/ActorMovieController.java b/backend/src/main/java/com/example/backend/controller/MovieActorController.java similarity index 64% rename from backend/src/main/java/com/example/backend/controller/ActorMovieController.java rename to backend/src/main/java/com/example/backend/controller/MovieActorController.java index dc81658..18953d0 100644 --- a/backend/src/main/java/com/example/backend/controller/ActorMovieController.java +++ b/backend/src/main/java/com/example/backend/controller/MovieActorController.java @@ -1,8 +1,8 @@ package com.example.backend.controller; import com.example.backend.dto.ActorResponse; -import com.example.backend.dto.IdRequest; -import com.example.backend.service.ActorMovieService; +import com.example.backend.dto.MovieActorRequest; +import com.example.backend.service.MovieActorService; import lombok.AllArgsConstructor; import lombok.NonNull; import org.springframework.http.HttpMethod; @@ -13,19 +13,19 @@ @RestController @AllArgsConstructor -@RequestMapping("/api/actor-movie") -public class ActorMovieController { +@RequestMapping("/api/movie-actor") +public class MovieActorController { - private final ActorMovieService actorMovieService; + private final MovieActorService movieActorService; - @PostMapping("/{movieId}") - public void addActorById(@PathVariable @NonNull Long movieId, @RequestBody IdRequest idRequest) { - actorMovieService.addActor(movieId, idRequest.id()); + @PostMapping() + public void addActorById(@RequestBody @NonNull MovieActorRequest movieActorRequest) { + movieActorService.addActor(movieActorRequest.movieId(), movieActorRequest.actorId()); } @GetMapping("/{movieId}") public List getActorsByMovieId(@PathVariable @NonNull Long movieId) { - return actorMovieService.getActorsByMovieId(movieId).stream().map(ActorResponse::from).toList(); + return movieActorService.getActorsByMovieId(movieId).stream().map(ActorResponse::from).toList(); } /** diff --git a/backend/src/main/java/com/example/backend/dto/IdRequest.java b/backend/src/main/java/com/example/backend/dto/IdRequest.java deleted file mode 100644 index 004d0c3..0000000 --- a/backend/src/main/java/com/example/backend/dto/IdRequest.java +++ /dev/null @@ -1,6 +0,0 @@ -package com.example.backend.dto; - -import lombok.NonNull; - -public record IdRequest(@NonNull Long id) { -} diff --git a/backend/src/main/java/com/example/backend/dto/MovieActorRequest.java b/backend/src/main/java/com/example/backend/dto/MovieActorRequest.java new file mode 100644 index 0000000..53e1ceb --- /dev/null +++ b/backend/src/main/java/com/example/backend/dto/MovieActorRequest.java @@ -0,0 +1,6 @@ +package com.example.backend.dto; + +import lombok.NonNull; + +public record MovieActorRequest(@NonNull Long movieId, @NonNull Long actorId) { +} diff --git a/backend/src/main/java/com/example/backend/model/ActorMovieRelation.java b/backend/src/main/java/com/example/backend/model/MovieActorRelation.java similarity index 94% rename from backend/src/main/java/com/example/backend/model/ActorMovieRelation.java rename to backend/src/main/java/com/example/backend/model/MovieActorRelation.java index 0168647..64cb8ba 100644 --- a/backend/src/main/java/com/example/backend/model/ActorMovieRelation.java +++ b/backend/src/main/java/com/example/backend/model/MovieActorRelation.java @@ -14,7 +14,7 @@ @UniqueConstraint(columnNames = {"actor_id", "movie_id"}) } ) -public class ActorMovieRelation { +public class MovieActorRelation { @Id @GeneratedValue private Long id; diff --git a/backend/src/main/java/com/example/backend/model/ActorMovieRelationRepository.java b/backend/src/main/java/com/example/backend/model/MovieActorRelationRepository.java similarity index 54% rename from backend/src/main/java/com/example/backend/model/ActorMovieRelationRepository.java rename to backend/src/main/java/com/example/backend/model/MovieActorRelationRepository.java index c12c0ef..89cf51e 100644 --- a/backend/src/main/java/com/example/backend/model/ActorMovieRelationRepository.java +++ b/backend/src/main/java/com/example/backend/model/MovieActorRelationRepository.java @@ -6,6 +6,6 @@ import java.util.List; @Repository -public interface ActorMovieRelationRepository extends JpaRepository { - List findByMovieId(Long movieId); +public interface MovieActorRelationRepository extends JpaRepository { + List findByMovieId(Long movieId); } diff --git a/backend/src/main/java/com/example/backend/service/ActorService.java b/backend/src/main/java/com/example/backend/service/ActorService.java index 30cde2b..534ec0d 100644 --- a/backend/src/main/java/com/example/backend/service/ActorService.java +++ b/backend/src/main/java/com/example/backend/service/ActorService.java @@ -1,8 +1,6 @@ package com.example.backend.service; import com.example.backend.model.Actor; -import com.example.backend.model.ActorMovieRelation; -import com.example.backend.model.ActorMovieRelationRepository; import com.example.backend.model.ActorRepository; import lombok.AllArgsConstructor; import org.springframework.stereotype.Service; diff --git a/backend/src/main/java/com/example/backend/service/ActorMovieService.java b/backend/src/main/java/com/example/backend/service/MovieActorService.java similarity index 72% rename from backend/src/main/java/com/example/backend/service/ActorMovieService.java rename to backend/src/main/java/com/example/backend/service/MovieActorService.java index c3f7106..f2bd066 100644 --- a/backend/src/main/java/com/example/backend/service/ActorMovieService.java +++ b/backend/src/main/java/com/example/backend/service/MovieActorService.java @@ -8,23 +8,23 @@ @Service @RequiredArgsConstructor -public class ActorMovieService { - private final ActorMovieRelationRepository actorMovieRelationRepository; +public class MovieActorService { + private final MovieActorRelationRepository movieActorRelationRepository; private final ActorRepository actorRepository; private final MovieRepository movieRepository; public List getActorsByMovieId(Long movieId) { - return actorMovieRelationRepository.findByMovieId(movieId) + return movieActorRelationRepository.findByMovieId(movieId) .stream() - .map(ActorMovieRelation::getActor) + .map(MovieActorRelation::getActor) .toList(); } public void addActor(Long movieId, Long actorId) { Movie movie = movieRepository.findById(movieId).orElseThrow(); Actor actor = actorRepository.findById(actorId).orElseThrow(); - actorMovieRelationRepository.save(ActorMovieRelation.builder().actor(actor).movie(movie).actor(actor).build()); + movieActorRelationRepository.save(MovieActorRelation.builder().actor(actor).movie(movie).actor(actor).build()); } } diff --git a/backend/src/test/java/com/example/backend/controller/ActorControllerTest.java b/backend/src/test/java/com/example/backend/controller/ActorControllerTest.java index 8c6de48..51f61e4 100644 --- a/backend/src/test/java/com/example/backend/controller/ActorControllerTest.java +++ b/backend/src/test/java/com/example/backend/controller/ActorControllerTest.java @@ -41,7 +41,7 @@ class ActorControllerTest { private MovieRepository movieRepository; @Autowired - private ActorMovieRelationRepository actorMovieRelationRepository; + private MovieActorRelationRepository movieActorRelationRepository; @Test @DirtiesContext diff --git a/backend/src/test/java/com/example/backend/controller/ActorMovieControllerTest.java b/backend/src/test/java/com/example/backend/controller/MovieActorControllerTest.java similarity index 78% rename from backend/src/test/java/com/example/backend/controller/ActorMovieControllerTest.java rename to backend/src/test/java/com/example/backend/controller/MovieActorControllerTest.java index 8388eed..b1ccc01 100644 --- a/backend/src/test/java/com/example/backend/controller/ActorMovieControllerTest.java +++ b/backend/src/test/java/com/example/backend/controller/MovieActorControllerTest.java @@ -20,8 +20,9 @@ @SpringBootTest @AutoConfigureMockMvc -class ActorMovieControllerTest { - private static final String URL_ACTOR_MOVIE_BASE = "/api/actor-movie/{movieId}"; +class MovieActorControllerTest { + private static final String URL_BASE = "/api/movie-actor"; + private static final String URL_WITH_ID = "/api/movie-actor/{movieId}"; private static final String ACTOR_NAME_JANE = "Jane Doe"; private static final String ACTOR_NAME_JIM = "Jim Doe"; @@ -41,7 +42,7 @@ class ActorMovieControllerTest { private ActorRepository actorRepository; @Autowired - private ActorMovieRelationRepository actorMovieRelationRepository; + private MovieActorRelationRepository actorMovieRelationRepository; @Test @DirtiesContext @@ -56,14 +57,14 @@ void getByMovieIdTest_multipleMatch() throws Exception { actorRepository.saveAll(List.of(actorJane, actorJim, actorJoe, actorJohn)); actorMovieRelationRepository.saveAll( List.of( - ActorMovieRelation.builder().actor(actorJane).movie(movieFirst).build(), - ActorMovieRelation.builder().actor(actorJoe).movie(movieSecond).build(), - ActorMovieRelation.builder().actor(actorJim).movie(movieSecond).build(), - ActorMovieRelation.builder().actor(actorJane).movie(movieSecond).build() + MovieActorRelation.builder().actor(actorJane).movie(movieFirst).build(), + MovieActorRelation.builder().actor(actorJoe).movie(movieSecond).build(), + MovieActorRelation.builder().actor(actorJim).movie(movieSecond).build(), + MovieActorRelation.builder().actor(actorJane).movie(movieSecond).build() ) ); - mockMvc.perform(MockMvcRequestBuilders.get(URL_ACTOR_MOVIE_BASE, movieSecond.getId())) + mockMvc.perform(MockMvcRequestBuilders.get(URL_WITH_ID, movieSecond.getId())) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(jsonPath("$", hasSize(3))) .andExpect(jsonPath("$[*].name", containsInAnyOrder( @@ -86,21 +87,21 @@ void getByMovieIdTest_noMatch() throws Exception { actorRepository.saveAll(List.of(actorJane, actorJim, actorJoe, actorJohn)); actorMovieRelationRepository.saveAll( List.of( - ActorMovieRelation.builder().actor(actorJane).movie(movieFirst).build(), - ActorMovieRelation.builder().actor(actorJoe).movie(movieFirst).build(), - ActorMovieRelation.builder().actor(actorJim).movie(movieFirst).build(), - ActorMovieRelation.builder().actor(actorJohn).movie(movieFirst).build() + MovieActorRelation.builder().actor(actorJane).movie(movieFirst).build(), + MovieActorRelation.builder().actor(actorJoe).movie(movieFirst).build(), + MovieActorRelation.builder().actor(actorJim).movie(movieFirst).build(), + MovieActorRelation.builder().actor(actorJohn).movie(movieFirst).build() ) ); - mockMvc.perform(MockMvcRequestBuilders.get(URL_ACTOR_MOVIE_BASE, movieSecond.getId())) + mockMvc.perform(MockMvcRequestBuilders.get(URL_WITH_ID, movieSecond.getId())) .andExpect(MockMvcResultMatchers.status().isOk()) .andExpect(jsonPath("$", hasSize(0))); } @Test void getByMovieIdTest_emptyRequest() throws Exception { - mockMvc.perform(MockMvcRequestBuilders.get(URL_ACTOR_MOVIE_BASE, "")) + mockMvc.perform(MockMvcRequestBuilders.get(URL_WITH_ID, "")) .andExpect(MockMvcResultMatchers.status().is4xxClientError()); } @@ -112,19 +113,20 @@ void addActorById_successFull() throws Exception { movieRepository.save(movie); actorRepository.save(actor); - mockMvc.perform(MockMvcRequestBuilders.post(URL_ACTOR_MOVIE_BASE, movie.getId()) + mockMvc.perform(MockMvcRequestBuilders.post(URL_BASE) .contentType(MediaType.APPLICATION_JSON) .content( """ { - "id": "%s" + "actorId": "%s", + "movieId": "%s" } - """.formatted(actor.getId()) + """.formatted(actor.getId(), movie.getId()) ) ) .andExpect(MockMvcResultMatchers.status().isOk()); - List actualActorIdList = actorMovieRelationRepository.findByMovieId(movie.getId()); + List actualActorIdList = actorMovieRelationRepository.findByMovieId(movie.getId()); assertEquals(1, actualActorIdList.size()); assertEquals(actor.getId(), actualActorIdList.getFirst().getActor().getId()); } @@ -136,16 +138,17 @@ void addActorById_alreadyAdded() throws Exception { Actor actor = Actor.builder().name(ACTOR_NAME_JANE).build(); movieRepository.save(movie); actorRepository.save(actor); - actorMovieRelationRepository.save(ActorMovieRelation.builder().actor(actor).movie(movie).build()); + actorMovieRelationRepository.save(MovieActorRelation.builder().actor(actor).movie(movie).build()); - mockMvc.perform(MockMvcRequestBuilders.post(URL_ACTOR_MOVIE_BASE, movie.getId()) + mockMvc.perform(MockMvcRequestBuilders.post(URL_BASE) .contentType(MediaType.APPLICATION_JSON) .content( """ { - "id": "%s" + "actorId": "%s", + "movieId": "%s" } - """.formatted(actor.getId()) + """.formatted(actor.getId(), movie.getId()) )) .andExpect(MockMvcResultMatchers.status().is5xxServerError()); } @@ -159,14 +162,15 @@ void addActorById_noSuchActor() throws Exception { actorRepository.save(actor); Long nonExistentActorId = actor.getId() + 1; - mockMvc.perform(MockMvcRequestBuilders.post(URL_ACTOR_MOVIE_BASE, movie.getId()) + mockMvc.perform(MockMvcRequestBuilders.post(URL_BASE) .contentType(MediaType.APPLICATION_JSON) .content( """ { - "id": "%s" + "actorId": "%s", + "movieId": "%s", } - """.formatted(nonExistentActorId) + """.formatted(nonExistentActorId, movie.getId()) )) .andExpect(MockMvcResultMatchers.status().is4xxClientError()); } @@ -180,14 +184,15 @@ void addActorById_noSuchMovie() throws Exception { actorRepository.save(actor); Long nonExistentMovieId = movie.getId() + 1L; - mockMvc.perform(MockMvcRequestBuilders.post(URL_ACTOR_MOVIE_BASE, nonExistentMovieId) + mockMvc.perform(MockMvcRequestBuilders.post(URL_BASE) .contentType(MediaType.APPLICATION_JSON) .content( """ { - "id": "%s" + "actorId": "%s", + "movieId": "%s" } - """.formatted(actor.getId()) + """.formatted(actor.getId(), nonExistentMovieId) )) .andExpect(MockMvcResultMatchers.status().is4xxClientError());