From b92e2c3aacd6fb7457b4728149d431e09f95d501 Mon Sep 17 00:00:00 2001 From: leeedohyun Date: Tue, 28 Oct 2025 16:26:27 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=20=EC=97=85=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=EC=8B=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=ED=83=9C=EA=B7=B8=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/api/user/UserTagController.java | 9 ++- .../core/domain/tag/ImageTagRepository.java | 4 ++ .../core/service/tag/ImageTagService.java | 29 ++++++++ .../core/api/user/UserTagControllerTest.java | 6 +- .../domain/tag/ImageTagRepositoryTest.java | 59 +++++++++++++++++ .../core/service/tag/ImageTagServiceTest.java | 66 +++++++++++++++++++ 6 files changed, 170 insertions(+), 3 deletions(-) create mode 100644 capturecat-core/src/main/java/com/capturecat/core/service/tag/ImageTagService.java create mode 100644 capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java diff --git a/capturecat-core/src/main/java/com/capturecat/core/api/user/UserTagController.java b/capturecat-core/src/main/java/com/capturecat/core/api/user/UserTagController.java index a48a5a3..dfcfe0d 100644 --- a/capturecat-core/src/main/java/com/capturecat/core/api/user/UserTagController.java +++ b/capturecat-core/src/main/java/com/capturecat/core/api/user/UserTagController.java @@ -17,6 +17,7 @@ import com.capturecat.core.api.user.dto.TagRenameRequest; import com.capturecat.core.service.auth.LoginUser; import com.capturecat.core.service.image.TagResponse; +import com.capturecat.core.service.tag.ImageTagService; import com.capturecat.core.service.user.UserTagService; import com.capturecat.core.support.response.ApiResponse; import com.capturecat.core.support.response.CursorResponse; @@ -27,6 +28,7 @@ public class UserTagController { private final UserTagService userTagService; + private final ImageTagService imageTagService; @PostMapping public ApiResponse create(@AuthenticationPrincipal LoginUser loginUser, @RequestParam String tagName) { @@ -44,9 +46,12 @@ public ApiResponse> getAll(@AuthenticationPrincipal } @PatchMapping - public ApiResponse update(@AuthenticationPrincipal LoginUser loginUser, - @RequestBody TagRenameRequest request) { + public ApiResponse update( + @AuthenticationPrincipal LoginUser loginUser, + @RequestBody TagRenameRequest request + ) { TagResponse response = userTagService.update(loginUser, request.currentTagId(), request.newTagName()); + imageTagService.update(loginUser, request.currentTagId(), response.id()); return ApiResponse.success(response); } diff --git a/capturecat-core/src/main/java/com/capturecat/core/domain/tag/ImageTagRepository.java b/capturecat-core/src/main/java/com/capturecat/core/domain/tag/ImageTagRepository.java index f1d8345..0e97049 100644 --- a/capturecat-core/src/main/java/com/capturecat/core/domain/tag/ImageTagRepository.java +++ b/capturecat-core/src/main/java/com/capturecat/core/domain/tag/ImageTagRepository.java @@ -32,6 +32,10 @@ public interface ImageTagRepository extends JpaRepository { @Query("DELETE FROM ImageTag it WHERE it.tag = :tag AND it.image.user = :user") void deleteByTagAndUser(Tag tag, User user); + @Modifying(clearAutomatically = true, flushAutomatically = true) + @Query("UPDATE ImageTag it SET it.tag.id = :newTagId WHERE it.tag.id = :oldTagId AND it.image.user.id = :userId") + void updateImageTagsForUser(Long userId, Long oldTagId, Long newTagId); + @Modifying(clearAutomatically = true, flushAutomatically = true) @Query("DELETE FROM ImageTag it WHERE it.image.id IN (SELECT i.id FROM Image i WHERE i.user.id = :userId)") void deleteAllTagsByUserId(Long userId); diff --git a/capturecat-core/src/main/java/com/capturecat/core/service/tag/ImageTagService.java b/capturecat-core/src/main/java/com/capturecat/core/service/tag/ImageTagService.java new file mode 100644 index 0000000..c897720 --- /dev/null +++ b/capturecat-core/src/main/java/com/capturecat/core/service/tag/ImageTagService.java @@ -0,0 +1,29 @@ +package com.capturecat.core.service.tag; + +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import lombok.RequiredArgsConstructor; + +import com.capturecat.core.domain.tag.ImageTagRepository; +import com.capturecat.core.domain.user.User; +import com.capturecat.core.domain.user.UserRepository; +import com.capturecat.core.service.auth.LoginUser; +import com.capturecat.core.support.error.CoreException; +import com.capturecat.core.support.error.ErrorType; + +@Service +@RequiredArgsConstructor +public class ImageTagService { + + private final ImageTagRepository imageTagRepository; + private final UserRepository userRepository; + + @Transactional + public void update(LoginUser loginUser, Long oldTagId, Long newTagId) { + User user = userRepository.findByUsername(loginUser.getUsername()) + .orElseThrow(() -> new CoreException(ErrorType.USER_NOT_FOUND)); + + imageTagRepository.updateImageTagsForUser(user.getId(), oldTagId, newTagId); + } +} diff --git a/capturecat-core/src/test/java/com/capturecat/core/api/user/UserTagControllerTest.java b/capturecat-core/src/test/java/com/capturecat/core/api/user/UserTagControllerTest.java index 7563e00..3e072a8 100644 --- a/capturecat-core/src/test/java/com/capturecat/core/api/user/UserTagControllerTest.java +++ b/capturecat-core/src/test/java/com/capturecat/core/api/user/UserTagControllerTest.java @@ -29,6 +29,7 @@ import com.capturecat.core.config.jwt.JwtUtil; import com.capturecat.core.service.image.TagResponse; +import com.capturecat.core.service.tag.ImageTagService; import com.capturecat.core.service.user.UserTagService; import com.capturecat.core.support.response.CursorResponse; import com.capturecat.test.api.RestDocsTest; @@ -39,11 +40,13 @@ class UserTagControllerTest extends RestDocsTest { private UserTagController userTagController; private UserTagService userTagService; + private ImageTagService imageTagService; @BeforeEach void setUp() { userTagService = mock(UserTagService.class); - userTagController = new UserTagController(userTagService); + imageTagService = mock(ImageTagService.class); + userTagController = new UserTagController(userTagService, imageTagService); mockMvc = mockController(userTagController); } @@ -101,6 +104,7 @@ void setUp() { void 유저_태그_수정() { // given BDDMockito.given(userTagService.update(any(), anyLong(), anyString())).willReturn(new TagResponse(1L, "java")); + BDDMockito.willDoNothing().given(imageTagService).update(any(), anyLong(), anyLong()); // when & then given() diff --git a/capturecat-core/src/test/java/com/capturecat/core/domain/tag/ImageTagRepositoryTest.java b/capturecat-core/src/test/java/com/capturecat/core/domain/tag/ImageTagRepositoryTest.java index 0dcb869..addff3d 100644 --- a/capturecat-core/src/test/java/com/capturecat/core/domain/tag/ImageTagRepositoryTest.java +++ b/capturecat-core/src/test/java/com/capturecat/core/domain/tag/ImageTagRepositoryTest.java @@ -114,4 +114,63 @@ class ImageTagRepositoryTest { assertThat(user2Result).hasSize(1); assertThat(user2Result.get(0).getImage().getUser()).isEqualTo(user2); } + + @Test + void 지정한_사용자만_태그가_교체된다() { + // given + var user1 = userRepository.save(DummyObject.newUser("user1")); + var user2 = userRepository.save(DummyObject.newUser("user2")); + + var image1 = imageRepository.save(DummyObject.newMockUserImage(user1)); + var image2 = imageRepository.save(DummyObject.newMockUserImage(user2)); + + var oldTag = tagRepository.save(TagFixture.createTag("old")); + var newTag = tagRepository.save(TagFixture.createTag("new")); + + imageTagRepository.save(new ImageTag(image1, oldTag)); + imageTagRepository.save(new ImageTag(image2, oldTag)); + + entityManager.flush(); + entityManager.clear(); + + // when + imageTagRepository.updateImageTagsForUser(user1.getId(), oldTag.getId(), newTag.getId()); + + entityManager.flush(); + entityManager.clear(); + + // then + var it1 = imageTagRepository.findByImage(image1).get(0); + var it2 = imageTagRepository.findByImage(image2).get(0); + + assertThat(it1.getTag().getId()).isEqualTo(newTag.getId()); + assertThat(it2.getTag().getId()).isEqualTo(oldTag.getId()); + } + + @Test + void 태그가_없는_이미지에는_영향이_없다() { + // given + var user = userRepository.save(DummyObject.newUser("noTagUser")); + var imageWithNoTag = imageRepository.save(DummyObject.newMockUserImage(user)); + + var oldTag = tagRepository.save(TagFixture.createTag("old")); + var newTag = tagRepository.save(TagFixture.createTag("new")); + + var imageWithTag = imageRepository.save(DummyObject.newMockUserImage(user)); + imageTagRepository.save(new ImageTag(imageWithTag, oldTag)); + + entityManager.flush(); + entityManager.clear(); + + // when + imageTagRepository.updateImageTagsForUser(user.getId(), oldTag.getId(), newTag.getId()); + + entityManager.flush(); + entityManager.clear(); + + // then + assertThat(imageTagRepository.findByImage(imageWithNoTag)).isEmpty(); + var updated = imageTagRepository.findByImage(imageWithTag).get(0); + assertThat(updated.getTag().getId()).isEqualTo(newTag.getId()); + } } diff --git a/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java b/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java new file mode 100644 index 0000000..eb42478 --- /dev/null +++ b/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java @@ -0,0 +1,66 @@ +package com.capturecat.core.service.tag; + +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.capturecat.core.domain.tag.ImageTagRepository; +import com.capturecat.core.domain.user.User; +import com.capturecat.core.domain.user.UserRepository; +import com.capturecat.core.service.auth.LoginUser; +import com.capturecat.core.support.error.CoreException; + +@ExtendWith(MockitoExtension.class) +class ImageTagServiceTest { + + @Mock + ImageTagRepository imageTagRepository; + + @Mock + UserRepository userRepository; + + @InjectMocks + ImageTagService imageTagService; + + @Test + void 업데이트_사용자_존재하면_레포지토리_호출한다() { + // given + LoginUser loginUser = mock(LoginUser.class); + when(loginUser.getUsername()).thenReturn("existingUser"); + + User user = mock(User.class); + when(user.getId()).thenReturn(123L); + + when(userRepository.findByUsername("existingUser")).thenReturn(Optional.of(user)); + + // when + imageTagService.update(loginUser, 10L, 20L); + + // then + verify(imageTagRepository, times(1)).updateImageTagsForUser(123L, 10L, 20L); + } + + @Test + void 업데이트_사용자_없으면_CoreException_던진다() { + // given + LoginUser loginUser = mock(LoginUser.class); + when(loginUser.getUsername()).thenReturn("noUser"); + when(userRepository.findByUsername("noUser")).thenReturn(Optional.empty()); + + // when / then + assertThrows(CoreException.class, () -> imageTagService.update(loginUser, 1L, 2L)); + verifyNoInteractions(imageTagRepository); + } +} + From 5c4a93837b917f31854ff9ddeb1d6ef87e4d29e0 Mon Sep 17 00:00:00 2001 From: leeedohyun Date: Tue, 28 Oct 2025 16:57:56 +0900 Subject: [PATCH 2/4] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=20=EC=82=AD=EC=A0=9C=20=EC=8B=9C=20=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=20=ED=83=9C=EA=B7=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/api/user/UserTagController.java | 1 + .../core/service/tag/ImageTagService.java | 13 +++++ .../core/api/user/UserTagControllerTest.java | 1 + .../core/service/tag/ImageTagServiceTest.java | 52 +++++++++++++++++++ 4 files changed, 67 insertions(+) diff --git a/capturecat-core/src/main/java/com/capturecat/core/api/user/UserTagController.java b/capturecat-core/src/main/java/com/capturecat/core/api/user/UserTagController.java index dfcfe0d..302fff4 100644 --- a/capturecat-core/src/main/java/com/capturecat/core/api/user/UserTagController.java +++ b/capturecat-core/src/main/java/com/capturecat/core/api/user/UserTagController.java @@ -59,6 +59,7 @@ public ApiResponse update( @DeleteMapping public ApiResponse delete(@AuthenticationPrincipal LoginUser loginUser, @RequestParam Long tagId) { userTagService.delete(loginUser, tagId); + imageTagService.delete(loginUser, tagId); return ApiResponse.success(); } diff --git a/capturecat-core/src/main/java/com/capturecat/core/service/tag/ImageTagService.java b/capturecat-core/src/main/java/com/capturecat/core/service/tag/ImageTagService.java index c897720..e28b2f3 100644 --- a/capturecat-core/src/main/java/com/capturecat/core/service/tag/ImageTagService.java +++ b/capturecat-core/src/main/java/com/capturecat/core/service/tag/ImageTagService.java @@ -6,6 +6,8 @@ import lombok.RequiredArgsConstructor; import com.capturecat.core.domain.tag.ImageTagRepository; +import com.capturecat.core.domain.tag.Tag; +import com.capturecat.core.domain.tag.TagRepository; import com.capturecat.core.domain.user.User; import com.capturecat.core.domain.user.UserRepository; import com.capturecat.core.service.auth.LoginUser; @@ -18,6 +20,7 @@ public class ImageTagService { private final ImageTagRepository imageTagRepository; private final UserRepository userRepository; + private final TagRepository tagRepository; @Transactional public void update(LoginUser loginUser, Long oldTagId, Long newTagId) { @@ -26,4 +29,14 @@ public void update(LoginUser loginUser, Long oldTagId, Long newTagId) { imageTagRepository.updateImageTagsForUser(user.getId(), oldTagId, newTagId); } + + @Transactional + public void delete(LoginUser loginUser, Long tagId) { + User user = userRepository.findByUsername(loginUser.getUsername()) + .orElseThrow(() -> new CoreException(ErrorType.USER_NOT_FOUND)); + Tag tag = tagRepository.findById(tagId) + .orElseThrow(() -> new CoreException(ErrorType.TAG_NOT_FOUND)); + + imageTagRepository.deleteByTagAndUser(tag, user); + } } diff --git a/capturecat-core/src/test/java/com/capturecat/core/api/user/UserTagControllerTest.java b/capturecat-core/src/test/java/com/capturecat/core/api/user/UserTagControllerTest.java index 3e072a8..b0abfaf 100644 --- a/capturecat-core/src/test/java/com/capturecat/core/api/user/UserTagControllerTest.java +++ b/capturecat-core/src/test/java/com/capturecat/core/api/user/UserTagControllerTest.java @@ -130,6 +130,7 @@ void setUp() { void 유저_태그_삭제() { // given BDDMockito.given(userTagService.create(any(), anyString())).willReturn(new TagResponse(1L, "java")); + BDDMockito.willDoNothing().given(imageTagService).delete(any(), anyLong()); // when & then given() diff --git a/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java b/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java index eb42478..682e0b4 100644 --- a/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java +++ b/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java @@ -16,6 +16,8 @@ import org.mockito.junit.jupiter.MockitoExtension; import com.capturecat.core.domain.tag.ImageTagRepository; +import com.capturecat.core.domain.tag.Tag; +import com.capturecat.core.domain.tag.TagRepository; import com.capturecat.core.domain.user.User; import com.capturecat.core.domain.user.UserRepository; import com.capturecat.core.service.auth.LoginUser; @@ -30,6 +32,9 @@ class ImageTagServiceTest { @Mock UserRepository userRepository; + @Mock + TagRepository tagRepository; + @InjectMocks ImageTagService imageTagService; @@ -62,5 +67,52 @@ class ImageTagServiceTest { assertThrows(CoreException.class, () -> imageTagService.update(loginUser, 1L, 2L)); verifyNoInteractions(imageTagRepository); } + + @Test + void 삭제_사용자_태그_존재하면_레포지토리_호출한다() { + // given + LoginUser loginUser = mock(LoginUser.class); + when(loginUser.getUsername()).thenReturn("existingUser"); + + User user = mock(User.class); + when(userRepository.findByUsername("existingUser")).thenReturn(Optional.of(user)); + + Tag tag = mock(Tag.class); + when(tagRepository.findById(10L)).thenReturn(Optional.of(tag)); + + // when + imageTagService.delete(loginUser, 10L); + + // then + verify(imageTagRepository, times(1)).deleteByTagAndUser(tag, user); + } + + @Test + void 삭제_사용자_없으면_CoreException_던진다() { + // given + LoginUser loginUser = mock(LoginUser.class); + when(loginUser.getUsername()).thenReturn("noUser"); + when(userRepository.findByUsername("noUser")).thenReturn(Optional.empty()); + + // when / then + assertThrows(CoreException.class, () -> imageTagService.delete(loginUser, 1L)); + verifyNoInteractions(imageTagRepository, tagRepository); + } + + @Test + void 삭제_태그_없으면_CoreException_던진다() { + // given + LoginUser loginUser = mock(LoginUser.class); + when(loginUser.getUsername()).thenReturn("existingUser"); + + User user = mock(User.class); + when(userRepository.findByUsername("existingUser")).thenReturn(Optional.of(user)); + + when(tagRepository.findById(2L)).thenReturn(Optional.empty()); + + // when / then + assertThrows(CoreException.class, () -> imageTagService.delete(loginUser, 2L)); + verifyNoInteractions(imageTagRepository); + } } From 0eb792a94b84ef0d39aab18d3dce542a947852f3 Mon Sep 17 00:00:00 2001 From: leeedohyun Date: Tue, 28 Oct 2025 17:10:57 +0900 Subject: [PATCH 3/4] =?UTF-8?q?refactor:=20BDDMockito=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/service/tag/ImageTagServiceTest.java | 70 +++++++++---------- 1 file changed, 34 insertions(+), 36 deletions(-) diff --git a/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java b/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java index 682e0b4..e670aa2 100644 --- a/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java +++ b/capturecat-core/src/test/java/com/capturecat/core/service/tag/ImageTagServiceTest.java @@ -1,11 +1,12 @@ package com.capturecat.core.service.tag; -import static org.junit.jupiter.api.Assertions.assertThrows; -import static org.mockito.Mockito.mock; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; -import static org.mockito.Mockito.when; import java.util.Optional; @@ -15,8 +16,10 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import com.capturecat.core.DummyObject; import com.capturecat.core.domain.tag.ImageTagRepository; import com.capturecat.core.domain.tag.Tag; +import com.capturecat.core.domain.tag.TagFixture; import com.capturecat.core.domain.tag.TagRepository; import com.capturecat.core.domain.user.User; import com.capturecat.core.domain.user.UserRepository; @@ -41,47 +44,43 @@ class ImageTagServiceTest { @Test void 업데이트_사용자_존재하면_레포지토리_호출한다() { // given - LoginUser loginUser = mock(LoginUser.class); - when(loginUser.getUsername()).thenReturn("existingUser"); + User user = DummyObject.newMockUser(123L); - User user = mock(User.class); - when(user.getId()).thenReturn(123L); - - when(userRepository.findByUsername("existingUser")).thenReturn(Optional.of(user)); + given(userRepository.findByUsername(anyString())).willReturn(Optional.of(user)); // when - imageTagService.update(loginUser, 10L, 20L); + imageTagService.update(new LoginUser(user), 10L, 20L); // then - verify(imageTagRepository, times(1)).updateImageTagsForUser(123L, 10L, 20L); + verify(imageTagRepository, times(1)) + .updateImageTagsForUser(user.getId(), 10L, 20L); } @Test void 업데이트_사용자_없으면_CoreException_던진다() { // given - LoginUser loginUser = mock(LoginUser.class); - when(loginUser.getUsername()).thenReturn("noUser"); - when(userRepository.findByUsername("noUser")).thenReturn(Optional.empty()); + User user = DummyObject.newUser("noUser"); + + given(userRepository.findByUsername(anyString())).willReturn(Optional.empty()); - // when / then - assertThrows(CoreException.class, () -> imageTagService.update(loginUser, 1L, 2L)); + // when & then + assertThatThrownBy(() -> imageTagService.update(new LoginUser(user), 1L, 2L)) + .isInstanceOf(CoreException.class); verifyNoInteractions(imageTagRepository); } @Test void 삭제_사용자_태그_존재하면_레포지토리_호출한다() { // given - LoginUser loginUser = mock(LoginUser.class); - when(loginUser.getUsername()).thenReturn("existingUser"); + User user = DummyObject.newUser("test"); - User user = mock(User.class); - when(userRepository.findByUsername("existingUser")).thenReturn(Optional.of(user)); + given(userRepository.findByUsername(anyString())).willReturn(Optional.of(user)); - Tag tag = mock(Tag.class); - when(tagRepository.findById(10L)).thenReturn(Optional.of(tag)); + Tag tag = TagFixture.createTag(10L, "testTag"); + given(tagRepository.findById(anyLong())).willReturn(Optional.of(tag)); // when - imageTagService.delete(loginUser, 10L); + imageTagService.delete(new LoginUser(user), tag.getId()); // then verify(imageTagRepository, times(1)).deleteByTagAndUser(tag, user); @@ -90,28 +89,27 @@ class ImageTagServiceTest { @Test void 삭제_사용자_없으면_CoreException_던진다() { // given - LoginUser loginUser = mock(LoginUser.class); - when(loginUser.getUsername()).thenReturn("noUser"); - when(userRepository.findByUsername("noUser")).thenReturn(Optional.empty()); + User user = DummyObject.newUser("noUser"); - // when / then - assertThrows(CoreException.class, () -> imageTagService.delete(loginUser, 1L)); + given(userRepository.findByUsername(anyString())).willReturn(Optional.empty()); + + // when & then + assertThatThrownBy(() -> imageTagService.delete(new LoginUser(user), 1L)) + .isInstanceOf(CoreException.class); verifyNoInteractions(imageTagRepository, tagRepository); } @Test void 삭제_태그_없으면_CoreException_던진다() { // given - LoginUser loginUser = mock(LoginUser.class); - when(loginUser.getUsername()).thenReturn("existingUser"); - - User user = mock(User.class); - when(userRepository.findByUsername("existingUser")).thenReturn(Optional.of(user)); + User user = DummyObject.newUser("test"); - when(tagRepository.findById(2L)).thenReturn(Optional.empty()); + given(userRepository.findByUsername(anyString())).willReturn(Optional.of(user)); + given(tagRepository.findById(anyLong())).willReturn(Optional.empty()); - // when / then - assertThrows(CoreException.class, () -> imageTagService.delete(loginUser, 2L)); + // when & then + assertThatThrownBy(() -> imageTagService.delete(new LoginUser(user), 2L)) + .isInstanceOf(CoreException.class); verifyNoInteractions(imageTagRepository); } } From 81aa85fb223d081a023c054c1b8a89cb1fad64f5 Mon Sep 17 00:00:00 2001 From: leeedohyun Date: Sun, 9 Nov 2025 22:09:55 +0900 Subject: [PATCH 4/4] =?UTF-8?q?feat:=20=EC=9C=A0=EC=A0=80=20=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=20=EC=B5=9C=EB=8C=80=20=EA=B0=9C=EC=88=98=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/capturecat/core/service/user/UserTagService.java | 2 +- .../com/capturecat/core/service/user/UserTagServiceTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/capturecat-core/src/main/java/com/capturecat/core/service/user/UserTagService.java b/capturecat-core/src/main/java/com/capturecat/core/service/user/UserTagService.java index b657f4c..87157b3 100644 --- a/capturecat-core/src/main/java/com/capturecat/core/service/user/UserTagService.java +++ b/capturecat-core/src/main/java/com/capturecat/core/service/user/UserTagService.java @@ -30,7 +30,7 @@ @RequiredArgsConstructor public class UserTagService { - private static final int MAX_USER_TAG_COUNT = 30; + private static final int MAX_USER_TAG_COUNT = 40; private final UserRepository userRepository; private final UserTagRepository userTagRepository; diff --git a/capturecat-core/src/test/java/com/capturecat/core/service/user/UserTagServiceTest.java b/capturecat-core/src/test/java/com/capturecat/core/service/user/UserTagServiceTest.java index 07dacdc..b443480 100644 --- a/capturecat-core/src/test/java/com/capturecat/core/service/user/UserTagServiceTest.java +++ b/capturecat-core/src/test/java/com/capturecat/core/service/user/UserTagServiceTest.java @@ -115,7 +115,7 @@ class UserTagServiceTest { given(userRepository.findByUsername(anyString())).willReturn(Optional.of(user)); given(tagRegister.registerTagsFor(anyString())).willReturn(tag); given(userTagRepository.existsByUserAndTag(eq(user), eq(tag))).willReturn(false); - given(userTagRepository.countByUser(eq(user))).willReturn(30L); + given(userTagRepository.countByUser(eq(user))).willReturn(40L); // when & then assertThatThrownBy(() -> userTagService.create(new LoginUser(DummyObject.newUser("test")), "java"))