diff --git a/src/main/java/tipitapi/drawmytoday/domain/diary/controller/ImageController.java b/src/main/java/tipitapi/drawmytoday/domain/diary/controller/ImageController.java index c55ce9b4..9e54b6bb 100644 --- a/src/main/java/tipitapi/drawmytoday/domain/diary/controller/ImageController.java +++ b/src/main/java/tipitapi/drawmytoday/domain/diary/controller/ImageController.java @@ -14,6 +14,7 @@ import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @@ -88,4 +89,31 @@ public ResponseEntity reviewImage( imageService.reviewImage(tokenInfo.getUserId(), imageId, reviewDiaryRequest.getReview()); return ResponseEntity.noContent().build(); } + + @Operation(summary = "대표 이미지 설정", description = "주어진 ID의 이미지를 일기의 대표 이미지로 설정한다.") + @ApiResponses(value = { + @ApiResponse( + responseCode = "204", + description = "성공적으로 이미지를 평가함"), + @ApiResponse( + responseCode = "403", + description = "I004 : 자신의 이미지에만 접근할 수 있습니다.", + content = @Content(schema = @Schema(hidden = true))), + @ApiResponse( + responseCode = "404", + description = "D001 : 일기를 찾을 수 없습니다.", + content = @Content(schema = @Schema(hidden = true))), + @ApiResponse( + responseCode = "404", + description = "I001 : 이미지를 찾을 수 없습니다.", + content = @Content(schema = @Schema(hidden = true))), + }) + @PutMapping("/{id}") + public ResponseEntity setSelectedImage( + @AuthUser JwtTokenInfo tokenInfo, + @Parameter(description = "이미지 ID", in = ParameterIn.PATH) @PathVariable("id") Long imageId + ) { + imageService.setSelectedImage(tokenInfo.getUserId(), imageId); + return ResponseEntity.noContent().build(); + } } diff --git a/src/main/java/tipitapi/drawmytoday/domain/diary/service/ImageService.java b/src/main/java/tipitapi/drawmytoday/domain/diary/service/ImageService.java index 22913d8a..d390b5f1 100644 --- a/src/main/java/tipitapi/drawmytoday/domain/diary/service/ImageService.java +++ b/src/main/java/tipitapi/drawmytoday/domain/diary/service/ImageService.java @@ -68,6 +68,16 @@ public void reviewImage(Long userId, Long imageId, String review) { image.reviewImage(review); } + @Transactional + public void setSelectedImage(Long userId, Long imageId) { + User user = validateUserService.validateUserById(userId); + Image image = validateImageService.validateImageById(imageId); + Diary diary = validateDiaryService.validateDiaryById(image.getDiary().getDiaryId(), user); + + unSelectAllImage(diary.getDiaryId()); + image.setSelected(true); + } + private Image validateImage(Long imageId, User user) { Image image = imageRepository.findImage(imageId).orElseThrow(ImageNotFoundException::new); if (image.isSelected()) { diff --git a/src/main/java/tipitapi/drawmytoday/domain/diary/service/ValidateImageService.java b/src/main/java/tipitapi/drawmytoday/domain/diary/service/ValidateImageService.java index 839171d8..be5f7def 100644 --- a/src/main/java/tipitapi/drawmytoday/domain/diary/service/ValidateImageService.java +++ b/src/main/java/tipitapi/drawmytoday/domain/diary/service/ValidateImageService.java @@ -17,7 +17,7 @@ public class ValidateImageService { private final ImageRepository imageRepository; public Image validateImageById(Long imageId) { - return imageRepository.findById(imageId).orElseThrow(ImageNotFoundException::new); + return imageRepository.findImage(imageId).orElseThrow(ImageNotFoundException::new); } public void validateImageOwner(Long imageId, User user) { diff --git a/src/test/java/tipitapi/drawmytoday/domain/diary/controller/ImageControllerTest.java b/src/test/java/tipitapi/drawmytoday/domain/diary/controller/ImageControllerTest.java index fd694ee7..eccef915 100644 --- a/src/test/java/tipitapi/drawmytoday/domain/diary/controller/ImageControllerTest.java +++ b/src/test/java/tipitapi/drawmytoday/domain/diary/controller/ImageControllerTest.java @@ -3,6 +3,7 @@ import static org.mockito.Mockito.verify; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import com.fasterxml.jackson.databind.ObjectMapper; @@ -99,4 +100,24 @@ void review_image(String review) throws Exception { verify(imageService).reviewImage(imageId, REQUEST_USER_ID, review); } } + + @Nested + @DisplayName("setSelectedImage 메서드는") + class SetSelectedImageTest { + + @Test + @DisplayName("imageId에 해당하는 일기를 대표 설정한다.") + void sets_image_selected() throws Exception { + // given + Long imageId = 1L; + + // when + ResultActions result = mockMvc.perform(put(BASIC_URL + "/" + imageId) + .with(SecurityMockMvcRequestPostProcessors.csrf())); + + // then + result.andExpect(status().isNoContent()); + verify(imageService).setSelectedImage(REQUEST_USER_ID, imageId); + } + } } diff --git a/src/test/java/tipitapi/drawmytoday/domain/diary/service/ImageServiceTest.java b/src/test/java/tipitapi/drawmytoday/domain/diary/service/ImageServiceTest.java index a5c83a35..7b3abdbe 100644 --- a/src/test/java/tipitapi/drawmytoday/domain/diary/service/ImageServiceTest.java +++ b/src/test/java/tipitapi/drawmytoday/domain/diary/service/ImageServiceTest.java @@ -7,6 +7,7 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.matches; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.verify; import static tipitapi.drawmytoday.common.testdata.TestDiary.createDiary; import static tipitapi.drawmytoday.common.testdata.TestDiary.createDiaryWithId; @@ -23,6 +24,7 @@ import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.InjectMocks; import org.mockito.Mock; +import org.mockito.Spy; import org.mockito.junit.jupiter.MockitoExtension; import org.springframework.test.util.ReflectionTestUtils; import tipitapi.drawmytoday.domain.diary.domain.Diary; @@ -48,6 +50,7 @@ class ImageServiceTest { ValidateDiaryService validateDiaryService; @Mock ValidateImageService validateImageService; + @Spy @InjectMocks ImageService imageService; @@ -182,4 +185,31 @@ void it_updates_image_review() { verify(validateImageService).validateImageOwner(eq(image.getImageId()), eq(user)); } } + + @Nested + @DisplayName("setSelectedImage 메서드 테스트") + class SetSelectedImageTest { + + @Test + @DisplayName("user, image, diary를 검증한 후 기존 대표 설정을 해제하고 주어진 이미지를 대표 이미지로 설정한다.") + void it_sets_selected_image() { + User user = createUserWithId(1L); + Diary diary = createDiaryWithId(1L, user, createEmotion()); + Image image = createImageWithId(1L, diary); + given(validateUserService.validateUserById(anyLong())).willReturn(user); + given(validateImageService.validateImageById(anyLong())).willReturn(image); + given(validateDiaryService.validateDiaryById(anyLong(), any(User.class))) + .willReturn(diary); + doNothing().when(imageService).unSelectAllImage(anyLong()); + + imageService.setSelectedImage(1L, 1L); + + assertThat(image.isSelected()).isTrue(); + verify(validateUserService).validateUserById(eq(user.getUserId())); + verify(validateImageService).validateImageById(eq(image.getImageId())); + verify(validateDiaryService).validateDiaryById(eq(diary.getDiaryId()), eq(user)); + verify(imageService).unSelectAllImage(eq(diary.getDiaryId())); + } + } + } \ No newline at end of file