From 4bcabb9468a7b4b53e77ccb0eb19e011cb3b09b2 Mon Sep 17 00:00:00 2001 From: stoneTiger0912 Date: Mon, 11 Aug 2025 23:38:44 +0900 Subject: [PATCH 1/5] =?UTF-8?q?Feat:=20=EA=B7=B8=EB=A3=B9=20=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20API=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../group/controller/GroupController.java | 12 ++ .../project/flipnote/group/entity/Group.java | 11 ++ .../flipnote/group/entity/GroupMember.java | 5 + .../group/model/GroupDetailResponse.java | 41 +++++ .../flipnote/group/service/GroupService.java | 55 ++++++- .../group/service/GroupServiceTest.java | 146 ++++++++++++------ 6 files changed, 215 insertions(+), 55 deletions(-) create mode 100644 src/main/java/project/flipnote/group/model/GroupDetailResponse.java diff --git a/src/main/java/project/flipnote/group/controller/GroupController.java b/src/main/java/project/flipnote/group/controller/GroupController.java index efe9104a..f10b21a9 100644 --- a/src/main/java/project/flipnote/group/controller/GroupController.java +++ b/src/main/java/project/flipnote/group/controller/GroupController.java @@ -3,6 +3,8 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -13,6 +15,7 @@ import project.flipnote.common.security.dto.AuthPrinciple; import project.flipnote.group.model.GroupCreateRequest; import project.flipnote.group.model.GroupCreateResponse; +import project.flipnote.group.model.GroupDetailResponse; import project.flipnote.group.service.GroupService; @RequiredArgsConstructor @@ -28,4 +31,13 @@ public ResponseEntity create( GroupCreateResponse res = groupService.create(authPrinciple, req); return ResponseEntity.status(HttpStatus.CREATED).body(res); } + + @GetMapping("/{groupId}") + public ResponseEntity findGroupDetail( + @AuthenticationPrincipal AuthPrinciple authPrinciple, + @PathVariable("groupId") Long groupId) { + GroupDetailResponse res = groupService.findGroupDetail(authPrinciple, groupId); + + return ResponseEntity.ok(res); + } } diff --git a/src/main/java/project/flipnote/group/entity/Group.java b/src/main/java/project/flipnote/group/entity/Group.java index bf9551e7..4fe98ed7 100644 --- a/src/main/java/project/flipnote/group/entity/Group.java +++ b/src/main/java/project/flipnote/group/entity/Group.java @@ -1,5 +1,11 @@ package project.flipnote.group.entity; +import java.time.LocalDateTime; + +import org.hibernate.annotations.SQLDelete; +import org.hibernate.annotations.SQLRestriction; +import org.hibernate.annotations.Where; + import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -21,6 +27,8 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) @Table(name = "app_groups") @Entity +@SQLDelete(sql = "UPDATE app_groups SET deleted_at = now() WHERE id = ?") +@SQLRestriction("deleted_at IS NULL") public class Group extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -49,6 +57,9 @@ public class Group extends BaseEntity { private String imageUrl; + @Column(name = "deleted_at") + private LocalDateTime deletedAt; + @Builder private Group( String name, diff --git a/src/main/java/project/flipnote/group/entity/GroupMember.java b/src/main/java/project/flipnote/group/entity/GroupMember.java index 0d41b3ea..c5bc9aea 100644 --- a/src/main/java/project/flipnote/group/entity/GroupMember.java +++ b/src/main/java/project/flipnote/group/entity/GroupMember.java @@ -1,5 +1,8 @@ package project.flipnote.group.entity; +import org.hibernate.annotations.SQLDelete; +import org.hibernate.annotations.SQLRestriction; + import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -21,6 +24,8 @@ @Entity @Table(name = "group_members") @NoArgsConstructor(access = AccessLevel.PROTECTED) +@SQLDelete(sql = "UPDATE group_members SET deleted_at = CURRENT_TIMESTAMP WHERE id = ?") +@SQLRestriction("deleted_at IS NULL") public class GroupMember extends BaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/src/main/java/project/flipnote/group/model/GroupDetailResponse.java b/src/main/java/project/flipnote/group/model/GroupDetailResponse.java new file mode 100644 index 00000000..839f1561 --- /dev/null +++ b/src/main/java/project/flipnote/group/model/GroupDetailResponse.java @@ -0,0 +1,41 @@ +package project.flipnote.group.model; + +import java.time.LocalDateTime; + +import project.flipnote.group.entity.Category; +import project.flipnote.group.entity.Group; + +public record GroupDetailResponse( + + String name, + + Category category, + + String description, + + Boolean applicationRequired, + + Boolean publicVisible, + + Integer maxMember, + + String imageUrl, + + LocalDateTime createdAt, + + LocalDateTime modifiedAt +) { + public static GroupDetailResponse from(Group group) { + return new GroupDetailResponse( + group.getName(), + group.getCategory(), + group.getDescription(), + group.getApplicationRequired(), + group.getPublicVisible(), + group.getMaxMember(), + group.getImageUrl(), + group.getCreatedAt(), + group.getModifiedAt() + ); + } +} diff --git a/src/main/java/project/flipnote/group/service/GroupService.java b/src/main/java/project/flipnote/group/service/GroupService.java index eba053c5..84870f85 100644 --- a/src/main/java/project/flipnote/group/service/GroupService.java +++ b/src/main/java/project/flipnote/group/service/GroupService.java @@ -18,10 +18,12 @@ import project.flipnote.group.exception.GroupErrorCode; import project.flipnote.group.model.GroupCreateRequest; import project.flipnote.group.model.GroupCreateResponse; +import project.flipnote.group.model.GroupDetailResponse; import project.flipnote.group.repository.GroupMemberRepository; import project.flipnote.group.repository.GroupPermissionRepository; import project.flipnote.group.repository.GroupRepository; import project.flipnote.group.repository.GroupRolePermissionRepository; +import project.flipnote.groupjoin.exception.GroupJoinErrorCode; import project.flipnote.user.entity.UserProfile; import project.flipnote.user.entity.UserStatus; import project.flipnote.user.exception.UserErrorCode; @@ -39,19 +41,40 @@ public class GroupService { private final GroupRolePermissionRepository groupRolePermissionRepository; private final UserProfileRepository userProfileRepository; - //유저 정보 조회 - public UserProfile findUser(AuthPrinciple authPrinciple) { + /* + 유저 정보 조회 + */ + public UserProfile validateUser(AuthPrinciple authPrinciple) { return userProfileRepository.findByIdAndStatus(authPrinciple.userId(), UserStatus.ACTIVE).orElseThrow( () -> new BizException(UserErrorCode.USER_NOT_FOUND) ); } + + /* + 그룹 내 유저 조회 + */ + public boolean validateGroupInUser(UserProfile user, Long groupId) { + return groupMemberRepository.existsByGroup_idAndUser_id(groupId, user.getId()); + } + + /* + 그룹 조회 + */ + public Group valiateGroup(Long groupId) { + return groupRepository.findById(groupId).orElseThrow( + () -> new BizException(GroupErrorCode.GROUP_NOT_FOUND) + ); + } - //그룹 생성 + + /* + 그룹 생성 + */ @Transactional public GroupCreateResponse create(AuthPrinciple authPrinciple, GroupCreateRequest req) { //1. 유저 조회 - UserProfile userProfile = findUser(authPrinciple); + UserProfile user = validateUser(authPrinciple); //2. 인원수 검증 validateMaxMember(req.maxMember()); @@ -60,7 +83,7 @@ public GroupCreateResponse create(AuthPrinciple authPrinciple, GroupCreateReques Group group = createGroup(req); //4. 그룹 회원 정보 생성 - saveGroupOwner(group, userProfile); + saveGroupOwner(group, user); //5. 그룹 내의 모든 권한 조회 initializeGroupPermissions(group); @@ -120,11 +143,31 @@ private void saveGroupOwner(Group group, UserProfile user) { groupMemberRepository.save(groupMember); } - //인원수 검증 + /* + 인원수 검증 + */ private void validateMaxMember(int maxMember) { if (maxMember < 1 || maxMember > 100) { throw new BizException(GroupErrorCode.INVALID_MAX_MEMBER); } } + /* + 그룹 상세 정보 조회 + */ + public GroupDetailResponse findGroupDetail(AuthPrinciple authPrinciple, Long groupId) { + + //1. 유저 조회 + UserProfile user = validateUser(authPrinciple); + + Group group = valiateGroup(groupId); + + //2. 그룹 내 유저 조회 + if (!validateGroupInUser(user, groupId)) { + throw new BizException(GroupJoinErrorCode.USER_NOT_IN_GROUP); + } + + + return GroupDetailResponse.from(group); + } } diff --git a/src/test/java/project/flipnote/group/service/GroupServiceTest.java b/src/test/java/project/flipnote/group/service/GroupServiceTest.java index 5383ceec..3f176f73 100644 --- a/src/test/java/project/flipnote/group/service/GroupServiceTest.java +++ b/src/test/java/project/flipnote/group/service/GroupServiceTest.java @@ -1,7 +1,7 @@ package project.flipnote.group.service; import static org.assertj.core.api.Assertions.*; -import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.*; import static org.mockito.BDDMockito.*; import java.util.List; @@ -17,6 +17,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.test.util.ReflectionTestUtils; + +import project.flipnote.auth.entity.AccountRole; import project.flipnote.auth.repository.EmailVerificationRedisRepository; import project.flipnote.common.exception.BizException; import project.flipnote.common.security.dto.AuthPrinciple; @@ -25,6 +27,7 @@ import project.flipnote.group.entity.Group; import project.flipnote.group.entity.GroupPermission; import project.flipnote.group.entity.GroupPermissionStatus; +import project.flipnote.group.exception.GroupErrorCode; import project.flipnote.group.model.GroupCreateRequest; import project.flipnote.group.model.GroupCreateResponse; import project.flipnote.group.repository.GroupMemberRepository; @@ -65,58 +68,103 @@ class GroupServiceTest { @BeforeEach void before() { - // userProfile = UserFixture.createActiveUser(); - // authPrinciple = new AuthPrinciple(userProfile.getId(), userProfile.getEmail(), userProfile.getRole(), userProfile.getTokenVersion()); + userProfile = UserFixture.createActiveUser(); + authPrinciple = new AuthPrinciple(1L, userProfile.getId(), userProfile.getEmail(), AccountRole.USER, 1L); // 사용자 검증 로직 given(userProfileRepository.findByIdAndStatus(userProfile.getId(), UserStatus.ACTIVE)).willReturn(Optional.of( userProfile)); } - // @Test - // void 그룹_생성_성공() { - // // given - // GroupCreateRequest req = new GroupCreateRequest("그룹1", Category.ENGLISH, "설명1", true, true, 100, "www.~~~"); - // Group group = Group.builder().name(req.name()).build(); - // ReflectionTestUtils.setField(group, "id", 1L); - // - // given(groupRepository.save(any(Group.class))).willReturn(group); - // - // // 그룹 퍼미션 미리 세팅 - // List permissions = List.of( - // GroupPermission.builder().name(GroupPermissionStatus.INVITE).build(), - // GroupPermission.builder().name(GroupPermissionStatus.KICK).build(), - // GroupPermission.builder().name(GroupPermissionStatus.JOIN_REQUEST_MANAGE).build() - // ); - // given(groupPermissionRepository.findAll()).willReturn(permissions); - // - // // when - // GroupCreateResponse response = groupService.create(userPrincipal, req); - // - // // then - // assertThat(response.groupId()).isEqualTo(1L); - // } - // - // @Test - // void 그룹_생성_실패_음수() { - // // given - // GroupCreateRequest req = new GroupCreateRequest("그룹1", Category.ENGLISH, "설명1", true, true, -100, "www.~~~"); - // Group group = Group.builder().name(req.name()).build(); - // ReflectionTestUtils.setField(group, "id", 1L); - // - // - // // when & then - // assertThrows(BizException.class, () -> groupService.create(userPrincipal, req)); - // } - // - // @Test - // void 그룹_생성_실패_초과() { - // // given - // GroupCreateRequest req = new GroupCreateRequest("그룹1", Category.ENGLISH, "설명1", true, true, 200, "www.~~~"); - // Group group = Group.builder().name(req.name()).build(); - // ReflectionTestUtils.setField(group, "id", 1L); - // - // // when & then - // assertThrows(BizException.class, () -> groupService.create(userPrincipal, req)); - // } + @Test + void 그룹_생성_성공() { + // given + GroupCreateRequest req = new GroupCreateRequest("그룹1", Category.ENGLISH, "설명1", true, true, 100, "www.~~~"); + Group group = Group.builder().name(req.name()).build(); + ReflectionTestUtils.setField(group, "id", 1L); + + given(groupRepository.save(any(Group.class))).willReturn(group); + + // 그룹 퍼미션 미리 세팅 + List permissions = List.of( + GroupPermission.builder().name(GroupPermissionStatus.INVITE).build(), + GroupPermission.builder().name(GroupPermissionStatus.KICK).build(), + GroupPermission.builder().name(GroupPermissionStatus.JOIN_REQUEST_MANAGE).build() + ); + given(groupPermissionRepository.findAll()).willReturn(permissions); + + // when + GroupCreateResponse response = groupService.create(authPrinciple, req); + + // then + assertThat(response.groupId()).isEqualTo(1L); + } + + @Test + void 그룹_생성_실패_음수() { + // given + GroupCreateRequest req = new GroupCreateRequest("그룹1", Category.ENGLISH, "설명1", true, true, -100, "www.~~~"); + Group group = Group.builder().name(req.name()).build(); + ReflectionTestUtils.setField(group, "id", 1L); + + + // when & then + assertThrows(BizException.class, () -> groupService.create(authPrinciple, req)); + } + + @Test + void 그룹_생성_실패_초과() { + // given + GroupCreateRequest req = new GroupCreateRequest("그룹1", Category.ENGLISH, "설명1", true, true, 200, "www.~~~"); + Group group = Group.builder().name(req.name()).build(); + ReflectionTestUtils.setField(group, "id", 1L); + + // when & then + assertThrows(BizException.class, () -> groupService.create(authPrinciple, req)); + } + + @Test + public void 그룹_상세_조회_성공() throws Exception { + //given + Group group = Group.builder() + .name("그룹1") + .category(Category.IT) + .description("설명1") + .publicVisible(true) + .applicationRequired(true) + .maxMember(100) + .imageUrl("www.~~~") + .build(); + + given(groupRepository.findById(any())).willReturn(Optional.ofNullable(group)); + given(groupMemberRepository.existsByGroup_idAndUser_id(any(), any())).willReturn(true); + + //when + groupService.findGroupDetail(authPrinciple, 1L); + + //then + } + + @Test + public void 그룹_상세_조회_실패_삭제() throws Exception { + //given + Group group = Group.builder() + .name("그룹1") + .category(Category.IT) + .description("설명1") + .publicVisible(true) + .applicationRequired(true) + .maxMember(100) + .imageUrl("www.~~~") + .build(); + + groupRepository.save(group); + groupRepository.delete(group); + + //when & then + BizException exception = + assertThrows(BizException.class, () -> groupService.findGroupDetail(authPrinciple, 1L)); + + assertEquals(GroupErrorCode.GROUP_NOT_FOUND, exception.getErrorCode()); + } } From 915e55d58a1c08b8f935bdc9a67c4d0a77fd93fd Mon Sep 17 00:00:00 2001 From: stoneTiger0912 Date: Mon, 11 Aug 2025 23:44:14 +0900 Subject: [PATCH 2/5] =?UTF-8?q?Fix:=20=EA=B7=B8=EB=A3=B9=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C=EC=8B=9C=20=EC=82=AD=EC=A0=9C=EB=90=9C=20=EA=B7=B8?= =?UTF-8?q?=EB=A3=B9=EC=9D=80=20=EC=A0=9C=EC=99=B8=ED=95=98=EA=B3=A0=20?= =?UTF-8?q?=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flipnote/group/repository/GroupRepository.java | 2 +- .../project/flipnote/group/service/GroupService.java | 11 ++++++----- .../flipnote/group/service/GroupServiceTest.java | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/project/flipnote/group/repository/GroupRepository.java b/src/main/java/project/flipnote/group/repository/GroupRepository.java index 1959fc9f..ec4279be 100644 --- a/src/main/java/project/flipnote/group/repository/GroupRepository.java +++ b/src/main/java/project/flipnote/group/repository/GroupRepository.java @@ -14,7 +14,7 @@ @Repository public interface GroupRepository extends JpaRepository { - Optional findById(Long groupId); + Optional findByIdAndDeletedAtIsNull(Long groupId); @Lock(LockModeType.PESSIMISTIC_WRITE) @Query("select g from Group g where g.id = :id") diff --git a/src/main/java/project/flipnote/group/service/GroupService.java b/src/main/java/project/flipnote/group/service/GroupService.java index 84870f85..a044fe1c 100644 --- a/src/main/java/project/flipnote/group/service/GroupService.java +++ b/src/main/java/project/flipnote/group/service/GroupService.java @@ -61,7 +61,7 @@ public boolean validateGroupInUser(UserProfile user, Long groupId) { 그룹 조회 */ public Group valiateGroup(Long groupId) { - return groupRepository.findById(groupId).orElseThrow( + return groupRepository.findByIdAndDeletedAtIsNull(groupId).orElseThrow( () -> new BizException(GroupErrorCode.GROUP_NOT_FOUND) ); } @@ -156,13 +156,14 @@ private void validateMaxMember(int maxMember) { 그룹 상세 정보 조회 */ public GroupDetailResponse findGroupDetail(AuthPrinciple authPrinciple, Long groupId) { - - //1. 유저 조회 - UserProfile user = validateUser(authPrinciple); + //1. 그룹 조회 Group group = valiateGroup(groupId); - //2. 그룹 내 유저 조회 + //2. 유저 조회 + UserProfile user = validateUser(authPrinciple); + + //3. 그룹 내 유저 조회 if (!validateGroupInUser(user, groupId)) { throw new BizException(GroupJoinErrorCode.USER_NOT_IN_GROUP); } diff --git a/src/test/java/project/flipnote/group/service/GroupServiceTest.java b/src/test/java/project/flipnote/group/service/GroupServiceTest.java index 3f176f73..e2bf0164 100644 --- a/src/test/java/project/flipnote/group/service/GroupServiceTest.java +++ b/src/test/java/project/flipnote/group/service/GroupServiceTest.java @@ -136,7 +136,7 @@ void before() { .imageUrl("www.~~~") .build(); - given(groupRepository.findById(any())).willReturn(Optional.ofNullable(group)); + given(groupRepository.findByIdAndDeletedAtIsNull(any())).willReturn(Optional.ofNullable(group)); given(groupMemberRepository.existsByGroup_idAndUser_id(any(), any())).willReturn(true); //when From ef217d17b0462f8ca694581e114ce71e50a48a7e Mon Sep 17 00:00:00 2001 From: stoneTiger0912 Date: Tue, 12 Aug 2025 21:45:42 +0900 Subject: [PATCH 3/5] =?UTF-8?q?Fix:=20=EA=B7=B8=EB=A3=B9=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=EC=A1=B0=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flipnote/group/service/GroupService.java | 1 - .../group/service/GroupServiceTest.java | 53 +++++++++++++++---- 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/main/java/project/flipnote/group/service/GroupService.java b/src/main/java/project/flipnote/group/service/GroupService.java index a044fe1c..6e00dce9 100644 --- a/src/main/java/project/flipnote/group/service/GroupService.java +++ b/src/main/java/project/flipnote/group/service/GroupService.java @@ -168,7 +168,6 @@ public GroupDetailResponse findGroupDetail(AuthPrinciple authPrinciple, Long gro throw new BizException(GroupJoinErrorCode.USER_NOT_IN_GROUP); } - return GroupDetailResponse.from(group); } } diff --git a/src/test/java/project/flipnote/group/service/GroupServiceTest.java b/src/test/java/project/flipnote/group/service/GroupServiceTest.java index e2bf0164..37c913c5 100644 --- a/src/test/java/project/flipnote/group/service/GroupServiceTest.java +++ b/src/test/java/project/flipnote/group/service/GroupServiceTest.java @@ -30,10 +30,12 @@ import project.flipnote.group.exception.GroupErrorCode; import project.flipnote.group.model.GroupCreateRequest; import project.flipnote.group.model.GroupCreateResponse; +import project.flipnote.group.model.GroupDetailResponse; import project.flipnote.group.repository.GroupMemberRepository; import project.flipnote.group.repository.GroupPermissionRepository; import project.flipnote.group.repository.GroupRepository; import project.flipnote.group.repository.GroupRolePermissionRepository; +import project.flipnote.groupjoin.exception.GroupJoinErrorCode; import project.flipnote.user.entity.UserProfile; import project.flipnote.user.entity.UserStatus; import project.flipnote.user.repository.UserProfileRepository; @@ -70,10 +72,6 @@ class GroupServiceTest { void before() { userProfile = UserFixture.createActiveUser(); authPrinciple = new AuthPrinciple(1L, userProfile.getId(), userProfile.getEmail(), AccountRole.USER, 1L); - - // 사용자 검증 로직 - given(userProfileRepository.findByIdAndStatus(userProfile.getId(), UserStatus.ACTIVE)).willReturn(Optional.of( - userProfile)); } @Test @@ -84,6 +82,9 @@ void before() { ReflectionTestUtils.setField(group, "id", 1L); given(groupRepository.save(any(Group.class))).willReturn(group); + // 사용자 검증 로직 + given(userProfileRepository.findByIdAndStatus(userProfile.getId(), UserStatus.ACTIVE)) + .willReturn(Optional.of(userProfile)); // 그룹 퍼미션 미리 세팅 List permissions = List.of( @@ -106,7 +107,9 @@ void before() { GroupCreateRequest req = new GroupCreateRequest("그룹1", Category.ENGLISH, "설명1", true, true, -100, "www.~~~"); Group group = Group.builder().name(req.name()).build(); ReflectionTestUtils.setField(group, "id", 1L); - + // 사용자 검증 로직 + given(userProfileRepository.findByIdAndStatus(userProfile.getId(), UserStatus.ACTIVE)) + .willReturn(Optional.of(userProfile)); // when & then assertThrows(BizException.class, () -> groupService.create(authPrinciple, req)); @@ -118,6 +121,9 @@ void before() { GroupCreateRequest req = new GroupCreateRequest("그룹1", Category.ENGLISH, "설명1", true, true, 200, "www.~~~"); Group group = Group.builder().name(req.name()).build(); ReflectionTestUtils.setField(group, "id", 1L); + // 사용자 검증 로직 + given(userProfileRepository.findByIdAndStatus(userProfile.getId(), UserStatus.ACTIVE)) + .willReturn(Optional.of(userProfile)); // when & then assertThrows(BizException.class, () -> groupService.create(authPrinciple, req)); @@ -138,15 +144,44 @@ void before() { given(groupRepository.findByIdAndDeletedAtIsNull(any())).willReturn(Optional.ofNullable(group)); given(groupMemberRepository.existsByGroup_idAndUser_id(any(), any())).willReturn(true); - + // 사용자 검증 로직 + given(userProfileRepository.findByIdAndStatus(userProfile.getId(), UserStatus.ACTIVE)) + .willReturn(Optional.of(userProfile)); + //when - groupService.findGroupDetail(authPrinciple, 1L); - + GroupDetailResponse res = groupService.findGroupDetail(authPrinciple, 1L); + + //then + assertEquals("그룹1", res.name()); + } + + @Test + public void 그룹_상세_조회_실패_그룹내_유저가_없는경우() throws Exception { + //given + Group group = Group.builder() + .name("그룹1") + .category(Category.IT) + .description("설명1") + .publicVisible(true) + .applicationRequired(true) + .maxMember(100) + .imageUrl("www.~~~") + .build(); + + given(groupRepository.findByIdAndDeletedAtIsNull(any())).willReturn(Optional.ofNullable(group)); + given(userProfileRepository.findByIdAndStatus(1L, UserStatus.ACTIVE)).willReturn(Optional.ofNullable(userProfile)); + given(groupMemberRepository.existsByGroup_idAndUser_id(any(), any())).willReturn(false); + + //when + BizException exception = + assertThrows(BizException.class, () -> groupService.findGroupDetail(authPrinciple, 1L)); + //then + assertEquals(GroupJoinErrorCode.USER_NOT_IN_GROUP, exception.getErrorCode()); } @Test - public void 그룹_상세_조회_실패_삭제() throws Exception { + public void 그룹_상세_조회_실패_삭제된_경우() throws Exception { //given Group group = Group.builder() .name("그룹1") From 3088d3c47c4aa95b581a44a91b8f8df42df622e1 Mon Sep 17 00:00:00 2001 From: stoneTiger0912 Date: Tue, 12 Aug 2025 22:03:38 +0900 Subject: [PATCH 4/5] =?UTF-8?q?Fix:=20=EC=98=A4=ED=83=80=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/project/flipnote/group/service/GroupService.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/flipnote/group/service/GroupService.java b/src/main/java/project/flipnote/group/service/GroupService.java index af5b04de..2990dbcd 100644 --- a/src/main/java/project/flipnote/group/service/GroupService.java +++ b/src/main/java/project/flipnote/group/service/GroupService.java @@ -61,7 +61,7 @@ public boolean validateGroupInUser(UserProfile user, Long groupId) { /* 그룹 조회 */ - public Group valiateGroup(Long groupId) { + public Group validateGroup(Long groupId) { return groupRepository.findByIdAndDeletedAtIsNull(groupId).orElseThrow( () -> new BizException(GroupErrorCode.GROUP_NOT_FOUND) ); @@ -173,7 +173,7 @@ private void validateMaxMember(int maxMember) { public GroupDetailResponse findGroupDetail(AuthPrinciple authPrinciple, Long groupId) { //1. 그룹 조회 - Group group = valiateGroup(groupId); + Group group = validateGroup(groupId); //2. 유저 조회 UserProfile user = validateUser(authPrinciple); @@ -185,4 +185,8 @@ public GroupDetailResponse findGroupDetail(AuthPrinciple authPrinciple, Long gro return GroupDetailResponse.from(group); } + + public void deleteGroup(AuthPrinciple authPrinciple, Long groupId) { + + } } From 1870b3f339b7cf06a84ca7d599dcd095f76cfebc Mon Sep 17 00:00:00 2001 From: stoneTiger0912 Date: Tue, 12 Aug 2025 22:04:09 +0900 Subject: [PATCH 5/5] =?UTF-8?q?Refactor:=20=EC=A0=95=ED=99=95=ED=95=9C=20?= =?UTF-8?q?=EC=97=90=EB=9F=AC=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flipnote/group/service/GroupServiceTest.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/test/java/project/flipnote/group/service/GroupServiceTest.java b/src/test/java/project/flipnote/group/service/GroupServiceTest.java index 37c913c5..cee94539 100644 --- a/src/test/java/project/flipnote/group/service/GroupServiceTest.java +++ b/src/test/java/project/flipnote/group/service/GroupServiceTest.java @@ -112,7 +112,11 @@ void before() { .willReturn(Optional.of(userProfile)); // when & then - assertThrows(BizException.class, () -> groupService.create(authPrinciple, req)); + BizException exception = assertThrows( + BizException.class, () -> groupService.create(authPrinciple, req) + ); + + assertThat(exception.getErrorCode()).isEqualTo(GroupErrorCode.INVALID_MAX_MEMBER); } @Test @@ -169,7 +173,7 @@ void before() { .build(); given(groupRepository.findByIdAndDeletedAtIsNull(any())).willReturn(Optional.ofNullable(group)); - given(userProfileRepository.findByIdAndStatus(1L, UserStatus.ACTIVE)).willReturn(Optional.ofNullable(userProfile)); + given(userProfileRepository.findByIdAndStatus(userProfile.getId(), UserStatus.ACTIVE)).willReturn(Optional.ofNullable(userProfile)); given(groupMemberRepository.existsByGroup_idAndUser_id(any(), any())).willReturn(false); //when @@ -193,8 +197,7 @@ void before() { .imageUrl("www.~~~") .build(); - groupRepository.save(group); - groupRepository.delete(group); + given(groupRepository.findByIdAndDeletedAtIsNull(1L)).willReturn(Optional.empty()); //when & then BizException exception =