diff --git a/src/main/java/org/noostak/group/api/GroupController.java b/src/main/java/org/noostak/group/api/GroupController.java index a8b913c7..98bf0e74 100644 --- a/src/main/java/org/noostak/group/api/GroupController.java +++ b/src/main/java/org/noostak/group/api/GroupController.java @@ -5,15 +5,14 @@ import org.noostak.group.application.GroupService; import org.noostak.group.dto.request.GroupCreateRequest; import org.noostak.group.dto.response.GroupCreateResponse; +import org.noostak.group.dto.response.GroupsRetrieveResponse; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.io.IOException; import static org.noostak.group.common.success.GroupSuccessCode.GROUP_CREATED; +import static org.noostak.group.common.success.GroupSuccessCode.GROUP_RETRIEVED; @RestController @RequestMapping("/api/v1/groups") @@ -32,4 +31,14 @@ public ResponseEntity> createGroup( GroupCreateResponse response = groupService.createGroup(memberId, request); return ResponseEntity.ok((SuccessResponse.of(GROUP_CREATED, response))); } + + @GetMapping + public ResponseEntity> getGroups( + // @AuthenticationPrincipal Long memberId + ) { + // TODO: AuthenticationPrincipal + Long memberId = 1L; + GroupsRetrieveResponse groups = groupService.findGroups(memberId); + return ResponseEntity.ok(SuccessResponse.of(GROUP_RETRIEVED, groups)); + } } diff --git a/src/main/java/org/noostak/group/application/GroupRetrieveService.java b/src/main/java/org/noostak/group/application/GroupRetrieveService.java new file mode 100644 index 00000000..45b41c31 --- /dev/null +++ b/src/main/java/org/noostak/group/application/GroupRetrieveService.java @@ -0,0 +1,7 @@ +package org.noostak.group.application; + +import org.noostak.group.dto.response.GroupsRetrieveResponse; + +public interface GroupRetrieveService { + GroupsRetrieveResponse findGroups(Long memberId); +} diff --git a/src/main/java/org/noostak/group/application/GroupRetrieveServiceImpl.java b/src/main/java/org/noostak/group/application/GroupRetrieveServiceImpl.java new file mode 100644 index 00000000..a6da47b8 --- /dev/null +++ b/src/main/java/org/noostak/group/application/GroupRetrieveServiceImpl.java @@ -0,0 +1,58 @@ +package org.noostak.group.application; + +import lombok.RequiredArgsConstructor; +import org.noostak.group.common.exception.GroupErrorCode; +import org.noostak.group.common.exception.GroupException; +import org.noostak.group.domain.Groups; +import org.noostak.group.dto.response.GroupInternalRetrieveResponse; +import org.noostak.group.dto.response.GroupRetrieveResponse; +import org.noostak.group.dto.response.GroupsRetrieveResponse; +import org.noostak.infra.S3Service; +import org.noostak.membergroup.domain.MemberGroup; +import org.noostak.membergroup.domain.MemberGroupRepository; +import org.noostak.membergroup.domain.MemberGroups; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class GroupRetrieveServiceImpl implements GroupRetrieveService { + + private final MemberGroupRepository memberGroupRepository; + private final S3Service s3Service; + + @Override + public GroupsRetrieveResponse findGroups(Long memberId) { + MemberGroups memberGroups = getMemberGroups(memberId); + Groups groups = convertToGroups(memberGroups); + return convertToResponse(groups); + } + + private MemberGroups getMemberGroups(Long memberId) { + List foundMemberGroups = memberGroupRepository.findByMemberId(memberId); + MemberGroups memberGroups = MemberGroups.of(foundMemberGroups); + + if (memberGroups.isEmpty()) { + throw new GroupException(GroupErrorCode.GROUP_NOT_FOUND); + } + + return memberGroups; + } + + private Groups convertToGroups(MemberGroups memberGroups) { + return Groups.of(memberGroups.toGroups()); + } + + private GroupsRetrieveResponse convertToResponse(Groups groups) { + List internalResponses = groups.getGroups().stream() + .map(group -> GroupInternalRetrieveResponse.of(group, s3Service.getImageUrl(group.getKey().value()))) + .toList(); + + List groupResponses = internalResponses.stream() + .map(internal -> GroupRetrieveResponse.of(internal.group(), internal.groupProfileImageUrl())) + .toList(); + + return GroupsRetrieveResponse.of(groupResponses); + } +} diff --git a/src/main/java/org/noostak/group/application/GroupService.java b/src/main/java/org/noostak/group/application/GroupService.java index 58aab347..6e40051d 100644 --- a/src/main/java/org/noostak/group/application/GroupService.java +++ b/src/main/java/org/noostak/group/application/GroupService.java @@ -4,6 +4,7 @@ import org.noostak.group.dto.request.GroupCreateRequest; import org.noostak.group.dto.response.GroupCreateInternalResponse; import org.noostak.group.dto.response.GroupCreateResponse; +import org.noostak.group.dto.response.GroupsRetrieveResponse; import org.springframework.stereotype.Service; import java.io.IOException; @@ -13,9 +14,14 @@ public class GroupService { private final GroupCreateService groupCreateService; + private final GroupRetrieveService groupRetrieveService; public GroupCreateResponse createGroup(Long memberId, GroupCreateRequest request) throws IOException { GroupCreateInternalResponse response = groupCreateService.createGroup(memberId, request); return GroupCreateResponse.of(response.group(), response.groupProfileImageUrl()); } + + public GroupsRetrieveResponse findGroups(Long memberId) { + return groupRetrieveService.findGroups(memberId); + } } diff --git a/src/main/java/org/noostak/group/common/exception/GroupErrorCode.java b/src/main/java/org/noostak/group/common/exception/GroupErrorCode.java index 31c20f50..8fa98d1b 100644 --- a/src/main/java/org/noostak/group/common/exception/GroupErrorCode.java +++ b/src/main/java/org/noostak/group/common/exception/GroupErrorCode.java @@ -25,6 +25,8 @@ public enum GroupErrorCode implements ErrorCode { GROUP_CREATION_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "그룹 생성에 실패했습니다."), GROUP_PROFILE_IMAGE_DELETE_FAILED(HttpStatus.INTERNAL_SERVER_ERROR, "그룹 프로필 이미지 삭제에 실패했습니다."), + GROUP_NOT_FOUND(HttpStatus.NOT_FOUND, "그룹을 찾을 수 없습니다."), + GROUP_MEMBER_NOT_FOUND(HttpStatus.NOT_FOUND, "그룹 멤버를 찾을 수 없습니다."), ; public static final String PREFIX = "[GROUP ERROR] "; diff --git a/src/main/java/org/noostak/group/common/success/GroupSuccessCode.java b/src/main/java/org/noostak/group/common/success/GroupSuccessCode.java index 7e0932a7..32593e1c 100644 --- a/src/main/java/org/noostak/group/common/success/GroupSuccessCode.java +++ b/src/main/java/org/noostak/group/common/success/GroupSuccessCode.java @@ -9,6 +9,8 @@ @AllArgsConstructor public enum GroupSuccessCode implements SuccessCode { GROUP_CREATED(HttpStatus.CREATED, "그룹이 성공적으로 생성되었습니다."), + + GROUP_RETRIEVED(HttpStatus.OK, "그룹이 성공적으로 조회되었습니다."), ; private final HttpStatus status; diff --git a/src/main/java/org/noostak/group/domain/Groups.java b/src/main/java/org/noostak/group/domain/Groups.java new file mode 100644 index 00000000..9fdd19d0 --- /dev/null +++ b/src/main/java/org/noostak/group/domain/Groups.java @@ -0,0 +1,20 @@ +package org.noostak.group.domain; + +import java.util.Collections; +import java.util.List; + +public class Groups { + private final List groups; + + private Groups(List groups) { + this.groups = groups; + } + + public static Groups of(final List groups) { + return new Groups(groups); + } + + public List getGroups() { + return Collections.unmodifiableList(groups); + } +} diff --git a/src/main/java/org/noostak/group/dto/response/GroupCreateResponse.java b/src/main/java/org/noostak/group/dto/response/GroupCreateResponse.java index d46be194..bcd2d5ae 100644 --- a/src/main/java/org/noostak/group/dto/response/GroupCreateResponse.java +++ b/src/main/java/org/noostak/group/dto/response/GroupCreateResponse.java @@ -1,9 +1,7 @@ package org.noostak.group.dto.response; -import lombok.Builder; import org.noostak.group.domain.Group; -@Builder public record GroupCreateResponse( Long groupId, String groupName, @@ -11,13 +9,11 @@ public record GroupCreateResponse( String groupInvitationCode ) { public static GroupCreateResponse of(final Group group, final String groupProfileImageUrl) { - { - return GroupCreateResponse.builder() - .groupId(group.getGroupId()) - .groupName(group.getName().value()) - .groupProfileImageUrl(groupProfileImageUrl) - .groupInvitationCode(group.getCode().value()) - .build(); - } + return new GroupCreateResponse( + group.getGroupId(), + group.getName().value(), + groupProfileImageUrl, + group.getCode().value() + ); } -} +} \ No newline at end of file diff --git a/src/main/java/org/noostak/group/dto/response/GroupInternalRetrieveResponse.java b/src/main/java/org/noostak/group/dto/response/GroupInternalRetrieveResponse.java new file mode 100644 index 00000000..12b5519f --- /dev/null +++ b/src/main/java/org/noostak/group/dto/response/GroupInternalRetrieveResponse.java @@ -0,0 +1,15 @@ +package org.noostak.group.dto.response; + +import org.noostak.group.domain.Group; + +public record GroupInternalRetrieveResponse( + Group group, + String groupProfileImageUrl +) { + public static GroupInternalRetrieveResponse of(final Group group, final String groupProfileImageUrl) { + return new GroupInternalRetrieveResponse( + group, + groupProfileImageUrl + ); + } +} diff --git a/src/main/java/org/noostak/group/dto/response/GroupRetrieveResponse.java b/src/main/java/org/noostak/group/dto/response/GroupRetrieveResponse.java new file mode 100644 index 00000000..eef05a5e --- /dev/null +++ b/src/main/java/org/noostak/group/dto/response/GroupRetrieveResponse.java @@ -0,0 +1,19 @@ +package org.noostak.group.dto.response; + +import org.noostak.group.domain.Group; + +public record GroupRetrieveResponse( + Long groupId, + String groupName, + Long groupMemberCount, + String groupProfileImageUrl +) { + public static GroupRetrieveResponse of(final Group group, final String groupProfileImageUrl) { + return new GroupRetrieveResponse( + group.getGroupId(), + group.getName().value(), + group.getCount().value(), + groupProfileImageUrl + ); + } +} \ No newline at end of file diff --git a/src/main/java/org/noostak/group/dto/response/GroupsRetrieveResponse.java b/src/main/java/org/noostak/group/dto/response/GroupsRetrieveResponse.java new file mode 100644 index 00000000..acbc6461 --- /dev/null +++ b/src/main/java/org/noostak/group/dto/response/GroupsRetrieveResponse.java @@ -0,0 +1,11 @@ +package org.noostak.group.dto.response; + +import java.util.List; + +public record GroupsRetrieveResponse( + List groups +) { + public static GroupsRetrieveResponse of(final List groupResponses) { + return new GroupsRetrieveResponse(groupResponses); + } +} diff --git a/src/main/java/org/noostak/infra/S3Service.java b/src/main/java/org/noostak/infra/S3Service.java index 0d875f88..2dbe1aaf 100644 --- a/src/main/java/org/noostak/infra/S3Service.java +++ b/src/main/java/org/noostak/infra/S3Service.java @@ -6,8 +6,6 @@ public interface S3Service { KeyAndUrl uploadImage(S3DirectoryPath dirPath, MultipartFile image) throws IOException; - - String findImageUrl(String key); - + String getImageUrl(String key); void deleteImage(String key); } diff --git a/src/main/java/org/noostak/infra/S3ServiceImpl.java b/src/main/java/org/noostak/infra/S3ServiceImpl.java index 94eb62c4..368f1778 100644 --- a/src/main/java/org/noostak/infra/S3ServiceImpl.java +++ b/src/main/java/org/noostak/infra/S3ServiceImpl.java @@ -24,7 +24,7 @@ public KeyAndUrl uploadImage(S3DirectoryPath dirPath, MultipartFile image) throw } @Override - public String findImageUrl(String key) { + public String getImageUrl(String key) { return s3Storage.findPublicUrlByKey(key); } diff --git a/src/main/java/org/noostak/membergroup/domain/MemberGroup.java b/src/main/java/org/noostak/membergroup/domain/MemberGroup.java new file mode 100644 index 00000000..b2ca0246 --- /dev/null +++ b/src/main/java/org/noostak/membergroup/domain/MemberGroup.java @@ -0,0 +1,35 @@ +package org.noostak.membergroup.domain; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.noostak.global.entity.BaseTimeEntity; +import org.noostak.group.domain.Group; +import org.noostak.member.domain.Member; + +@Entity +@Getter +@NoArgsConstructor +public class MemberGroup extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long memberGroupId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "group_id") + private Group group; + + private MemberGroup(final Member member, final Group groups) { + this.member = member; + this.group = groups; + } + + public static MemberGroup of(final Member member, final Group group) { + return new MemberGroup(member, group); + } +} diff --git a/src/main/java/org/noostak/membergroup/domain/MemberGroupRepository.java b/src/main/java/org/noostak/membergroup/domain/MemberGroupRepository.java new file mode 100644 index 00000000..0db9351c --- /dev/null +++ b/src/main/java/org/noostak/membergroup/domain/MemberGroupRepository.java @@ -0,0 +1,10 @@ +package org.noostak.membergroup.domain; + +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface MemberGroupRepository extends JpaRepository { + + List findByMemberId(Long memberId); +} diff --git a/src/main/java/org/noostak/membergroup/domain/MemberGroups.java b/src/main/java/org/noostak/membergroup/domain/MemberGroups.java index 17c4f3b8..483d9757 100644 --- a/src/main/java/org/noostak/membergroup/domain/MemberGroups.java +++ b/src/main/java/org/noostak/membergroup/domain/MemberGroups.java @@ -1,35 +1,31 @@ package org.noostak.membergroup.domain; -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.noostak.global.entity.BaseTimeEntity; import org.noostak.group.domain.Group; -import org.noostak.member.domain.Member; +import java.util.Collections; +import java.util.List; -@Entity -@Getter -@NoArgsConstructor -public class MemberGroups extends BaseTimeEntity { +public class MemberGroups { + private final List memberGroups; - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long memberGroupId; + private MemberGroups(List memberGroups) { + this.memberGroups = memberGroups; + } - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; + public static MemberGroups of(final List memberGroups) { + return new MemberGroups(memberGroups); + } - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "group_id") - private Group group; + public List getMemberGroups() { + return Collections.unmodifiableList(memberGroups); + } - private MemberGroups(final Member member, final Group groups) { - this.member = member; - this.group = groups; + public List toGroups() { + return memberGroups.stream() + .map(MemberGroup::getGroup) + .toList(); } - public static MemberGroups of(final Member member, final Group group) { - return new MemberGroups(member, group); + public boolean isEmpty() { + return memberGroups.isEmpty(); } } diff --git a/src/main/java/org/noostak/membergroup/domain/temp b/src/main/java/org/noostak/membergroup/domain/temp deleted file mode 100644 index e69de29b..00000000 diff --git a/src/test/java/org/noostak/group/application/GroupRetrieveServiceImplTest.java b/src/test/java/org/noostak/group/application/GroupRetrieveServiceImplTest.java new file mode 100644 index 00000000..aa8bd091 --- /dev/null +++ b/src/test/java/org/noostak/group/application/GroupRetrieveServiceImplTest.java @@ -0,0 +1,202 @@ +package org.noostak.group.application; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.noostak.group.common.exception.GroupErrorCode; +import org.noostak.group.common.exception.GroupException; +import org.noostak.group.domain.Group; +import org.noostak.group.domain.GroupRepository; +import org.noostak.group.domain.vo.GroupName; +import org.noostak.group.domain.vo.GroupProfileImageKey; +import org.noostak.group.dto.response.GroupsRetrieveResponse; +import org.noostak.infra.S3Service; +import org.noostak.member.MemberRepositoryTest; +import org.noostak.member.domain.Member; +import org.noostak.member.domain.MemberRepository; +import org.noostak.member.domain.vo.AuthId; +import org.noostak.member.domain.vo.AuthType; +import org.noostak.member.domain.vo.MemberName; +import org.noostak.member.domain.vo.MemberProfileImageKey; +import org.noostak.membergroup.MemberGroupRepositoryTest; +import org.noostak.membergroup.domain.MemberGroup; +import org.noostak.membergroup.domain.MemberGroupRepository; +import org.noostak.server.group.domain.GroupRepositoryTest; + +import java.util.List; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.mock; + +class GroupRetrieveServiceImplTest { + + private MemberRepository memberRepository; + private GroupRepository groupRepository; + private MemberGroupRepository memberGroupRepository; + private GroupRetrieveServiceImpl groupRetrieveService; + private final S3Service s3Service = mock(S3Service.class); + + private Long savedMemberId; + private Long savedGroup1Id; + private Long savedGroup2Id; + private Long savedGroup3Id; + + @BeforeEach + void setUp() { + memberRepository = new MemberRepositoryTest(); + memberGroupRepository = new MemberGroupRepositoryTest(); + groupRepository = new GroupRepositoryTest(); + memberGroupRepository.deleteAll(); + + groupRetrieveService = new GroupRetrieveServiceImpl(memberGroupRepository, s3Service); + + Member savedMember = saveMember("MemberOne", "key1", "authId1", "refreshToken1"); + savedMemberId = savedMember.getMemberId(); + + Group savedGroup1 = saveGroup(savedMemberId, "StudyGroup", "group-images/1", "ABC123"); + Group savedGroup2 = saveGroup(savedMemberId, "GamingClub", "group-images/2", "XYZ789"); + Group savedGroup3 = saveGroup(savedMemberId, "BookClub", "group-images/3", "LMN456"); + savedGroup1Id = savedGroup1.getGroupId(); + savedGroup2Id = savedGroup2.getGroupId(); + savedGroup3Id = savedGroup3.getGroupId(); + + saveMemberGroup(savedMemberId, savedGroup1Id); + saveMemberGroup(savedMemberId, savedGroup2Id); + saveMemberGroup(savedMemberId, savedGroup3Id); + } + + + @Nested + @DisplayName("성공 케이스") + class Success { + + @Test + @DisplayName("멤버가 여러 개의 그룹을 정상적으로 조회한다.") + void shouldRetrieveMultipleGroupsSuccessfully() { + // given + Long memberId = savedMemberId; + + List memberGroups = memberGroupRepository.findByMemberId(memberId); + assertThat(memberGroups).isNotEmpty(); + + // when + GroupsRetrieveResponse response = groupRetrieveService.findGroups(memberId); + + // then + assertThat(response).isNotNull(); + assertThat(response.groups()).hasSize(3); + } + + @Test + @DisplayName("멤버가 하나의 그룹만 속해 있는 경우 정상 조회") + void shouldRetrieveSingleGroupSuccessfully() { + // given + Long memberId = saveMember("singleUser", "keySingle", "authIdSingle", "refreshTokenSingle").getMemberId(); + Long groupId = saveGroup(memberId, "SingleGroup", "group-images/single", "SINGLE").getGroupId(); + saveMemberGroup(memberId, groupId); + + // when + GroupsRetrieveResponse response = groupRetrieveService.findGroups(memberId); + + // then + assertThat(response).isNotNull(); + assertThat(response.groups()).hasSize(1); + } + + @Test + @DisplayName("여러 명의 멤버가 같은 그룹에 속한 경우 특정 멤버가 정상적으로 조회") + void shouldRetrieveGroupsWhenMultipleMembersInSameGroup() { + // given + Long member1 = saveMember("memberOne", "key1", "authId1", "refreshToken1").getMemberId(); + Long member2 = saveMember("memberTwo", "key2", "authId2", "refreshToken2").getMemberId(); + Long groupId = saveGroup(member1, "SharedGroup", "group-images/shared", "SHARED").getGroupId(); + + saveMemberGroup(member1, groupId); + saveMemberGroup(member2, groupId); + + // when + GroupsRetrieveResponse response1 = groupRetrieveService.findGroups(member1); + GroupsRetrieveResponse response2 = groupRetrieveService.findGroups(member2); + + // then + assertThat(response1.groups()).hasSize(1); + assertThat(response2.groups()).hasSize(1); + } + } + + @Nested + @DisplayName("실패 케이스") + class Failure { + + @Test + @DisplayName("멤버가 속한 그룹이 없는 경우 예외를 발생시킨다.") + void shouldThrowExceptionWhenNoGroupsFound() { + // given + Long invalidMemberId = 999L; + + // when & then + assertThatThrownBy(() -> groupRetrieveService.findGroups(invalidMemberId)) + .isInstanceOf(GroupException.class) + .hasMessage(GroupErrorCode.GROUP_NOT_FOUND.getMessage()); + } + + @Test + @DisplayName("그룹이 삭제된 후 멤버가 속한 그룹을 조회하면 예외 발생") + void shouldThrowExceptionWhenGroupIsDeleted() { + // given + Long memberId = savedMemberId; + memberGroupRepository.deleteAll(); + + // when & then + assertThatThrownBy(() -> groupRetrieveService.findGroups(memberId)) + .isInstanceOf(GroupException.class) + .hasMessage(GroupErrorCode.GROUP_NOT_FOUND.getMessage()); + } + + @Test + @DisplayName("멤버 ID가 null이면 GroupException 발생") + void shouldThrowExceptionWhenMemberIdIsNull() { + // when & then + assertThatThrownBy(() -> groupRetrieveService.findGroups(null)) + .isInstanceOf(GroupException.class) + .hasMessage(GroupErrorCode.GROUP_NOT_FOUND.getMessage()); + } + } + + private Group saveGroup(Long groupHostId, String groupName, String groupImageUrl, String inviteCode) { + return groupRepository.save( + Group.of( + groupHostId, + GroupName.from(groupName), + GroupProfileImageKey.from(groupImageUrl), + inviteCode + ) + ); + } + + private Member saveMember(String name, String key, String authId, String refreshToken) { + return memberRepository.save( + Member.of( + MemberName.from(name), + MemberProfileImageKey.from(key), + AuthType.GOOGLE, + AuthId.from(authId), + refreshToken + ) + ); + } + + private MemberGroup saveMemberGroup(Long memberId, Long groupId) { + Member member = memberRepository.findById(memberId) + .orElseThrow(() -> new GroupException(GroupErrorCode.GROUP_MEMBER_NOT_FOUND)); + + Group group = groupRepository.findById(groupId) + .orElseThrow(() -> new GroupException(GroupErrorCode.GROUP_NOT_FOUND)); + + MemberGroup memberGroup = MemberGroup.of(member, group); + MemberGroup savedMemberGroup = memberGroupRepository.save(memberGroup); + + return savedMemberGroup; + } +} diff --git a/src/test/java/org/noostak/group/domain/GroupRepositoryTest.java b/src/test/java/org/noostak/group/domain/GroupRepositoryTest.java index 04f2ab5c..58b5772f 100644 --- a/src/test/java/org/noostak/group/domain/GroupRepositoryTest.java +++ b/src/test/java/org/noostak/group/domain/GroupRepositoryTest.java @@ -2,6 +2,7 @@ import org.noostak.group.domain.Group; import org.noostak.group.domain.GroupRepository; +import org.noostak.group.domain.Groups; import org.springframework.context.annotation.Primary; import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; @@ -191,5 +192,4 @@ public List findAll(Sort sort) { public Page findAll(Pageable pageable) { return null; } - } diff --git a/src/test/java/org/noostak/membergroup/MemberGroupRepositoryTest.java b/src/test/java/org/noostak/membergroup/MemberGroupRepositoryTest.java new file mode 100644 index 00000000..2991813e --- /dev/null +++ b/src/test/java/org/noostak/membergroup/MemberGroupRepositoryTest.java @@ -0,0 +1,196 @@ +package org.noostak.membergroup; + +import org.noostak.membergroup.domain.MemberGroup; +import org.noostak.membergroup.domain.MemberGroupRepository; +import org.springframework.data.domain.*; +import org.springframework.data.repository.query.FluentQuery; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicLong; +import java.util.function.Function; + +public class MemberGroupRepositoryTest implements MemberGroupRepository { + + private final List memberGroups = new ArrayList<>(); + private final AtomicLong idGenerator = new AtomicLong(1); + + @Override + public MemberGroup save(MemberGroup memberGroup) { + try { + if (memberGroup.getMemberGroupId() == null) { + var idField = MemberGroup.class.getDeclaredField("memberGroupId"); + idField.setAccessible(true); + idField.set(memberGroup, idGenerator.getAndIncrement()); + } + } catch (NoSuchFieldException e) { + throw new RuntimeException("[ERROR] 'memberGroupId' 필드를 MemberGroup 클래스에서 찾을 수 없습니다. 필드 이름이 정확한지 확인하세요.", e); + } catch (IllegalAccessException e) { + throw new RuntimeException("[ERROR] MemberGroup 클래스의 'memberGroupId' 필드에 접근할 수 없습니다. 접근 제한자가 적절한지 확인하세요.", e); + } + memberGroups.add(memberGroup); + return memberGroup; + } + + @Override + public Optional findById(Long id) { + return memberGroups.stream() + .filter(memberGroup -> memberGroup.getMemberGroupId().equals(id)) + .findFirst(); + } + + @Override + public List findByMemberId(Long memberId) { + return memberGroups.stream() + .filter(memberGroup -> memberGroup.getMember().getMemberId().equals(memberId)) + .toList(); + } + + @Override + public List findAll() { + return new ArrayList<>(memberGroups); + } + + @Override + public void deleteAll() { + memberGroups.clear(); + } + + @Override + public void deleteById(Long id) { + memberGroups.removeIf(memberGroup -> memberGroup.getMemberGroupId().equals(id)); + } + + @Override + public void delete(MemberGroup entity) { + + } + + @Override + public void deleteAllById(Iterable longs) { + + } + + @Override + public void deleteAll(Iterable entities) { + + } + + @Override + public boolean existsById(Long id) { + return memberGroups.stream().anyMatch(memberGroup -> memberGroup.getMemberGroupId().equals(id)); + } + + @Override + public long count() { + return memberGroups.size(); + } + + @Override + public List findAllById(Iterable ids) { + List result = new ArrayList<>(); + ids.forEach(id -> findById(id).ifPresent(result::add)); + return result; + } + + @Override + public List saveAll(Iterable entities) { + List result = new ArrayList<>(); + entities.forEach(entity -> { + MemberGroup savedMemberGroup = save(entity); + result.add((S) savedMemberGroup); + }); + return result; + } + + @Override + public void flush() { + + } + + @Override + public S saveAndFlush(S entity) { + return null; + } + + @Override + public List saveAllAndFlush(Iterable entities) { + return List.of(); + } + + @Override + public void deleteAllInBatch(Iterable entities) { + + } + + @Override + public void deleteAllByIdInBatch(Iterable longs) { + + } + + @Override + public void deleteAllInBatch() { + + } + + @Override + public MemberGroup getOne(Long aLong) { + return null; + } + + @Override + public MemberGroup getById(Long aLong) { + return null; + } + + @Override + public MemberGroup getReferenceById(Long aLong) { + return null; + } + + @Override + public Optional findOne(Example example) { + return Optional.empty(); + } + + @Override + public List findAll(Example example) { + return List.of(); + } + + @Override + public List findAll(Example example, Sort sort) { + return List.of(); + } + + @Override + public Page findAll(Example example, Pageable pageable) { + return null; + } + + @Override + public long count(Example example) { + return 0; + } + + @Override + public boolean exists(Example example) { + return false; + } + + @Override + public R findBy(Example example, Function, R> queryFunction) { + return null; + } + + @Override + public List findAll(Sort sort) { + return List.of(); + } + + @Override + public Page findAll(Pageable pageable) { + return null; + } +}