From 6daf86c2affc8ae5fa4ef4001ef940ce7efe2d3d Mon Sep 17 00:00:00 2001 From: hong seokho Date: Wed, 12 Jun 2024 22:26:14 +0900 Subject: [PATCH 1/9] =?UTF-8?q?fix=20:=20=EA=B7=B8=EB=A3=B9=20=EC=BA=A1?= =?UTF-8?q?=EC=8A=90=20=EC=9A=94=EC=95=BD=20=EC=A1=B0=ED=9A=8C=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 - 멤버 아이디 추가 - 그룹 아이디 추가 --- .../data/dto/GroupCapsuleDetailDto.java | 9 ++- .../data/dto/GroupCapsuleMemberDto.java | 15 ++++ .../dto/GroupCapsuleMemberSummaryDto.java | 14 ++++ .../data/dto/GroupCapsuleSummaryDto.java | 58 ++++++++------- .../response/GroupCapsuleDetailResponse.java | 4 +- .../response/GroupCapsuleMemberResponse.java | 21 ++++++ .../GroupCapsuleMemberSummaryResponse.java} | 4 +- .../response/GroupCapsuleSummaryResponse.java | 12 ++-- .../GroupCapsuleQueryRepository.java | 70 ++++++++++++------- .../group/data/dto/GroupMemberSummaryDto.java | 15 ---- 10 files changed, 143 insertions(+), 79 deletions(-) create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberSummaryDto.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java rename backend/core/src/main/java/site/timecapsulearchive/core/domain/{group/data/response/GroupMemberSummaryResponse.java => capsule/group_capsule/data/response/GroupCapsuleMemberSummaryResponse.java} (69%) delete mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/group/data/dto/GroupMemberSummaryDto.java diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleDetailDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleDetailDto.java index e47993f89..e7e83d422 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleDetailDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleDetailDto.java @@ -5,17 +5,16 @@ import org.locationtech.jts.geom.Point; import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleDetailDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleDetailResponse; -import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberSummaryDto; -import site.timecapsulearchive.core.domain.group.data.response.GroupMemberSummaryResponse; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleMemberSummaryResponse; public record GroupCapsuleDetailDto( CapsuleDetailDto capsuleDetailDto, - List members + List members ) { - public List groupMemberSummaryDtoToResponse() { + public List groupMemberSummaryDtoToResponse() { return members.stream() - .map(GroupMemberSummaryDto::toResponse) + .map(GroupCapsuleMemberSummaryDto::toResponse) .toList(); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java new file mode 100644 index 000000000..28d8983cf --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java @@ -0,0 +1,15 @@ +package site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto; + +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleMemberResponse; + +public record GroupCapsuleMemberDto( + Long id, + String nickname, + String profileUrl, + Boolean isOpened +) { + + public GroupCapsuleMemberResponse toResponse() { + return new GroupCapsuleMemberResponse(id, nickname, profileUrl, isOpened); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberSummaryDto.java new file mode 100644 index 000000000..b5788148d --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberSummaryDto.java @@ -0,0 +1,14 @@ +package site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto; + +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleMemberSummaryResponse; + +public record GroupCapsuleMemberSummaryDto( + String nickname, + String profileUrl, + Boolean isOpened +) { + + public GroupCapsuleMemberSummaryResponse toResponse() { + return new GroupCapsuleMemberSummaryResponse(nickname, profileUrl, isOpened); + } +} \ No newline at end of file diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java index b3306cf0a..f2dbdfbed 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java @@ -1,43 +1,51 @@ package site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto; +import java.time.ZonedDateTime; import java.util.List; -import java.util.function.Function; +import java.util.function.UnaryOperator; import org.locationtech.jts.geom.Point; -import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleSummaryDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleMemberResponse; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleSummaryResponse; -import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberSummaryDto; -import site.timecapsulearchive.core.domain.group.data.response.GroupMemberSummaryResponse; public record GroupCapsuleSummaryDto( - CapsuleSummaryDto capsuleSummaryDto, - List members + Long groupId, + String nickname, + String profileUrl, + String skinUrl, + String title, + ZonedDateTime dueDate, + Point point, + String address, + String roadName, + Boolean isOpened, + ZonedDateTime createdAt, + List groupMembers ) { - public List groupMemberSummaryDtoToResponse() { - return members.stream() - .map(GroupMemberSummaryDto::toResponse) - .toList(); - } - public GroupCapsuleSummaryResponse toResponse( - final Function preSignUrlFunction, - final Function changePointFunction + final UnaryOperator preSignUrlFunction, + final UnaryOperator changePointFunction ) { - final Point changePoint = changePointFunction.apply(capsuleSummaryDto.point()); + final Point changePoint = changePointFunction.apply(point); + + final List groupMembersResponse = groupMembers.stream() + .map(GroupCapsuleMemberDto::toResponse) + .toList(); return GroupCapsuleSummaryResponse.builder() - .members(groupMemberSummaryDtoToResponse()) - .nickname(capsuleSummaryDto.nickname()) - .profileUrl(capsuleSummaryDto.profileUrl()) - .skinUrl(preSignUrlFunction.apply(capsuleSummaryDto.skinUrl())) - .title(capsuleSummaryDto.title()) - .dueDate(capsuleSummaryDto.dueDate()) + .groupId(groupId) + .groupMembers(groupMembersResponse) + .nickname(nickname) + .profileUrl(profileUrl) + .skinUrl(preSignUrlFunction.apply(skinUrl)) + .title(title) + .dueDate(dueDate) .latitude(changePoint.getX()) .longitude(changePoint.getY()) - .address(capsuleSummaryDto.address()) - .roadName(capsuleSummaryDto.roadName()) - .isOpened(capsuleSummaryDto.isOpened()) - .createdAt(capsuleSummaryDto.createdAt()) + .address(address) + .roadName(roadName) + .isOpened(isOpened) + .createdAt(createdAt) .build(); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleDetailResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleDetailResponse.java index 378ec4751..fba1be05b 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleDetailResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleDetailResponse.java @@ -8,12 +8,12 @@ import org.locationtech.jts.geom.Point; import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; -import site.timecapsulearchive.core.domain.group.data.response.GroupMemberSummaryResponse; import site.timecapsulearchive.core.global.common.response.ResponseMappingConstant; @Schema(description = "그룹 캡슐 상세 정보") @Builder public record GroupCapsuleDetailResponse( + @Schema(description = "캡슐 아이디") Long capsuleId, @@ -21,7 +21,7 @@ public record GroupCapsuleDetailResponse( String capsuleSkinUrl, @Schema(description = "그룹원 요약 정보") - List members, + List members, @Schema(description = "개봉일") ZonedDateTime dueDate, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java new file mode 100644 index 000000000..8bfccdd9e --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java @@ -0,0 +1,21 @@ +package site.timecapsulearchive.core.domain.capsule.group_capsule.data.response; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "그룹원 요약 정보") +public record GroupCapsuleMemberResponse( + + @Schema(description = "멤버 아이디") + Long id, + + @Schema(description = "닉네임") + String nickname, + + @Schema(description = "프로필 url") + String profileUrl, + + @Schema(description = "개봉 여부") + Boolean isOpened +) { + +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/data/response/GroupMemberSummaryResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberSummaryResponse.java similarity index 69% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/group/data/response/GroupMemberSummaryResponse.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberSummaryResponse.java index d780de6a5..c7fccd3b7 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/data/response/GroupMemberSummaryResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberSummaryResponse.java @@ -1,9 +1,9 @@ -package site.timecapsulearchive.core.domain.group.data.response; +package site.timecapsulearchive.core.domain.capsule.group_capsule.data.response; import io.swagger.v3.oas.annotations.media.Schema; @Schema(description = "그룹원 요약 정보") -public record GroupMemberSummaryResponse( +public record GroupCapsuleMemberSummaryResponse( @Schema(description = "닉네임") String nickname, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java index 4337b2879..99b65b1bd 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java @@ -3,19 +3,21 @@ import io.swagger.v3.oas.annotations.media.Schema; import java.time.ZonedDateTime; import java.util.List; -import java.util.function.Function; +import java.util.function.UnaryOperator; import lombok.Builder; import org.locationtech.jts.geom.Point; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; -import site.timecapsulearchive.core.domain.group.data.response.GroupMemberSummaryResponse; import site.timecapsulearchive.core.global.common.response.ResponseMappingConstant; @Schema(description = "캡슐 요약 정보") @Builder public record GroupCapsuleSummaryResponse( + @Schema(description = "그룹 아이디") + Long groupId, + @Schema(description = "그룹원 요약 정보") - List members, + List groupMembers, @Schema(description = "생성자 닉네임") String nickname, @@ -61,8 +63,8 @@ public record GroupCapsuleSummaryResponse( public static GroupCapsuleSummaryResponse createOf( final GroupCapsuleSummaryDto summaryDto, - final Function preSignUrlFunction, - final Function changePointFunction + final UnaryOperator preSignUrlFunction, + final UnaryOperator changePointFunction ) { return summaryDto.toResponse(preSignUrlFunction, changePointFunction); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java index 92f3b8b23..78accfa8d 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java @@ -23,11 +23,11 @@ import site.timecapsulearchive.core.domain.capsule.data.dto.CapsuleBasicInfoDto; import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType; import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleDetailDto; -import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; -import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberSummaryDto; import site.timecapsulearchive.core.domain.member.entity.QMember; import site.timecapsulearchive.core.global.util.SliceUtil; @@ -76,7 +76,7 @@ public Optional findGroupCapsuleDetailDtoByCapsuleId( capsule.isOpened, capsule.type ), - list(Projections.constructor(GroupMemberSummaryDto.class, + list(Projections.constructor(GroupCapsuleMemberSummaryDto.class, groupMember.nickname, groupMember.profileUrl, groupCapsuleOpen.isOpened) @@ -95,21 +95,36 @@ public Optional findGroupCapsuleSummaryDtoByCapsuleId( final QMember owner = new QMember("owner"); final QMember groupMember = new QMember("groupMember"); - return Optional.ofNullable(jpaQueryFactory - .selectFrom(capsule) - .join(owner).on(capsule.member.id.eq(owner.id)) - .join(capsuleSkin).on(capsule.capsuleSkin.id.eq(capsuleSkin.id)).join(groupCapsuleOpen) - .on(groupCapsuleOpen.capsule.id.eq(capsuleId)) - .join(groupMember).on(groupMember.id.eq(groupCapsuleOpen.member.id)) - .groupBy(groupCapsuleOpen.id) - .where(groupCapsuleOpen.capsule.id.eq(capsuleId)) - .where(capsule.id.eq(capsuleId).and(capsule.type.eq(CapsuleType.GROUP))) - .transform( - groupBy(capsule.id).as( - Projections.constructor( - GroupCapsuleSummaryDto.class, + return Optional.ofNullable( + jpaQueryFactory + .select( + groupCapsuleOpen.group.id, + owner.nickname, + owner.profileUrl, + capsuleSkin.imageUrl, + capsule.title, + capsule.dueDate, + capsule.point, + capsule.address.fullRoadAddressName, + capsule.address.roadName, + capsule.isOpened, + capsule.createdAt, + groupMember.id, + groupMember.nickname, + groupMember.profileUrl, + groupCapsuleOpen.isOpened + ) + .from(capsule) + .join(owner).on(owner.id.eq(capsule.member.id)) + .join(capsule.capsuleSkin, capsuleSkin) + .join(capsule.groupCapsuleOpens, groupCapsuleOpen) + .join(groupMember).on(groupMember.id.eq(groupCapsuleOpen.member.id)) + .where(capsule.id.eq(capsuleId).and(capsule.type.eq(CapsuleType.GROUP))) + .transform( + groupBy(capsule.id).as( Projections.constructor( - CapsuleSummaryDto.class, + GroupCapsuleSummaryDto.class, + groupCapsuleOpen.group.id, owner.nickname, owner.profileUrl, capsuleSkin.imageUrl, @@ -119,17 +134,22 @@ public Optional findGroupCapsuleSummaryDtoByCapsuleId( capsule.address.fullRoadAddressName, capsule.address.roadName, capsule.isOpened, - capsule.createdAt - ), - list(Projections.constructor(GroupMemberSummaryDto.class, - groupMember.nickname, - groupMember.profileUrl, - groupCapsuleOpen.isOpened) + capsule.createdAt, + list( + Projections.constructor( + GroupCapsuleMemberDto.class, + groupMember.id, + groupMember.nickname, + groupMember.profileUrl, + groupCapsuleOpen.isOpened + ) + ) ) - ) + ) ) - ).get(capsuleId)); + .get(capsuleId) + ); } public Slice findMyGroupCapsuleSlice( diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/data/dto/GroupMemberSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/data/dto/GroupMemberSummaryDto.java deleted file mode 100644 index d4eb241fe..000000000 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/data/dto/GroupMemberSummaryDto.java +++ /dev/null @@ -1,15 +0,0 @@ -package site.timecapsulearchive.core.domain.group.data.dto; - -import site.timecapsulearchive.core.domain.group.data.response.GroupMemberSummaryResponse; - -public record GroupMemberSummaryDto( - String nickname, - String profileUrl, - Boolean isOpened -) { - - public GroupMemberSummaryResponse toResponse() { - return new GroupMemberSummaryResponse(nickname, profileUrl, isOpened); - } - -} \ No newline at end of file From 097ad6bb71200f1c3cfce70823b56aa77fc73ab1 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Thu, 13 Jun 2024 00:08:48 +0900 Subject: [PATCH 2/9] =?UTF-8?q?test=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/fixture/dto/CapsuleDtoFixture.java | 6 ++--- .../GroupCapsuleQueryRepositoryTest.java | 26 ++++++++++--------- .../service/GroupCapsuleServiceTest.java | 14 +++++----- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/CapsuleDtoFixture.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/CapsuleDtoFixture.java index be4754179..77185d08a 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/CapsuleDtoFixture.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/CapsuleDtoFixture.java @@ -7,7 +7,7 @@ import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType; import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleDetailDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; -import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberSummaryDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberSummaryDto; public class CapsuleDtoFixture { @@ -29,9 +29,9 @@ public static Optional getGroupCapsuleDetailDto(Long caps getGroupMemberSummaryDtos(count))); } - private static List getGroupMemberSummaryDtos(int count) { + private static List getGroupMemberSummaryDtos(int count) { return IntStream.range(0, count) - .mapToObj(i -> new GroupMemberSummaryDto(i + "testNickname", i + "testUrl", true)) + .mapToObj(i -> new GroupCapsuleMemberSummaryDto(i + "testNickname", i + "testUrl", true)) .toList(); } } \ No newline at end of file diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepositoryTest.java index 94f0a09ae..4cf4ec742 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepositoryTest.java @@ -27,12 +27,11 @@ import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType; import site.timecapsulearchive.core.domain.capsule.entity.GroupCapsuleOpen; import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleDetailDto; -import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; import site.timecapsulearchive.core.domain.capsuleskin.entity.CapsuleSkin; -import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberSummaryDto; import site.timecapsulearchive.core.domain.group.entity.Group; import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; @@ -115,7 +114,7 @@ void setup(@Autowired EntityManager entityManager) { //when GroupCapsuleDetailDto detailDto = groupCapsuleQueryRepository.findGroupCapsuleDetailDtoByCapsuleId( capsule.getId()).orElseThrow(); - List summaryDto = detailDto.members(); + List summaryDto = detailDto.members(); //then assertSoftly( @@ -144,9 +143,8 @@ void setup(@Autowired EntityManager entityManager) { void 그룹캡슐_아이디로_그룹_캡슐의_요약_조회_하면_요약_내용을_조회할_수_있다() { // given //when - GroupCapsuleSummaryDto detailDto = groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId( + GroupCapsuleSummaryDto capsuleSummaryDto = groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId( capsule.getId()).orElseThrow(); - CapsuleSummaryDto capsuleSummaryDto = detailDto.capsuleSummaryDto(); //then assertSoftly( @@ -162,17 +160,21 @@ void setup(@Autowired EntityManager entityManager) { void 그룹캡슐_아이디로_그룹_캡슐의_요약_조회_하면_그룹원_정보를_조회할_수_있다() { // given //when - GroupCapsuleSummaryDto detailDto = groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId( + GroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId( capsule.getId()).orElseThrow(); - List summaryDto = detailDto.members(); //then assertSoftly( softly -> { - softly.assertThat(summaryDto).isNotEmpty(); - softly.assertThat(summaryDto).allMatch(dto -> !dto.isOpened()); - softly.assertThat(summaryDto).allMatch(dto -> !dto.profileUrl().isEmpty()); - softly.assertThat(summaryDto).allMatch(dto -> !dto.nickname().isEmpty()); + softly.assertThat(groupCapsuleSummaryDto.groupMembers()).isNotEmpty(); + softly.assertThat(groupCapsuleSummaryDto.groupMembers()) + .allMatch(dto -> dto.id() != null); + softly.assertThat(groupCapsuleSummaryDto.groupMembers()) + .allMatch(dto -> !dto.isOpened()); + softly.assertThat(groupCapsuleSummaryDto.groupMembers()) + .allMatch(dto -> !dto.profileUrl().isEmpty()); + softly.assertThat(groupCapsuleSummaryDto.groupMembers()) + .allMatch(dto -> !dto.nickname().isEmpty()); }); } @@ -201,7 +203,7 @@ void setup(@Autowired EntityManager entityManager) { //then assertSoftly(softly -> { assertThat(groupCapsules.hasContent()).isTrue(); - assertThat(groupCapsules).allMatch(c-> c.capsuleType().equals(CapsuleType.GROUP)); + assertThat(groupCapsules).allMatch(c -> c.capsuleType().equals(CapsuleType.GROUP)); assertThat(groupCapsules).allMatch(c -> c.createdAt().isBefore(now)); }); } diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java index 4b361ab24..f3148906b 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java @@ -33,7 +33,7 @@ import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleOpenQueryRepository; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleQueryRepository; -import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberSummaryDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberSummaryDto; import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; @@ -71,7 +71,7 @@ class GroupCapsuleServiceTest { //then assertSoftly(softly -> { CapsuleDetailDto detailDto = response.capsuleDetailDto(); - List members = response.members(); + List members = response.members(); softly.assertThat(response).isNotNull(); softly.assertThat(detailDto.isOpened()).isTrue(); softly.assertThat(detailDto.title()).isNotBlank(); @@ -97,7 +97,7 @@ class GroupCapsuleServiceTest { //then assertSoftly(softly -> { CapsuleDetailDto detailDto = response.capsuleDetailDto(); - List members = response.members(); + List members = response.members(); softly.assertThat(response).isNotNull(); softly.assertThat(detailDto.isOpened()).isTrue(); softly.assertThat(detailDto.title()).isNotBlank(); @@ -123,7 +123,7 @@ class GroupCapsuleServiceTest { //then assertSoftly(softly -> { CapsuleDetailDto detailDto = response.capsuleDetailDto(); - List members = response.members(); + List members = response.members(); softly.assertThat(response).isNotNull(); softly.assertThat(detailDto.isOpened()).isFalse(); softly.assertThat(detailDto.title()).isNotBlank(); @@ -150,7 +150,7 @@ class GroupCapsuleServiceTest { //then assertSoftly(softly -> { CapsuleDetailDto detailDto = response.capsuleDetailDto(); - List members = response.members(); + List members = response.members(); softly.assertThat(response).isNotNull(); softly.assertThat(detailDto.isOpened()).isFalse(); softly.assertThat(detailDto.images()).isNullOrEmpty(); @@ -175,7 +175,7 @@ class GroupCapsuleServiceTest { //then assertSoftly(softly -> { CapsuleDetailDto detailDto = response.capsuleDetailDto(); - List members = response.members(); + List members = response.members(); softly.assertThat(response).isNotNull(); softly.assertThat(detailDto.isOpened()).isFalse(); softly.assertThat(detailDto.images()).isNullOrEmpty(); @@ -200,7 +200,7 @@ class GroupCapsuleServiceTest { //then assertSoftly(softly -> { CapsuleDetailDto detailDto = response.capsuleDetailDto(); - List members = response.members(); + List members = response.members(); softly.assertThat(response).isNotNull(); softly.assertThat(detailDto.isOpened()).isTrue(); softly.assertThat(detailDto.images()).isNullOrEmpty(); From 8d5aa2eb6dd421b296bc81fd518093011260da23 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Fri, 14 Jun 2024 01:12:44 +0900 Subject: [PATCH 3/9] =?UTF-8?q?fix=20:=20=EA=B7=B8=EB=A3=B9=20=EC=BA=A1?= =?UTF-8?q?=EC=8A=90=20=EC=9A=94=EC=95=BD=20=EC=A1=B0=ED=9A=8C=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 --- .../group_capsule/api/GroupCapsuleApi.java | 3 ++ .../api/GroupCapsuleApiController.java | 8 +++-- .../data/dto/GroupCapsuleMemberDto.java | 6 ++-- .../data/dto/GroupCapsuleSummaryDto.java | 12 ++++--- .../response/GroupCapsuleMemberResponse.java | 9 +++-- .../response/GroupCapsuleSummaryResponse.java | 10 ++++-- .../GroupCapsuleQueryRepository.java | 35 ++++++++++++++++--- .../service/GroupCapsuleService.java | 33 ++++++++++------- 8 files changed, 85 insertions(+), 31 deletions(-) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApi.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApi.java index 4ea78b58d..f61b6a45d 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApi.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApi.java @@ -98,6 +98,9 @@ ResponseEntity> getGroupCapsuleDetailByCapsu ResponseEntity> getGroupCapsuleSummaryByCapsuleId( Long memberId, + @Parameter(in = ParameterIn.QUERY, description = "그룹 아이디", required = true) + Long groupId, + @Parameter(in = ParameterIn.PATH, description = "조회할 캡슐 아이디", required = true) Long capsuleId ); diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApiController.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApiController.java index f2d701514..385ea4d5a 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApiController.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApiController.java @@ -95,10 +95,14 @@ public ResponseEntity> getGroupCapsuleDetail @Override public ResponseEntity> getGroupCapsuleSummaryByCapsuleId( @AuthenticationPrincipal Long memberId, + @RequestParam("group_id") Long groupId, @PathVariable("capsule_id") Long capsuleId ) { - final GroupCapsuleSummaryDto summaryDto = groupCapsuleService.findGroupCapsuleSummaryByGroupIDAndCapsuleId( - capsuleId); + final GroupCapsuleSummaryDto summaryDto = groupCapsuleService.findGroupCapsuleSummary( + memberId, + groupId, + capsuleId + ); return ResponseEntity.ok( ApiSpec.success( diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java index 28d8983cf..ebe60aaad 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java @@ -3,13 +3,15 @@ import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleMemberResponse; public record GroupCapsuleMemberDto( - Long id, String nickname, String profileUrl, + Boolean isRequestMember, + Boolean isGroupOwner, Boolean isOpened ) { public GroupCapsuleMemberResponse toResponse() { - return new GroupCapsuleMemberResponse(id, nickname, profileUrl, isOpened); + return new GroupCapsuleMemberResponse(nickname, profileUrl, isOpened, isGroupOwner, + isRequestMember); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java index f2dbdfbed..3cdaa57ed 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java @@ -9,8 +9,10 @@ public record GroupCapsuleSummaryDto( Long groupId, - String nickname, - String profileUrl, + String groupName, + String groupProfileUrl, + String creatorNickname, + String creatorProfileUrl, String skinUrl, String title, ZonedDateTime dueDate, @@ -35,8 +37,10 @@ public GroupCapsuleSummaryResponse toResponse( return GroupCapsuleSummaryResponse.builder() .groupId(groupId) .groupMembers(groupMembersResponse) - .nickname(nickname) - .profileUrl(profileUrl) + .groupName(groupName) + .groupProfileUrl(preSignUrlFunction.apply(groupProfileUrl)) + .creatorNickname(creatorNickname) + .creatorProfileUrl(creatorProfileUrl) .skinUrl(preSignUrlFunction.apply(skinUrl)) .title(title) .dueDate(dueDate) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java index 8bfccdd9e..9719cb281 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java @@ -5,15 +5,18 @@ @Schema(description = "그룹원 요약 정보") public record GroupCapsuleMemberResponse( - @Schema(description = "멤버 아이디") - Long id, - @Schema(description = "닉네임") String nickname, @Schema(description = "프로필 url") String profileUrl, + @Schema(description = "현재 요청한 사용자 여부") + Boolean isRequestMember, + + @Schema(description = "그룹장 여부") + Boolean isGroupOwner, + @Schema(description = "개봉 여부") Boolean isOpened ) { diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java index 99b65b1bd..ecc639e68 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java @@ -19,11 +19,17 @@ public record GroupCapsuleSummaryResponse( @Schema(description = "그룹원 요약 정보") List groupMembers, + @Schema(description = "그룹 이름") + String groupName, + + @Schema(description = "그룹 프로필 url") + String groupProfileUrl, + @Schema(description = "생성자 닉네임") - String nickname, + String creatorNickname, @Schema(description = "생성자 프로필 url") - String profileUrl, + String creatorProfileUrl, @Schema(description = "캡슐 스킨 url") String skinUrl, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java index 78accfa8d..3dc96e8d6 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java @@ -7,11 +7,16 @@ import static site.timecapsulearchive.core.domain.capsule.entity.QImage.image; import static site.timecapsulearchive.core.domain.capsule.entity.QVideo.video; import static site.timecapsulearchive.core.domain.capsuleskin.entity.QCapsuleSkin.capsuleSkin; +import static site.timecapsulearchive.core.domain.group.entity.QGroup.group; import static site.timecapsulearchive.core.domain.member.entity.QMember.member; +import static site.timecapsulearchive.core.domain.member_group.entity.QMemberGroup.memberGroup; +import com.querydsl.core.types.Expression; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.core.types.dsl.Expressions; +import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.time.ZonedDateTime; @@ -91,7 +96,10 @@ private StringExpression groupConcatDistinct(final StringExpression expression) } public Optional findGroupCapsuleSummaryDtoByCapsuleId( - final Long capsuleId) { + final Long memberId, + final Long groupId, + final Long capsuleId + ) { final QMember owner = new QMember("owner"); final QMember groupMember = new QMember("groupMember"); @@ -99,6 +107,8 @@ public Optional findGroupCapsuleSummaryDtoByCapsuleId( jpaQueryFactory .select( groupCapsuleOpen.group.id, + group.groupName, + group.groupProfileUrl, owner.nickname, owner.profileUrl, capsuleSkin.imageUrl, @@ -109,22 +119,30 @@ public Optional findGroupCapsuleSummaryDtoByCapsuleId( capsule.address.roadName, capsule.isOpened, capsule.createdAt, - groupMember.id, groupMember.nickname, groupMember.profileUrl, + groupMember.id, + memberGroup.isOwner, groupCapsuleOpen.isOpened ) .from(capsule) .join(owner).on(owner.id.eq(capsule.member.id)) .join(capsule.capsuleSkin, capsuleSkin) .join(capsule.groupCapsuleOpens, groupCapsuleOpen) + .join(capsule.group, group) .join(groupMember).on(groupMember.id.eq(groupCapsuleOpen.member.id)) - .where(capsule.id.eq(capsuleId).and(capsule.type.eq(CapsuleType.GROUP))) + .join(memberGroup).on(memberGroup.member.id.eq(groupMember.id)) + .where(capsule.id.eq(capsuleId) + .and(memberGroup.group.id.eq(groupId)) + .and(capsule.type.eq(CapsuleType.GROUP)) + ) .transform( groupBy(capsule.id).as( Projections.constructor( GroupCapsuleSummaryDto.class, groupCapsuleOpen.group.id, + group.groupName, + group.groupProfileUrl, owner.nickname, owner.profileUrl, capsuleSkin.imageUrl, @@ -138,20 +156,27 @@ public Optional findGroupCapsuleSummaryDtoByCapsuleId( list( Projections.constructor( GroupCapsuleMemberDto.class, - groupMember.id, groupMember.nickname, groupMember.profileUrl, + isRequestMemberCase(groupMember, memberId), + memberGroup.isOwner, groupCapsuleOpen.isOpened ) ) ) - ) ) .get(capsuleId) ); } + private Expression isRequestMemberCase(QMember groupMember, Long memberId) { + return new CaseBuilder() + .when(groupMember.id.eq(memberId)) + .then(Boolean.TRUE) + .otherwise(Boolean.FALSE); + } + public Slice findMyGroupCapsuleSlice( final Long memberId, final int size, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java index 715007656..69f12f3e5 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java @@ -15,9 +15,9 @@ import site.timecapsulearchive.core.domain.capsule.generic_capsule.repository.capsule.CapsuleRepository; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleCreateRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleOpenStateDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleOpenStateDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleOpenQueryRepository; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleQueryRepository; @@ -76,12 +76,26 @@ private boolean capsuleNotOpened(final GroupCapsuleDetailDto detailDto) { .isAfter(ZonedDateTime.now(ZoneOffset.UTC)); } - public GroupCapsuleSummaryDto findGroupCapsuleSummaryByGroupIDAndCapsuleId( - final Long capsuleId) { - return groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(capsuleId) + public GroupCapsuleSummaryDto findGroupCapsuleSummary( + final Long memberId, + final Long groupId, + final Long capsuleId + ) { + checkGroupAuthority(memberId, groupId); + + return groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(memberId, groupId, + capsuleId) .orElseThrow(CapsuleNotFondException::new); } + private void checkGroupAuthority(Long memberId, Long groupId) { + boolean isGroupMember = memberGroupRepository.existMemberGroupByMemberIdAndGroupId(memberId, + groupId); + if (!isGroupMember) { + throw new NoGroupAuthorityException(); + } + } + /** * 사용자가 만든 모든 그룹 캡슐을 조회한다. * @@ -130,11 +144,7 @@ public GroupCapsuleOpenStateDto openGroupCapsule(final Long memberId, final Long } public Slice findGroupCapsuleSlice(final GroupCapsuleSliceRequestDto dto) { - boolean isGroupMember = memberGroupRepository.existMemberGroupByMemberIdAndGroupId(dto.memberId(), - dto.groupId()); - if (!isGroupMember) { - throw new NoGroupAuthorityException(); - } + checkGroupAuthority(dto.memberId(), dto.groupId()); return groupCapsuleQueryRepository.findGroupCapsuleSlice(dto); } @@ -144,10 +154,7 @@ public List findGroupMemberCapsuleOpenStatus( final Long capsuleId, final Long groupId ) { - boolean isGroupMember = memberGroupRepository.existMemberGroupByMemberIdAndGroupId(memberId, groupId); - if (!isGroupMember) { - throw new NoGroupAuthorityException(); - } + checkGroupAuthority(memberId, groupId); return groupCapsuleOpenQueryRepository.findGroupMemberCapsuleOpenStatus(capsuleId, groupId); } From aeb7462d5dd46696d3bf219a61f589afe0eca320 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Fri, 14 Jun 2024 21:44:25 +0900 Subject: [PATCH 4/9] =?UTF-8?q?feat=20:=20=EA=B7=B8=EB=A3=B9=20=EC=BA=A1?= =?UTF-8?q?=EC=8A=90=20=EC=9A=94=EC=95=BD=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 서비스 로직 수정(그룹원 조회 + 캡슐 조회) - 쿼리 수정 --- .../api/GroupCapsuleApiController.java | 6 +- .../dto/CombinedGroupCapsuleSummaryDto.java | 81 +++++++++++++++++ .../data/dto/GroupCapsuleMemberDto.java | 5 +- .../data/dto/GroupCapsuleSummaryDto.java | 35 +------- .../response/GroupCapsuleMemberResponse.java | 3 - .../response/GroupCapsuleSummaryResponse.java | 13 +-- .../GroupCapsuleQueryRepository.java | 89 ++++--------------- .../service/GroupCapsuleService.java | 42 ++++++--- .../MemberGroupQueryRepository.java | 3 + .../MemberGroupQueryRepositoryImpl.java | 25 ++++++ 10 files changed, 173 insertions(+), 129 deletions(-) create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApiController.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApiController.java index 385ea4d5a..c739ffd70 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApiController.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/api/GroupCapsuleApiController.java @@ -15,10 +15,10 @@ import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import site.timecapsulearchive.core.domain.capsule.data.dto.CapsuleBasicInfoDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.CombinedGroupCapsuleSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleOpenStateDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleCreateRequest; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleUpdateRequest; @@ -98,7 +98,7 @@ public ResponseEntity> getGroupCapsuleSumma @RequestParam("group_id") Long groupId, @PathVariable("capsule_id") Long capsuleId ) { - final GroupCapsuleSummaryDto summaryDto = groupCapsuleService.findGroupCapsuleSummary( + CombinedGroupCapsuleSummaryDto groupCapsuleSummary = groupCapsuleService.findGroupCapsuleSummary( memberId, groupId, capsuleId @@ -108,7 +108,7 @@ public ResponseEntity> getGroupCapsuleSumma ApiSpec.success( SuccessCode.SUCCESS, GroupCapsuleSummaryResponse.createOf( - summaryDto, + groupCapsuleSummary, s3PreSignedUrlManager::getS3PreSignedUrlForGet, geoTransformManager::changePoint3857To4326 ) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java new file mode 100644 index 000000000..2c6beb628 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java @@ -0,0 +1,81 @@ +package site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto; + +import java.time.ZonedDateTime; +import java.util.List; +import java.util.function.UnaryOperator; +import org.locationtech.jts.geom.Point; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleMemberResponse; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleSummaryResponse; + +public record CombinedGroupCapsuleSummaryDto( + Long groupId, + String groupName, + String groupProfileUrl, + String creatorNickname, + String creatorProfileUrl, + String skinUrl, + String title, + ZonedDateTime dueDate, + Point point, + String address, + String roadName, + Boolean isCapsuleOpened, + ZonedDateTime createdAt, + Boolean isRequestMemberCapsuleOpen, + List groupMembers +) { + + public static CombinedGroupCapsuleSummaryDto create( + final GroupCapsuleSummaryDto groupCapsuleSummaryDto, + final List groupCapsuleMemberSummaryDtos, + final Boolean isRequestMemberCapsuleOpen + ) { + return new CombinedGroupCapsuleSummaryDto( + groupCapsuleSummaryDto.groupId(), + groupCapsuleSummaryDto.groupName(), + groupCapsuleSummaryDto.groupProfileUrl(), + groupCapsuleSummaryDto.creatorNickname(), + groupCapsuleSummaryDto.creatorProfileUrl(), + groupCapsuleSummaryDto.skinUrl(), + groupCapsuleSummaryDto.title(), + groupCapsuleSummaryDto.dueDate(), + groupCapsuleSummaryDto.point(), + groupCapsuleSummaryDto.address(), + groupCapsuleSummaryDto.roadName(), + groupCapsuleSummaryDto.isOpened(), + groupCapsuleSummaryDto.createdAt(), + isRequestMemberCapsuleOpen, + groupCapsuleMemberSummaryDtos + ); + } + + public GroupCapsuleSummaryResponse toResponse( + final UnaryOperator preSignUrlFunction, + final UnaryOperator changePointFunction + ) { + final Point changePoint = changePointFunction.apply(point); + + final List groupMembers = this.groupMembers.stream() + .map(GroupCapsuleMemberDto::toResponse) + .toList(); + + return GroupCapsuleSummaryResponse.builder() + .groupId(groupId) + .groupMembers(groupMembers) + .groupName(groupName) + .groupProfileUrl(preSignUrlFunction.apply(groupProfileUrl)) + .creatorNickname(creatorNickname) + .creatorProfileUrl(creatorProfileUrl) + .skinUrl(preSignUrlFunction.apply(skinUrl)) + .title(title) + .dueDate(dueDate) + .latitude(changePoint.getX()) + .longitude(changePoint.getY()) + .address(address) + .roadName(roadName) + .isCapsuleOpened(isCapsuleOpened) + .isRequestMemberCapsuleOpened(isRequestMemberCapsuleOpen) + .createdAt(createdAt) + .build(); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java index ebe60aaad..15f09a1f8 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java @@ -3,15 +3,14 @@ import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleMemberResponse; public record GroupCapsuleMemberDto( + Long id, String nickname, String profileUrl, - Boolean isRequestMember, Boolean isGroupOwner, Boolean isOpened ) { public GroupCapsuleMemberResponse toResponse() { - return new GroupCapsuleMemberResponse(nickname, profileUrl, isOpened, isGroupOwner, - isRequestMember); + return new GroupCapsuleMemberResponse(nickname, profileUrl, isGroupOwner, isOpened); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java index 3cdaa57ed..dc1d2244b 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java @@ -1,11 +1,7 @@ package site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto; import java.time.ZonedDateTime; -import java.util.List; -import java.util.function.UnaryOperator; import org.locationtech.jts.geom.Point; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleMemberResponse; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleSummaryResponse; public record GroupCapsuleSummaryDto( Long groupId, @@ -20,36 +16,7 @@ public record GroupCapsuleSummaryDto( String address, String roadName, Boolean isOpened, - ZonedDateTime createdAt, - List groupMembers + ZonedDateTime createdAt ) { - public GroupCapsuleSummaryResponse toResponse( - final UnaryOperator preSignUrlFunction, - final UnaryOperator changePointFunction - ) { - final Point changePoint = changePointFunction.apply(point); - - final List groupMembersResponse = groupMembers.stream() - .map(GroupCapsuleMemberDto::toResponse) - .toList(); - - return GroupCapsuleSummaryResponse.builder() - .groupId(groupId) - .groupMembers(groupMembersResponse) - .groupName(groupName) - .groupProfileUrl(preSignUrlFunction.apply(groupProfileUrl)) - .creatorNickname(creatorNickname) - .creatorProfileUrl(creatorProfileUrl) - .skinUrl(preSignUrlFunction.apply(skinUrl)) - .title(title) - .dueDate(dueDate) - .latitude(changePoint.getX()) - .longitude(changePoint.getY()) - .address(address) - .roadName(roadName) - .isOpened(isOpened) - .createdAt(createdAt) - .build(); - } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java index 9719cb281..2058450f1 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java @@ -11,9 +11,6 @@ public record GroupCapsuleMemberResponse( @Schema(description = "프로필 url") String profileUrl, - @Schema(description = "현재 요청한 사용자 여부") - Boolean isRequestMember, - @Schema(description = "그룹장 여부") Boolean isGroupOwner, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java index ecc639e68..aea479e14 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java @@ -6,7 +6,7 @@ import java.util.function.UnaryOperator; import lombok.Builder; import org.locationtech.jts.geom.Point; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.CombinedGroupCapsuleSummaryDto; import site.timecapsulearchive.core.global.common.response.ResponseMappingConstant; @Schema(description = "캡슐 요약 정보") @@ -52,8 +52,11 @@ public record GroupCapsuleSummaryResponse( @Schema(description = "캡슐 생성 도로 이름") String roadName, - @Schema(description = "개봉 여부") - Boolean isOpened, + @Schema(description = "캡슐 개봉 여부") + Boolean isCapsuleOpened, + + @Schema(description = "현재 사용자 캡슐 개봉 여부") + Boolean isRequestMemberCapsuleOpened, @Schema(description = "캡슐 생성 일") ZonedDateTime createdAt @@ -68,10 +71,10 @@ public record GroupCapsuleSummaryResponse( } public static GroupCapsuleSummaryResponse createOf( - final GroupCapsuleSummaryDto summaryDto, + final CombinedGroupCapsuleSummaryDto groupCapsuleSummary, final UnaryOperator preSignUrlFunction, final UnaryOperator changePointFunction ) { - return summaryDto.toResponse(preSignUrlFunction, changePointFunction); + return groupCapsuleSummary.toResponse(preSignUrlFunction, changePointFunction); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java index 3dc96e8d6..595794f1c 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java @@ -9,14 +9,10 @@ import static site.timecapsulearchive.core.domain.capsuleskin.entity.QCapsuleSkin.capsuleSkin; import static site.timecapsulearchive.core.domain.group.entity.QGroup.group; import static site.timecapsulearchive.core.domain.member.entity.QMember.member; -import static site.timecapsulearchive.core.domain.member_group.entity.QMemberGroup.memberGroup; -import com.querydsl.core.types.Expression; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.core.types.dsl.CaseBuilder; import com.querydsl.core.types.dsl.Expressions; -import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.core.types.dsl.StringExpression; import com.querydsl.jpa.impl.JPAQueryFactory; import java.time.ZonedDateTime; @@ -29,7 +25,6 @@ import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType; import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleDetailDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; @@ -96,87 +91,41 @@ private StringExpression groupConcatDistinct(final StringExpression expression) } public Optional findGroupCapsuleSummaryDtoByCapsuleId( - final Long memberId, final Long groupId, final Long capsuleId ) { - final QMember owner = new QMember("owner"); - final QMember groupMember = new QMember("groupMember"); - return Optional.ofNullable( jpaQueryFactory .select( - groupCapsuleOpen.group.id, - group.groupName, - group.groupProfileUrl, - owner.nickname, - owner.profileUrl, - capsuleSkin.imageUrl, - capsule.title, - capsule.dueDate, - capsule.point, - capsule.address.fullRoadAddressName, - capsule.address.roadName, - capsule.isOpened, - capsule.createdAt, - groupMember.nickname, - groupMember.profileUrl, - groupMember.id, - memberGroup.isOwner, - groupCapsuleOpen.isOpened + Projections.constructor( + GroupCapsuleSummaryDto.class, + group.id, + group.groupName, + group.groupProfileUrl, + member.nickname, + member.profileUrl, + capsuleSkin.imageUrl, + capsule.title, + capsule.dueDate, + capsule.point, + capsule.address.fullRoadAddressName, + capsule.address.roadName, + capsule.isOpened, + capsule.createdAt + ) ) .from(capsule) - .join(owner).on(owner.id.eq(capsule.member.id)) + .join(capsule.member, member) .join(capsule.capsuleSkin, capsuleSkin) - .join(capsule.groupCapsuleOpens, groupCapsuleOpen) .join(capsule.group, group) - .join(groupMember).on(groupMember.id.eq(groupCapsuleOpen.member.id)) - .join(memberGroup).on(memberGroup.member.id.eq(groupMember.id)) .where(capsule.id.eq(capsuleId) - .and(memberGroup.group.id.eq(groupId)) + .and(capsule.group.id.eq(groupId)) .and(capsule.type.eq(CapsuleType.GROUP)) ) - .transform( - groupBy(capsule.id).as( - Projections.constructor( - GroupCapsuleSummaryDto.class, - groupCapsuleOpen.group.id, - group.groupName, - group.groupProfileUrl, - owner.nickname, - owner.profileUrl, - capsuleSkin.imageUrl, - capsule.title, - capsule.dueDate, - capsule.point, - capsule.address.fullRoadAddressName, - capsule.address.roadName, - capsule.isOpened, - capsule.createdAt, - list( - Projections.constructor( - GroupCapsuleMemberDto.class, - groupMember.nickname, - groupMember.profileUrl, - isRequestMemberCase(groupMember, memberId), - memberGroup.isOwner, - groupCapsuleOpen.isOpened - ) - ) - ) - ) - ) - .get(capsuleId) + .fetchOne() ); } - private Expression isRequestMemberCase(QMember groupMember, Long memberId) { - return new CaseBuilder() - .when(groupMember.id.eq(memberId)) - .then(Boolean.TRUE) - .otherwise(Boolean.FALSE); - } - public Slice findMyGroupCapsuleSlice( final Long memberId, final int size, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java index 69f12f3e5..f4b765b52 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java @@ -13,8 +13,10 @@ import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType; import site.timecapsulearchive.core.domain.capsule.exception.CapsuleNotFondException; import site.timecapsulearchive.core.domain.capsule.generic_capsule.repository.capsule.CapsuleRepository; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.CombinedGroupCapsuleSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleCreateRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleOpenStateDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; @@ -76,24 +78,34 @@ private boolean capsuleNotOpened(final GroupCapsuleDetailDto detailDto) { .isAfter(ZonedDateTime.now(ZoneOffset.UTC)); } - public GroupCapsuleSummaryDto findGroupCapsuleSummary( + /** + * 그룹 캡슐의 요약 정보를 조회한다. + *
+ * @param memberId 사용자 아이디 + * @param groupId 캡슐이 만들어진 그룹 아이디 + * @param capsuleId 조회할 캡슐 아이디 + * @return 그룹 캡슐의 요약 정보(캡슐, 그룹원) + * @throws NoGroupAuthorityException 그룹에 대한 권한이 존재하지 않으면 예외가 발생한다. + */ + public CombinedGroupCapsuleSummaryDto findGroupCapsuleSummary( final Long memberId, final Long groupId, final Long capsuleId ) { - checkGroupAuthority(memberId, groupId); + List groupCapsuleMembers = memberGroupRepository.findGroupCapsuleMembers( + groupId, capsuleId); - return groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(memberId, groupId, - capsuleId) + GroupCapsuleMemberDto requestMember = groupCapsuleMembers.stream() + .filter(dto -> memberId.equals(dto.id())) + .findAny() + .orElseThrow(NoGroupAuthorityException::new); + + GroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId( + groupId, capsuleId) .orElseThrow(CapsuleNotFondException::new); - } - private void checkGroupAuthority(Long memberId, Long groupId) { - boolean isGroupMember = memberGroupRepository.existMemberGroupByMemberIdAndGroupId(memberId, - groupId); - if (!isGroupMember) { - throw new NoGroupAuthorityException(); - } + return CombinedGroupCapsuleSummaryDto.create(groupCapsuleSummaryDto, groupCapsuleMembers, + requestMember.isOpened()); } /** @@ -149,6 +161,14 @@ public Slice findGroupCapsuleSlice(final GroupCapsuleSliceR return groupCapsuleQueryRepository.findGroupCapsuleSlice(dto); } + private void checkGroupAuthority(Long memberId, Long groupId) { + boolean isGroupMember = memberGroupRepository.existMemberGroupByMemberIdAndGroupId(memberId, + groupId); + if (!isGroupMember) { + throw new NoGroupAuthorityException(); + } + } + public List findGroupMemberCapsuleOpenStatus( final Long memberId, final Long capsuleId, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java index c8aebdf57..9274389e4 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.Optional; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberDto; import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberDto; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupOwnerSummaryDto; @@ -22,4 +23,6 @@ public interface MemberGroupQueryRepository { List findGroupMemberIdsByGroupId(final Long groupId); boolean existMemberGroupByMemberIdAndGroupId(Long memberId, Long groupId); + + List findGroupCapsuleMembers(Long groupId, Long capsuleId); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java index 51fec1240..fef2e8f22 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java @@ -1,5 +1,6 @@ package site.timecapsulearchive.core.domain.member_group.repository.member_group_repository; +import static site.timecapsulearchive.core.domain.capsule.entity.QGroupCapsuleOpen.groupCapsuleOpen; import static site.timecapsulearchive.core.domain.group.entity.QGroup.group; import static site.timecapsulearchive.core.domain.member.entity.QMember.member; import static site.timecapsulearchive.core.domain.member_group.entity.QMemberGroup.memberGroup; @@ -10,6 +11,7 @@ import java.util.Optional; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Repository; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberDto; import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberDto; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupOwnerSummaryDto; @@ -121,4 +123,27 @@ public boolean existMemberGroupByMemberIdAndGroupId(Long memberId, Long groupId) return count != null; } + + @Override + public List findGroupCapsuleMembers( + final Long groupId, + final Long capsuleId + ) { + return jpaQueryFactory + .select( + Projections.constructor( + GroupCapsuleMemberDto.class, + member.id, + member.nickname, + member.profileUrl, + memberGroup.isOwner, + groupCapsuleOpen.isOpened + ) + ) + .from(memberGroup) + .join(memberGroup.member, member) + .join(groupCapsuleOpen).on(memberGroup.member.id.eq(groupCapsuleOpen.member.id)) + .where(memberGroup.group.id.eq(groupId).and(groupCapsuleOpen.capsule.id.eq(capsuleId))) + .fetch(); + } } From 5fb893a0ee51fdba4defca62c560fd854734ec07 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Fri, 14 Jun 2024 22:51:55 +0900 Subject: [PATCH 5/9] =?UTF-8?q?test=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 그룹 테스트 분리된 부분 통합 - 그룹 캡슐 요약 조회 테스트 수정 및 추가 --- .../dto/GroupCapsuleMemberDtoFixture.java | 30 ++++ .../dto/GroupCapsuleSummaryDtoFixture.java | 30 ++++ .../GroupCapsuleQueryRepositoryTest.java | 38 ++--- .../service/GroupCapsuleServiceTest.java | 64 +++++++- ...est.java => GroupQueryRepositoryTest.java} | 119 ++++++++++++-- .../MemberGroupQueryRepositoryTest.java | 147 ------------------ .../MemberGroupQueryRepositoryImplTest.java | 111 +++++++++++++ 7 files changed, 345 insertions(+), 194 deletions(-) create mode 100644 backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleMemberDtoFixture.java create mode 100644 backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleSummaryDtoFixture.java rename backend/core/src/test/java/site/timecapsulearchive/core/domain/group/repository/{GroupQueryRepositoryImplTest.java => GroupQueryRepositoryTest.java} (59%) delete mode 100644 backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java create mode 100644 backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImplTest.java diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleMemberDtoFixture.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleMemberDtoFixture.java new file mode 100644 index 000000000..4907f3fbb --- /dev/null +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleMemberDtoFixture.java @@ -0,0 +1,30 @@ +package site.timecapsulearchive.core.common.fixture.dto; + +import java.util.ArrayList; +import java.util.List; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberDto; + +public class GroupCapsuleMemberDtoFixture { + + /** + * 그룹 캡슐에 대한 그룹원 DTO Fixture를 만든다. + *
+ * 맨 처음 사용자(dataPrefix)가 그룹장으로 설정된다. + *
+ * 그룹 캡슐 개봉 상태는 전부 닫힌 상태이다. + * @param dataPrefix 데이터에 붙여지는 prefix + * @param size dto 크기 + * @return 그룹 캡슐에 대한 그룹원 목록 + */ + public static List members(int dataPrefix, int size) { + List result = new ArrayList<>(); + for (int count = dataPrefix; count < dataPrefix + size; count++) { + boolean isOwner = count == dataPrefix; + + result.add(new GroupCapsuleMemberDto((long) count, count + "nickname", + count + "profileUrl", isOwner, false)); + } + + return result; + } +} diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleSummaryDtoFixture.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleSummaryDtoFixture.java new file mode 100644 index 000000000..5bc0b1ec0 --- /dev/null +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleSummaryDtoFixture.java @@ -0,0 +1,30 @@ +package site.timecapsulearchive.core.common.fixture.dto; + +import java.time.ZonedDateTime; +import site.timecapsulearchive.core.common.dependency.UnitTestDependency; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSummaryDto; + +public class GroupCapsuleSummaryDtoFixture { + + private static final double TEST_LATITUDE = 37.078; + private static final double TEST_LONGITUDE = 127.423; + + public static GroupCapsuleSummaryDto groupCapsule(Long groupId) { + return new GroupCapsuleSummaryDto( + groupId, + "test-group", + "test-group-profile.com", + "test-creator", + "test-creator-profile.com", + "test-capsule-skin.com", + "test-capsule-title", + ZonedDateTime.now(), + UnitTestDependency.geoTransformManager() + .changePoint4326To3857(TEST_LATITUDE, TEST_LONGITUDE), + "test-address", + "test-roadName", + false, + ZonedDateTime.now() + ); + } +} diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepositoryTest.java index 4cf4ec742..bf0e14b4a 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepositoryTest.java @@ -54,7 +54,7 @@ class GroupCapsuleQueryRepositoryTest extends RepositoryTest { @BeforeEach @Transactional void setup(@Autowired EntityManager entityManager) { - // 그룹원 + // 그룹장 & 그룹원 List groupMember = MemberFixture.members(1, 5); groupMember.forEach(entityManager::persist); Member owner = groupMember.get(0); @@ -74,8 +74,9 @@ void setup(@Autowired EntityManager entityManager) { memberGroups.forEach(entityManager::persist); //그룹 캡슐 - List capsules = CapsuleFixture.groupCapsules(owner, capsuleSkin, group, MAX_COUNT); - for (Capsule c : capsules) { + List groupCapsules = CapsuleFixture.groupCapsules(owner, capsuleSkin, group, + MAX_COUNT); + for (Capsule c : groupCapsules) { entityManager.persist(c); List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens( @@ -84,8 +85,8 @@ void setup(@Autowired EntityManager entityManager) { c, groupMember); groupCapsuleOpens.forEach(entityManager::persist); } - capsule = capsules.get(0); - lastCapsuleId = capsules.get(capsules.size() - 1).getId(); + capsule = groupCapsules.get(0); + lastCapsuleId = groupCapsules.get(groupCapsules.size() - 1).getId(); } @Test @@ -144,40 +145,19 @@ void setup(@Autowired EntityManager entityManager) { // given //when GroupCapsuleSummaryDto capsuleSummaryDto = groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId( - capsule.getId()).orElseThrow(); + groupId, capsule.getId()).orElseThrow(); //then assertSoftly( softly -> { softly.assertThat(capsuleSummaryDto).isNotNull(); + softly.assertThat(capsuleSummaryDto.isOpened()).isFalse(); softly.assertThat(capsuleSummaryDto.title()).isEqualTo(capsule.getTitle()); softly.assertThat(capsuleSummaryDto.point()).isEqualTo(capsule.getPoint()); } ); } - @Test - void 그룹캡슐_아이디로_그룹_캡슐의_요약_조회_하면_그룹원_정보를_조회할_수_있다() { - // given - //when - GroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId( - capsule.getId()).orElseThrow(); - - //then - assertSoftly( - softly -> { - softly.assertThat(groupCapsuleSummaryDto.groupMembers()).isNotEmpty(); - softly.assertThat(groupCapsuleSummaryDto.groupMembers()) - .allMatch(dto -> dto.id() != null); - softly.assertThat(groupCapsuleSummaryDto.groupMembers()) - .allMatch(dto -> !dto.isOpened()); - softly.assertThat(groupCapsuleSummaryDto.groupMembers()) - .allMatch(dto -> !dto.profileUrl().isEmpty()); - softly.assertThat(groupCapsuleSummaryDto.groupMembers()) - .allMatch(dto -> !dto.nickname().isEmpty()); - }); - } - @Test void 그룹캡슐_아이디가_아니면_그룹_캡슐의_요약_내용을_조회할_수_없다() { //given @@ -185,7 +165,7 @@ void setup(@Autowired EntityManager entityManager) { //when Optional detailDto = groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId( - notCapsuleId); + notCapsuleId, groupId); //then assertThat(detailDto).isEmpty(); } diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java index f3148906b..ce0d0cbf2 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java @@ -19,6 +19,8 @@ import site.timecapsulearchive.core.common.fixture.domain.MemberFixture; import site.timecapsulearchive.core.common.fixture.dto.CapsuleBasicInfoDtoFixture; import site.timecapsulearchive.core.common.fixture.dto.CapsuleDtoFixture; +import site.timecapsulearchive.core.common.fixture.dto.GroupCapsuleMemberDtoFixture; +import site.timecapsulearchive.core.common.fixture.dto.GroupCapsuleSummaryDtoFixture; import site.timecapsulearchive.core.common.fixture.dto.GroupMemberCapsuleOpenStatusDtoFixture; import site.timecapsulearchive.core.domain.capsule.data.dto.CapsuleBasicInfoDto; import site.timecapsulearchive.core.domain.capsule.entity.Capsule; @@ -27,13 +29,14 @@ import site.timecapsulearchive.core.domain.capsule.generic_capsule.data.dto.CapsuleDetailDto; import site.timecapsulearchive.core.domain.capsule.generic_capsule.repository.capsule.CapsuleRepository; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.CapsuleOpenStatus; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.CombinedGroupCapsuleSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleDetailDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberSummaryDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleOpenStateDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleOpenQueryRepository; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleSliceRequestDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleQueryRepository; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberSummaryDto; import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; @@ -380,7 +383,7 @@ class GroupCapsuleServiceTest { } @Test - void 그룹원이_아닌_사용자가_그룹_캡슐_개봉_상태를_조회하면_오류가_발생한다() throws Exception { + void 그룹원이_아닌_사용자가_그룹_캡슐_개봉_상태를_조회하면_오류가_발생한다() { //given Long groupId = 1L; @@ -394,7 +397,7 @@ class GroupCapsuleServiceTest { } @Test - void 그룹원이_그룹_캡슐_개봉_상태를_조회하면_그룹_캡슐_개봉_상태를_조회할_수_있다() throws Exception { + void 그룹원이_그룹_캡슐_개봉_상태를_조회하면_그룹_캡슐_개봉_상태를_조회할_수_있다() { //given Long groupId = 1L; int size = 20; @@ -451,4 +454,57 @@ class GroupCapsuleServiceTest { //then assertThat(groupCapsuleSlice.hasContent()).isTrue(); } + + @Test + void 그룹원이_아닌_경우_그룹_캡슐_요약_조회_시_예외가_발생한다() { + //given + Long groupId = 1L; + Long notGroupMemberId = 999L; + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10)); + + //when + //then + assertThatThrownBy( + () -> groupCapsuleService.findGroupCapsuleSummary(notGroupMemberId, groupId, capsuleId)) + .isInstanceOf(NoGroupAuthorityException.class) + .hasMessageContaining(ErrorCode.NO_GROUP_AUTHORITY_ERROR.getMessage()); + } + + @Test + void 그룹원이_없는_그룹_캡슐을_요약_조회_시_예외가_발생한다() { + //given + Long groupId = 1L; + + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10)); + given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) + .willReturn(Optional.empty()); + + //when + //then + assertThatThrownBy( + () -> groupCapsuleService.findGroupCapsuleSummary(memberId, groupId, capsuleId)) + .isInstanceOf(CapsuleNotFondException.class) + .hasMessageContaining(ErrorCode.CAPSULE_NOT_FOUND_ERROR.getMessage()); + } + + @Test + void 그룹원이_그룹_캡슐을_요약_조회_시_그룹_캡슐_요약_조회를_볼_수_있다() { + //given + Long groupId = 1L; + + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10)); + given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) + .willReturn(Optional.of( + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + + //when + CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( + memberId, groupId, capsuleId);; + + //then + assertThat(groupCapsuleSummaryDto).isNotNull(); + } } diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/repository/GroupQueryRepositoryImplTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/repository/GroupQueryRepositoryTest.java similarity index 59% rename from backend/core/src/test/java/site/timecapsulearchive/core/domain/group/repository/GroupQueryRepositoryImplTest.java rename to backend/core/src/test/java/site/timecapsulearchive/core/domain/group/repository/GroupQueryRepositoryTest.java index 4909a0018..261ce6df8 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/repository/GroupQueryRepositoryImplTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/repository/GroupQueryRepositoryTest.java @@ -1,15 +1,21 @@ package site.timecapsulearchive.core.domain.group.repository; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.SoftAssertions.assertSoftly; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; +import java.time.ZonedDateTime; +import java.util.ArrayList; import java.util.List; import java.util.Optional; import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Slice; import org.springframework.test.context.TestConstructor; import org.springframework.test.context.TestConstructor.AutowireMode; import org.springframework.transaction.annotation.Transactional; @@ -19,45 +25,130 @@ import site.timecapsulearchive.core.common.fixture.domain.MemberGroupFixture; import site.timecapsulearchive.core.domain.group.data.dto.GroupDetailDto; import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberDto; +import site.timecapsulearchive.core.domain.group.data.dto.GroupSummaryDto; import site.timecapsulearchive.core.domain.group.entity.Group; import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; @TestConstructor(autowireMode = AutowireMode.ALL) -class GroupQueryRepositoryImplTest extends RepositoryTest { +class GroupQueryRepositoryTest extends RepositoryTest { + + private final static int GROUP_COUNT = 20; private final GroupQueryRepository groupQueryRepository; + private Long memberIdWithNoGroup; private Long groupId; private Long ownerId; private Long groupMemberId; - GroupQueryRepositoryImplTest(JPAQueryFactory jpaQueryFactory) { + GroupQueryRepositoryTest(JPAQueryFactory jpaQueryFactory) { this.groupQueryRepository = new GroupQueryRepositoryImpl(jpaQueryFactory); } @Transactional @BeforeEach void setup(@Autowired EntityManager entityManager) { - Group group = GroupFixture.group(); - entityManager.persist(group); - groupId = group.getId(); - - Member member = MemberFixture.member(1); + //사용자 + Member member = MemberFixture.member(0); entityManager.persist(member); ownerId = member.getId(); - MemberGroup memberGroup = MemberGroupFixture.groupOwner(member, group); - entityManager.persist(memberGroup); + //그룹이 없는 사용자 + Member memberNotInGroup = MemberFixture.member(1); + entityManager.persist(memberNotInGroup); + memberIdWithNoGroup = memberNotInGroup.getId(); - List members = MemberFixture.members(2, 10); - for (Member m : members) { - entityManager.persist(m); + //그룹 + List groups = new ArrayList<>(); + for (int count = 0; count < GROUP_COUNT; count++) { + Group group = GroupFixture.group(); + entityManager.persist(group); + groups.add(group); + } + groupId = groups.get(0).getId(); - MemberGroup mg = MemberGroupFixture.memberGroup(m, group, Boolean.FALSE); - entityManager.persist(mg); + //그룹에 사용자를 그룹장으로 설정 + for (int count = 0; count < GROUP_COUNT; count++) { + MemberGroup memberGroup = MemberGroupFixture.memberGroup(member, groups.get(count), + Boolean.TRUE); + entityManager.persist(memberGroup); } + + //그룹원들 + List members = MemberFixture.members(4, 2); + members.forEach(entityManager::persist); groupMemberId = members.get(0).getId(); + + //그룹원들 설정 + List memberGroups = MemberGroupFixture.memberGroups(members, groups.get(0)); + memberGroups.forEach(entityManager::persist); + } + + @ParameterizedTest + @ValueSource(ints = {1, 5, 15, 20}) + void 사용자와_개수_마지막_데이터_생성_시간으로_그룹_목록을_조회하면_개수만큼_그룹이_반환된다(int size) { + //given + ZonedDateTime now = ZonedDateTime.now().plusDays(3); + + //when + Slice groupsSlice = groupQueryRepository.findGroupSummaries(ownerId, + size, now); + + //then + assertThat(groupsSlice.getNumberOfElements()).isEqualTo(size); + } + + @Test + void 사용자와_개수_마지막_데이터_생성_시간으로_그룹_목록을_조회하면_개수만큼_그룹의_내용들이_반환된다() { + //given + int size = 20; + ZonedDateTime now = ZonedDateTime.now().plusDays(3); + + //when + List groupsSlice = groupQueryRepository.findGroupSummaries(ownerId, + size, now).getContent(); + + //then + assertSoftly(softly -> { + softly.assertThat(groupsSlice).allMatch(dto -> dto.id() != null); + softly.assertThat(groupsSlice) + .allMatch(dto -> !dto.groupName().isBlank()); + softly.assertThat(groupsSlice) + .allMatch(dto -> !dto.groupProfileUrl().isBlank()); + softly.assertThat(groupsSlice).allMatch(dto -> dto.isOwner() != null); + }); + } + + @Test + void 그룹이_없는_사용자로_그룹_목록을_조회하면_빈_그룹_목록이_반환된다() { + //given + int size = 20; + ZonedDateTime now = ZonedDateTime.now().plusDays(3); + + //when + List groupsSlice = groupQueryRepository.findGroupSummaries( + memberIdWithNoGroup, + size, + now) + .getContent(); + + //then + assertThat(groupsSlice.isEmpty()).isTrue(); + } + + @Test + void 사용자와_범위에_없는_마지막_데이터_생성_시간으로_그룹_목록을_조회하면_빈_그룹_목록이_반환된다() { + //given + int size = 20; + ZonedDateTime now = ZonedDateTime.now().minusDays(5); + + //when + List groupsSlice = groupQueryRepository.findGroupSummaries(ownerId, + size, now).getContent(); + + //then + assertThat(groupsSlice.isEmpty()).isTrue(); } @Test diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java deleted file mode 100644 index 04e9cfb94..000000000 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java +++ /dev/null @@ -1,147 +0,0 @@ -package site.timecapsulearchive.core.domain.member_group.repository; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.SoftAssertions.assertSoftly; - -import com.querydsl.jpa.impl.JPAQueryFactory; -import jakarta.persistence.EntityManager; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.List; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ValueSource; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.domain.Slice; -import org.springframework.test.context.TestConstructor; -import org.springframework.test.context.TestConstructor.AutowireMode; -import org.springframework.transaction.annotation.Transactional; -import site.timecapsulearchive.core.common.RepositoryTest; -import site.timecapsulearchive.core.common.fixture.domain.GroupFixture; -import site.timecapsulearchive.core.common.fixture.domain.MemberFixture; -import site.timecapsulearchive.core.common.fixture.domain.MemberGroupFixture; -import site.timecapsulearchive.core.domain.group.data.dto.GroupSummaryDto; -import site.timecapsulearchive.core.domain.group.entity.Group; -import site.timecapsulearchive.core.domain.group.repository.GroupQueryRepository; -import site.timecapsulearchive.core.domain.group.repository.GroupQueryRepositoryImpl; -import site.timecapsulearchive.core.domain.member.entity.Member; -import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; - -@TestConstructor(autowireMode = AutowireMode.ALL) -class MemberGroupQueryRepositoryTest extends RepositoryTest { - - private final static int GROUP_COUNT = 20; - - private final GroupQueryRepository groupQueryRepository; - - private Long memberId; - private Long memberIdWithNoGroup; - - MemberGroupQueryRepositoryTest(JPAQueryFactory jpaQueryFactory) { - this.groupQueryRepository = new GroupQueryRepositoryImpl(jpaQueryFactory); - } - - @Transactional - @BeforeEach - void setup(@Autowired EntityManager entityManager) { - //사용자 - Member member = MemberFixture.member(0); - entityManager.persist(member); - memberId = member.getId(); - - //그룹이 없는 사용자 - Member memberNotInGroup = MemberFixture.member(1); - entityManager.persist(memberNotInGroup); - memberIdWithNoGroup = memberNotInGroup.getId(); - - //그룹 - List groups = new ArrayList<>(); - for (int count = 0; count < GROUP_COUNT; count++) { - Group group = GroupFixture.group(); - entityManager.persist(group); - groups.add(group); - } - - //그룹에 사용자를 그룹장으로 설정 - for (int count = 0; count < GROUP_COUNT; count++) { - MemberGroup memberGroup = MemberGroupFixture.memberGroup(member, groups.get(count), - Boolean.TRUE); - entityManager.persist(memberGroup); - } - - //그룹원들 - List members = MemberFixture.members(4, 2); - members.forEach(entityManager::persist); - - //그룹원들 설정 - List memberGroups = MemberGroupFixture.memberGroups(members, groups.get(0)); - memberGroups.forEach(entityManager::persist); - } - - @ParameterizedTest - @ValueSource(ints = {1, 5, 15, 20}) - void 사용자와_개수_마지막_데이터_생성_시간으로_그룹_목록을_조회하면_개수만큼_그룹이_반환된다(int size) { - //given - ZonedDateTime now = ZonedDateTime.now().plusDays(3); - - //when - Slice groupsSlice = groupQueryRepository.findGroupSummaries(memberId, - size, now); - - //then - assertThat(groupsSlice.getNumberOfElements()).isEqualTo(size); - } - - @Test - void 사용자와_개수_마지막_데이터_생성_시간으로_그룹_목록을_조회하면_개수만큼_그룹의_내용들이_반환된다() { - //given - int size = 20; - ZonedDateTime now = ZonedDateTime.now().plusDays(3); - - //when - List groupsSlice = groupQueryRepository.findGroupSummaries(memberId, - size, now).getContent(); - - //then - assertSoftly(softly -> { - softly.assertThat(groupsSlice).allMatch(dto -> dto.id() != null); - softly.assertThat(groupsSlice) - .allMatch(dto -> !dto.groupName().isBlank()); - softly.assertThat(groupsSlice) - .allMatch(dto -> !dto.groupProfileUrl().isBlank()); - softly.assertThat(groupsSlice).allMatch(dto -> dto.isOwner() != null); - }); - } - - @Test - void 그룹이_없는_사용자로_그룹_목록을_조회하면_빈_그룹_목록이_반환된다() { - //given - int size = 20; - ZonedDateTime now = ZonedDateTime.now().plusDays(3); - - //when - List groupsSlice = groupQueryRepository.findGroupSummaries( - memberIdWithNoGroup, - size, - now) - .getContent(); - - //then - assertThat(groupsSlice.isEmpty()).isTrue(); - } - - @Test - void 사용자와_범위에_없는_마지막_데이터_생성_시간으로_그룹_목록을_조회하면_빈_그룹_목록이_반환된다() { - //given - int size = 20; - ZonedDateTime now = ZonedDateTime.now().minusDays(5); - - //when - List groupsSlice = groupQueryRepository.findGroupSummaries(memberId, - size, now).getContent(); - - //then - assertThat(groupsSlice.isEmpty()).isTrue(); - } -} \ No newline at end of file diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImplTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImplTest.java new file mode 100644 index 000000000..8a44862ae --- /dev/null +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImplTest.java @@ -0,0 +1,111 @@ +package site.timecapsulearchive.core.domain.member_group.repository.member_group_repository; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.SoftAssertions.assertSoftly; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import java.util.List; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.TestConstructor; +import org.springframework.test.context.TestConstructor.AutowireMode; +import site.timecapsulearchive.core.common.RepositoryTest; +import site.timecapsulearchive.core.common.fixture.domain.CapsuleFixture; +import site.timecapsulearchive.core.common.fixture.domain.CapsuleSkinFixture; +import site.timecapsulearchive.core.common.fixture.domain.GroupCapsuleOpenFixture; +import site.timecapsulearchive.core.common.fixture.domain.GroupFixture; +import site.timecapsulearchive.core.common.fixture.domain.MemberFixture; +import site.timecapsulearchive.core.common.fixture.domain.MemberGroupFixture; +import site.timecapsulearchive.core.domain.capsule.entity.Capsule; +import site.timecapsulearchive.core.domain.capsule.entity.GroupCapsuleOpen; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleMemberDto; +import site.timecapsulearchive.core.domain.capsuleskin.entity.CapsuleSkin; +import site.timecapsulearchive.core.domain.group.entity.Group; +import site.timecapsulearchive.core.domain.member.entity.Member; +import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; + +@TestConstructor(autowireMode = AutowireMode.ALL) +class MemberGroupQueryRepositoryImplTest extends RepositoryTest { + + private final MemberGroupQueryRepository memberGroupQueryRepository; + + private Long capsuleId; + private Long groupId; + private Long memberId; + + MemberGroupQueryRepositoryImplTest(JPAQueryFactory jpaQueryFactory) { + this.memberGroupQueryRepository = new MemberGroupQueryRepositoryImpl(jpaQueryFactory); + } + + @BeforeEach + void setup(@Autowired EntityManager entityManager) { + //그룹 + Group group = GroupFixture.group(); + entityManager.persist(group); + groupId = group.getId(); + + //그룹장 + Member member = MemberFixture.member(0); + entityManager.persist(member); + memberId = member.getId(); + + MemberGroup owner = MemberGroupFixture.groupOwner(member, group); + entityManager.persist(owner); + + //그룹원 + List members = MemberFixture.members(1, 10); + members.forEach(entityManager::persist); + + List memberGroups = MemberGroupFixture.memberGroups(members, group); + memberGroups.forEach(entityManager::persist); + + //그룹 캡슐 스킨 + CapsuleSkin capsuleSkin = CapsuleSkinFixture.capsuleSkin(member); + entityManager.persist(capsuleSkin); + + //그룹 캡슐 + Capsule capsule = CapsuleFixture.groupCapsule(member, capsuleSkin, group); + entityManager.persist(capsule); + capsuleId = capsule.getId(); + + //그룹 캡슐 개봉 상태 + members.add(member); + List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(group, + false, capsule, members); + groupCapsuleOpens.forEach(entityManager::persist); + } + + /** + * 테스트 케이스 + */ + @Test + void 그룹원이_그룹_캡슐의_그룹원_목록을_조회하면_그룹_캡슐의_그룹원_목록이_반환된다() { + //given + //when + List groupCapsuleMembers = memberGroupQueryRepository.findGroupCapsuleMembers( + groupId, capsuleId); + + //then + assertThat(groupCapsuleMembers).isNotEmpty(); + } + + @Test + void 그룹원이_그룹_캡슐의_그룹원_목록을_조회하면_그룹_캡슐의_그룹원_목록의_필드들이_반환된다() { + //given + //when + List groupCapsuleMembers = memberGroupQueryRepository.findGroupCapsuleMembers( + groupId, capsuleId); + + //then + assertSoftly(softly -> { + softly.assertThat(groupCapsuleMembers).allMatch(member -> member.id() != null); + softly.assertThat(groupCapsuleMembers) + .allMatch(member -> member.isGroupOwner() != null); + softly.assertThat(groupCapsuleMembers).allMatch(member -> member.isOpened() != null); + softly.assertThat(groupCapsuleMembers).allMatch(member -> member.profileUrl() != null + && !member.profileUrl().isBlank()); + }); + } +} \ No newline at end of file From cab1fc8100dd6e49ddbca2cb1ad70e99a6757609 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Fri, 14 Jun 2024 23:22:22 +0900 Subject: [PATCH 6/9] =?UTF-8?q?fix=20:=20=EC=9D=91=EB=8B=B5=20=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 멤버 아이디 추가 - 요청한 사용자 그룹장 여부 추가 --- .../data/dto/CombinedGroupCapsuleSummaryDto.java | 6 +++++- .../group_capsule/data/dto/GroupCapsuleMemberDto.java | 2 +- .../data/response/GroupCapsuleMemberResponse.java | 3 +++ .../data/response/GroupCapsuleSummaryResponse.java | 3 +++ .../capsule/group_capsule/service/GroupCapsuleService.java | 2 +- 5 files changed, 13 insertions(+), 3 deletions(-) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java index 2c6beb628..90632ab87 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java @@ -22,13 +22,15 @@ public record CombinedGroupCapsuleSummaryDto( Boolean isCapsuleOpened, ZonedDateTime createdAt, Boolean isRequestMemberCapsuleOpen, + Boolean isRequestMemberGroupOwner, List groupMembers ) { public static CombinedGroupCapsuleSummaryDto create( final GroupCapsuleSummaryDto groupCapsuleSummaryDto, final List groupCapsuleMemberSummaryDtos, - final Boolean isRequestMemberCapsuleOpen + final Boolean isRequestMemberCapsuleOpen, + final Boolean isRequestMemberGroupOwner ) { return new CombinedGroupCapsuleSummaryDto( groupCapsuleSummaryDto.groupId(), @@ -45,6 +47,7 @@ public static CombinedGroupCapsuleSummaryDto create( groupCapsuleSummaryDto.isOpened(), groupCapsuleSummaryDto.createdAt(), isRequestMemberCapsuleOpen, + isRequestMemberGroupOwner, groupCapsuleMemberSummaryDtos ); } @@ -75,6 +78,7 @@ public GroupCapsuleSummaryResponse toResponse( .roadName(roadName) .isCapsuleOpened(isCapsuleOpened) .isRequestMemberCapsuleOpened(isRequestMemberCapsuleOpen) + .isRequestMemberGroupOwner(isRequestMemberGroupOwner) .createdAt(createdAt) .build(); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java index 15f09a1f8..38372a52c 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleMemberDto.java @@ -11,6 +11,6 @@ public record GroupCapsuleMemberDto( ) { public GroupCapsuleMemberResponse toResponse() { - return new GroupCapsuleMemberResponse(nickname, profileUrl, isGroupOwner, isOpened); + return new GroupCapsuleMemberResponse(id, nickname, profileUrl, isGroupOwner, isOpened); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java index 2058450f1..750feec26 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleMemberResponse.java @@ -5,6 +5,9 @@ @Schema(description = "그룹원 요약 정보") public record GroupCapsuleMemberResponse( + @Schema(description = "사용자 아이디") + Long id, + @Schema(description = "닉네임") String nickname, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java index aea479e14..517d2278e 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java @@ -58,6 +58,9 @@ public record GroupCapsuleSummaryResponse( @Schema(description = "현재 사용자 캡슐 개봉 여부") Boolean isRequestMemberCapsuleOpened, + @Schema(description = "현재 사용자 그룹장 여부") + Boolean isRequestMemberGroupOwner, + @Schema(description = "캡슐 생성 일") ZonedDateTime createdAt ) { diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java index f4b765b52..1eaa0c1f5 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java @@ -105,7 +105,7 @@ public CombinedGroupCapsuleSummaryDto findGroupCapsuleSummary( .orElseThrow(CapsuleNotFondException::new); return CombinedGroupCapsuleSummaryDto.create(groupCapsuleSummaryDto, groupCapsuleMembers, - requestMember.isOpened()); + requestMember.isOpened(), requestMember.isGroupOwner()); } /** From 8b5f85d6f71e17cd740127c2a654d84ffd7d998c Mon Sep 17 00:00:00 2001 From: hong seokho Date: Fri, 14 Jun 2024 23:22:31 +0900 Subject: [PATCH 7/9] =?UTF-8?q?test=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/GroupCapsuleMemberDtoFixture.java | 5 +- .../service/GroupCapsuleServiceTest.java | 83 ++++++++++++++++++- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleMemberDtoFixture.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleMemberDtoFixture.java index 4907f3fbb..2e903e87b 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleMemberDtoFixture.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleMemberDtoFixture.java @@ -14,15 +14,16 @@ public class GroupCapsuleMemberDtoFixture { * 그룹 캡슐 개봉 상태는 전부 닫힌 상태이다. * @param dataPrefix 데이터에 붙여지는 prefix * @param size dto 크기 + * @param isOpened 전체 개봉 여부 * @return 그룹 캡슐에 대한 그룹원 목록 */ - public static List members(int dataPrefix, int size) { + public static List members(int dataPrefix, int size, boolean isOpened) { List result = new ArrayList<>(); for (int count = dataPrefix; count < dataPrefix + size; count++) { boolean isOwner = count == dataPrefix; result.add(new GroupCapsuleMemberDto((long) count, count + "nickname", - count + "profileUrl", isOwner, false)); + count + "profileUrl", isOwner, isOpened)); } return result; diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java index ce0d0cbf2..e016fa1e8 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java @@ -461,7 +461,7 @@ class GroupCapsuleServiceTest { Long groupId = 1L; Long notGroupMemberId = 999L; given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) - .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10)); + .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10, false)); //when //then @@ -477,7 +477,7 @@ class GroupCapsuleServiceTest { Long groupId = 1L; given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) - .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10)); + .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10, false)); given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) .willReturn(Optional.empty()); @@ -495,7 +495,7 @@ class GroupCapsuleServiceTest { Long groupId = 1L; given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) - .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10)); + .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10, false)); given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) .willReturn(Optional.of( GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); @@ -507,4 +507,81 @@ class GroupCapsuleServiceTest { //then assertThat(groupCapsuleSummaryDto).isNotNull(); } + + @Test + void 그룹원이_그룹_캡슐을_요약_조회_시_그룹장_여부가_거짓이다() { + //given + Long groupId = 1L; + Long groupMemberId = 2L; + + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, false)); + given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) + .willReturn(Optional.of( + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + + //when + CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( + groupMemberId, groupId, capsuleId);; + + //then + assertThat(groupCapsuleSummaryDto.isRequestMemberGroupOwner()).isFalse(); + } + + @Test + void 그룹장이_그룹_캡슐을_요약_조회_시_그룹장_여부가_참이다() { + //given + Long groupId = 1L; + + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, false)); + given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) + .willReturn(Optional.of( + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + + //when + CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( + memberId, groupId, capsuleId);; + + //then + assertThat(groupCapsuleSummaryDto.isRequestMemberGroupOwner()).isTrue(); + } + + @Test + void 사용자가_그룹_캡슐을_요약_조회_시_그룹_캡슐을_개봉했으면_현재_사용자의_그룹_캡슐_개봉_여부는_참이다() { + //given + Long groupId = 1L; + + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, true)); + given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) + .willReturn(Optional.of( + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + + //when + CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( + memberId, groupId, capsuleId);; + + //then + assertThat(groupCapsuleSummaryDto.isRequestMemberCapsuleOpen()).isTrue(); + } + + @Test + void 사용자가_그룹_캡슐을_요약_조회_시_그룹_캡슐을_개봉하지_않았으면_현재_사용자의_그룹_캡슐_개봉_여부는_거짓이다() { + //given + Long groupId = 1L; + + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, false)); + given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) + .willReturn(Optional.of( + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + + //when + CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( + memberId, groupId, capsuleId);; + + //then + assertThat(groupCapsuleSummaryDto.isRequestMemberCapsuleOpen()).isFalse(); + } } From bc7a429a6d8c2f6c2405c59121b49e734fbb9e80 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sat, 15 Jun 2024 13:03:54 +0900 Subject: [PATCH 8/9] =?UTF-8?q?fix=20:=20=EC=88=98=EC=A0=95=20=EA=B6=8C?= =?UTF-8?q?=ED=95=9C,=20=EC=82=AD=EC=A0=9C=20=EA=B6=8C=ED=95=9C=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/dto/CombinedGroupCapsuleSummaryDto.java | 12 ++++++++---- .../data/dto/GroupCapsuleSummaryDto.java | 1 + .../data/response/GroupCapsuleSummaryResponse.java | 7 +++++-- .../repository/GroupCapsuleQueryRepository.java | 1 + .../group_capsule/service/GroupCapsuleService.java | 12 ++++++++++-- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java index 90632ab87..d19e4ec70 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/CombinedGroupCapsuleSummaryDto.java @@ -22,7 +22,8 @@ public record CombinedGroupCapsuleSummaryDto( Boolean isCapsuleOpened, ZonedDateTime createdAt, Boolean isRequestMemberCapsuleOpen, - Boolean isRequestMemberGroupOwner, + Boolean hasEditPermission, + Boolean hasDeletePermission, List groupMembers ) { @@ -30,7 +31,8 @@ public static CombinedGroupCapsuleSummaryDto create( final GroupCapsuleSummaryDto groupCapsuleSummaryDto, final List groupCapsuleMemberSummaryDtos, final Boolean isRequestMemberCapsuleOpen, - final Boolean isRequestMemberGroupOwner + final Boolean hasEditPermission, + final Boolean hasDeletePermission ) { return new CombinedGroupCapsuleSummaryDto( groupCapsuleSummaryDto.groupId(), @@ -47,7 +49,8 @@ public static CombinedGroupCapsuleSummaryDto create( groupCapsuleSummaryDto.isOpened(), groupCapsuleSummaryDto.createdAt(), isRequestMemberCapsuleOpen, - isRequestMemberGroupOwner, + hasEditPermission, + hasDeletePermission, groupCapsuleMemberSummaryDtos ); } @@ -78,7 +81,8 @@ public GroupCapsuleSummaryResponse toResponse( .roadName(roadName) .isCapsuleOpened(isCapsuleOpened) .isRequestMemberCapsuleOpened(isRequestMemberCapsuleOpen) - .isRequestMemberGroupOwner(isRequestMemberGroupOwner) + .hasEditPermission(hasEditPermission) + .hasDeletePermission(hasDeletePermission) .createdAt(createdAt) .build(); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java index dc1d2244b..ab84a0a13 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupCapsuleSummaryDto.java @@ -7,6 +7,7 @@ public record GroupCapsuleSummaryDto( Long groupId, String groupName, String groupProfileUrl, + Long creatorId, String creatorNickname, String creatorProfileUrl, String skinUrl, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java index 517d2278e..c278ba733 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupCapsuleSummaryResponse.java @@ -58,8 +58,11 @@ public record GroupCapsuleSummaryResponse( @Schema(description = "현재 사용자 캡슐 개봉 여부") Boolean isRequestMemberCapsuleOpened, - @Schema(description = "현재 사용자 그룹장 여부") - Boolean isRequestMemberGroupOwner, + @Schema(description = "캡슐 수정 권한 여부") + Boolean hasEditPermission, + + @Schema(description = "캡슐 삭제 권한 여부") + Boolean hasDeletePermission, @Schema(description = "캡슐 생성 일") ZonedDateTime createdAt diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java index 595794f1c..243c7b16e 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleQueryRepository.java @@ -102,6 +102,7 @@ public Optional findGroupCapsuleSummaryDtoByCapsuleId( group.id, group.groupName, group.groupProfileUrl, + member.id, member.nickname, member.profileUrl, capsuleSkin.imageUrl, diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java index 1eaa0c1f5..2791a84d9 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleService.java @@ -104,8 +104,16 @@ public CombinedGroupCapsuleSummaryDto findGroupCapsuleSummary( groupId, capsuleId) .orElseThrow(CapsuleNotFondException::new); - return CombinedGroupCapsuleSummaryDto.create(groupCapsuleSummaryDto, groupCapsuleMembers, - requestMember.isOpened(), requestMember.isGroupOwner()); + Boolean hasEditPermission = requestMember.id().equals(groupCapsuleSummaryDto.creatorId()); + Boolean hasDeletePermission = hasEditPermission || requestMember.isGroupOwner(); + + return CombinedGroupCapsuleSummaryDto.create( + groupCapsuleSummaryDto, + groupCapsuleMembers, + requestMember.isOpened(), + hasEditPermission, + hasDeletePermission + ); } /** From e33d2fde0713a53ff94214fa21e2d3344e8fba95 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sat, 15 Jun 2024 13:04:00 +0900 Subject: [PATCH 9/9] =?UTF-8?q?test=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/GroupCapsuleSummaryDtoFixture.java | 3 +- .../service/GroupCapsuleServiceTest.java | 57 ++++++++++++++++--- 2 files changed, 50 insertions(+), 10 deletions(-) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleSummaryDtoFixture.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleSummaryDtoFixture.java index 5bc0b1ec0..bc892c8e2 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleSummaryDtoFixture.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupCapsuleSummaryDtoFixture.java @@ -9,11 +9,12 @@ public class GroupCapsuleSummaryDtoFixture { private static final double TEST_LATITUDE = 37.078; private static final double TEST_LONGITUDE = 127.423; - public static GroupCapsuleSummaryDto groupCapsule(Long groupId) { + public static GroupCapsuleSummaryDto groupCapsule(Long groupId, Long memberId) { return new GroupCapsuleSummaryDto( groupId, "test-group", "test-group-profile.com", + memberId, "test-creator", "test-creator-profile.com", "test-capsule-skin.com", diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java index e016fa1e8..d5857926e 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleServiceTest.java @@ -498,7 +498,7 @@ class GroupCapsuleServiceTest { .willReturn(GroupCapsuleMemberDtoFixture.members(0, 10, false)); given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) .willReturn(Optional.of( - GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId, memberId))); //when CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( @@ -509,7 +509,7 @@ class GroupCapsuleServiceTest { } @Test - void 그룹원이_그룹_캡슐을_요약_조회_시_그룹장_여부가_거짓이다() { + void 그룹_캡슐을_만든_사람이_아닌_그룹원이_그룹_캡슐을_요약_조회_시_수정_권한이_없다() { //given Long groupId = 1L; Long groupMemberId = 2L; @@ -518,18 +518,57 @@ class GroupCapsuleServiceTest { .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, false)); given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) .willReturn(Optional.of( - GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId, memberId))); //when CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( groupMemberId, groupId, capsuleId);; //then - assertThat(groupCapsuleSummaryDto.isRequestMemberGroupOwner()).isFalse(); + assertThat(groupCapsuleSummaryDto.hasEditPermission()).isFalse(); } @Test - void 그룹장이_그룹_캡슐을_요약_조회_시_그룹장_여부가_참이다() { + void 그룹_캡슐을_만든_사람이_아닌_그룹원이_그룹_캡슐을_요약_조회_시_삭제_권한이_없다() { + //given + Long groupId = 1L; + Long groupMemberId = 2L; + + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, false)); + given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) + .willReturn(Optional.of( + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId, memberId))); + + //when + CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( + groupMemberId, groupId, capsuleId);; + + //then + assertThat(groupCapsuleSummaryDto.hasDeletePermission()).isFalse(); + } + + @Test + void 그룹_캡슐을_만든_사람이_그룹_캡슐을_요약_조회_시_수정_권한이_있다() { + //given + Long groupId = 1L; + + given(memberGroupRepository.findGroupCapsuleMembers(anyLong(), anyLong())) + .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, false)); + given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) + .willReturn(Optional.of( + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId, memberId))); + + //when + CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( + memberId, groupId, capsuleId);; + + //then + assertThat(groupCapsuleSummaryDto.hasEditPermission()).isTrue(); + } + + @Test + void 그룹_캡슐을_만든_사람이_그룹_캡슐을_요약_조회_시_삭제_권한이_있다() { //given Long groupId = 1L; @@ -537,14 +576,14 @@ class GroupCapsuleServiceTest { .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, false)); given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) .willReturn(Optional.of( - GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId, memberId))); //when CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( memberId, groupId, capsuleId);; //then - assertThat(groupCapsuleSummaryDto.isRequestMemberGroupOwner()).isTrue(); + assertThat(groupCapsuleSummaryDto.hasDeletePermission()).isTrue(); } @Test @@ -556,7 +595,7 @@ class GroupCapsuleServiceTest { .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, true)); given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) .willReturn(Optional.of( - GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId, memberId))); //when CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary( @@ -575,7 +614,7 @@ class GroupCapsuleServiceTest { .willReturn(GroupCapsuleMemberDtoFixture.members(1, 10, false)); given(groupCapsuleQueryRepository.findGroupCapsuleSummaryDtoByCapsuleId(groupId, capsuleId)) .willReturn(Optional.of( - GroupCapsuleSummaryDtoFixture.groupCapsule(groupId))); + GroupCapsuleSummaryDtoFixture.groupCapsule(groupId, memberId))); //when CombinedGroupCapsuleSummaryDto groupCapsuleSummaryDto = groupCapsuleService.findGroupCapsuleSummary(