From 6c3140108a52245134de9aa3c15b29fcc720e56a Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 9 Jun 2024 09:31:27 +0900 Subject: [PATCH 1/5] =?UTF-8?q?fix=20:=20=EA=B7=B8=EB=A3=B9=20=EC=BA=A1?= =?UTF-8?q?=EC=8A=90=20=EA=B0=9C=EB=B4=89=EC=97=90=20=EA=B7=B8=EB=A3=B9=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../capsule/entity/GroupCapsuleOpen.java | 16 ++--- .../facade/GroupCapsuleFacade.java | 2 +- .../GroupCapsuleOpenQueryRepository.java | 13 ++-- .../service/GroupCapsuleOpenService.java | 8 ++- .../V29__group_capsule_open_add_group.sql | 3 + .../common/fixture/domain/CapsuleFixture.java | 31 ++++---- .../domain/GroupCapsuleOpenFixture.java | 70 ++++++++++++------- .../GroupCapsuleOpenQueryRepositoryTest.java | 17 +++-- .../GroupCapsuleQueryRepositoryTest.java | 2 +- 9 files changed, 94 insertions(+), 68 deletions(-) create mode 100644 backend/core/src/main/resources/db/migration/V29__group_capsule_open_add_group.sql diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/entity/GroupCapsuleOpen.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/entity/GroupCapsuleOpen.java index 809d9dc64..1364a6fc8 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/entity/GroupCapsuleOpen.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/entity/GroupCapsuleOpen.java @@ -9,11 +9,10 @@ import jakarta.persistence.JoinColumn; import jakarta.persistence.ManyToOne; import jakarta.persistence.Table; -import java.util.Objects; import lombok.AccessLevel; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import site.timecapsulearchive.core.domain.group.entity.Group; import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.global.entity.BaseEntity; @@ -39,16 +38,9 @@ public class GroupCapsuleOpen extends BaseEntity { @JoinColumn(name = "member_id", nullable = false) private Member member; - @Builder - private GroupCapsuleOpen(Boolean isOpened, Capsule capsule, Member member) { - this.isOpened = Objects.requireNonNull(isOpened); - this.capsule = Objects.requireNonNull(capsule); - this.member = Objects.requireNonNull(member); - } - - public static GroupCapsuleOpen createOf(Member member, Capsule capsule, Boolean isOpened) { - return new GroupCapsuleOpen(isOpened, capsule, member); - } + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "group_id", nullable = false) + private Group group; public void open() { this.isOpened = Boolean.TRUE; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/facade/GroupCapsuleFacade.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/facade/GroupCapsuleFacade.java index c4e160daa..16c37f7c7 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/facade/GroupCapsuleFacade.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/facade/GroupCapsuleFacade.java @@ -56,6 +56,6 @@ public void saveGroupCapsule( final List groupMemberIds = memberGroupQueryService.findGroupMemberIds(groupId); - groupCapsuleOpenService.bulkSave(groupMemberIds, capsule); + groupCapsuleOpenService.bulkSave(groupId, groupMemberIds, capsule); } } \ No newline at end of file diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepository.java index 218d84b9b..ff92ac3ae 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepository.java @@ -18,12 +18,16 @@ public class GroupCapsuleOpenQueryRepository { private final JdbcTemplate jdbcTemplate; - public void bulkSave(final List groupMemberIds, final Capsule capsule) { + public void bulkSave( + final Long groupId, + final List groupMemberIds, + final Capsule capsule + ) { jdbcTemplate.batchUpdate( """ INSERT INTO group_capsule_open ( - group_capsule_open_id, is_opened, member_id, capsule_id, created_at, updated_at - ) values (?, ? ,? ,? ,?, ?) + group_capsule_open_id, is_opened, member_id, capsule_id, group_id, created_at, updated_at + ) values (?, ? ,? ,? ,?, ?, ?) """, new BatchPreparedStatementSetter() { @Override @@ -34,8 +38,9 @@ public void setValues(PreparedStatement ps, int i) throws SQLException { ps.setBoolean(2, isOpened); ps.setLong(3, groupMemberIds.get(i)); ps.setLong(4, capsule.getId()); - ps.setTimestamp(5, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime())); + ps.setLong(5, groupId); ps.setTimestamp(6, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime())); + ps.setTimestamp(7, Timestamp.valueOf(ZonedDateTime.now().toLocalDateTime())); } @Override diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleOpenService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleOpenService.java index 32496954d..c695e2d7e 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleOpenService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/service/GroupCapsuleOpenService.java @@ -12,7 +12,11 @@ public class GroupCapsuleOpenService { private final GroupCapsuleOpenQueryRepository repository; - public void bulkSave(final List groupMemberIds, final Capsule capsule) { - repository.bulkSave(groupMemberIds, capsule); + public void bulkSave( + final Long groupId, + final List groupMemberIds, + final Capsule capsule + ) { + repository.bulkSave(groupId, groupMemberIds, capsule); } } diff --git a/backend/core/src/main/resources/db/migration/V29__group_capsule_open_add_group.sql b/backend/core/src/main/resources/db/migration/V29__group_capsule_open_add_group.sql new file mode 100644 index 000000000..c276318fe --- /dev/null +++ b/backend/core/src/main/resources/db/migration/V29__group_capsule_open_add_group.sql @@ -0,0 +1,3 @@ +alter table group_capsule_open add column group_id BIGINT; +ALTER TABLE group_capsule_open + ADD CONSTRAINT fk_group_capsule_open_group_id FOREIGN KEY (group_id) REFERENCES `group` (group_id); \ No newline at end of file diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/domain/CapsuleFixture.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/domain/CapsuleFixture.java index c9fdb0112..79ee69326 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/domain/CapsuleFixture.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/domain/CapsuleFixture.java @@ -1,7 +1,6 @@ package site.timecapsulearchive.core.common.fixture.domain; import java.lang.reflect.Field; -import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.List; import java.util.Optional; @@ -136,8 +135,10 @@ public static Optional groupCapsuleNotAllMemberOpen( Capsule capsule = capsuleBuilder.dueDate(ZonedDateTimeSupplier.utc().get()) .build(); - List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(false, - capsule, groupMembers); + Group group = GroupFixture.group(); + + List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(group, + false, capsule, groupMembers); setFieldValue(capsule, "id", capsuleId); setFieldValue(capsule, "groupCapsuleOpens", groupCapsuleOpens); @@ -153,7 +154,10 @@ public static Optional groupCapsuleHalfMemberOpen( Capsule capsule = capsuleBuilder.dueDate(ZonedDateTimeSupplier.utc().get()) .build(); + Group group = GroupFixture.group(); + List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpensNotAllOpened( + group, capsule, groupMembers); setFieldValue(capsule, "id", capsuleId); setFieldValue(capsule, "groupCapsuleOpens", groupCapsuleOpens); @@ -182,8 +186,10 @@ public static Optional groupCapsuleAllMemberOpen( Capsule capsule = capsuleBuilder.dueDate(ZonedDateTimeSupplier.utc().get()) .build(); - List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(true, - capsule, groupMembers); + Group group = GroupFixture.group(); + + List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(group, + true, capsule, groupMembers); setFieldValue(capsule, "id", capsuleId); setFieldValue(capsule, "groupCapsuleOpens", groupCapsuleOpens); @@ -199,22 +205,13 @@ public static Optional groupCapsuleExcludeSpecificMember( Capsule capsule = capsuleBuilder.dueDate(ZonedDateTimeSupplier.utc().get()) .build(); + Group group = GroupFixture.group(); + List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpensNotOpenSpecificMemberId( - capsule, groupMembers, memberId); + group, capsule, groupMembers, memberId); setFieldValue(capsule, "id", capsuleId); setFieldValue(capsule, "groupCapsuleOpens", groupCapsuleOpens); return Optional.ofNullable(capsule); } - - public static Optional groupCapsuleAlreadyOpen(Long memberId, Long capsuleId) { - CapsuleBuilder capsuleBuilder = getCapsuleBuilder(memberId); - Capsule capsule = capsuleBuilder.dueDate(ZonedDateTimeSupplier.utc().get()) - .build(); - - setFieldValue(capsule, "id", capsuleId); - setFieldValue(capsule, "isOpened", true); - - return Optional.ofNullable(capsule); - } } diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/domain/GroupCapsuleOpenFixture.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/domain/GroupCapsuleOpenFixture.java index e718b048e..7a4c17ff8 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/domain/GroupCapsuleOpenFixture.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/domain/GroupCapsuleOpenFixture.java @@ -1,50 +1,69 @@ package site.timecapsulearchive.core.common.fixture.domain; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collection; import java.util.List; -import java.util.Optional; import java.util.stream.Stream; import site.timecapsulearchive.core.domain.capsule.entity.Capsule; -import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType; import site.timecapsulearchive.core.domain.capsule.entity.GroupCapsuleOpen; -import site.timecapsulearchive.core.domain.capsuleskin.entity.CapsuleSkin; +import site.timecapsulearchive.core.domain.group.entity.Group; import site.timecapsulearchive.core.domain.member.entity.Member; public class GroupCapsuleOpenFixture { - public static List groupCapsuleOpens(Boolean isOpened, Capsule capsule, - List groupMembers) { + public static List groupCapsuleOpens( + Group group, + Boolean isOpened, + Capsule capsule, + List groupMembers + ) { return groupMembers.stream() - .map(member -> GroupCapsuleOpen.builder() - .isOpened(isOpened) - .capsule(capsule) - .member(member) - .build() - ).toList(); + .map(member -> getGroupCapsuleOpen(group, isOpened, capsule, member)) + .toList(); } - public static Optional groupCapsuleOpen(int dataPrefix) { - Member member = MemberFixture.member(dataPrefix); - CapsuleSkin capsuleSkin = CapsuleSkinFixture.capsuleSkin(member); + private static GroupCapsuleOpen getGroupCapsuleOpen( + Group group, + Boolean isOpened, + Capsule capsule, + Member member + ) { + try { + Constructor declaredConstructor = GroupCapsuleOpen.class.getDeclaredConstructor(); + declaredConstructor.setAccessible(true); + + GroupCapsuleOpen groupCapsuleOpen = declaredConstructor.newInstance(); + setFieldValue(groupCapsuleOpen, "group", group); + setFieldValue(groupCapsuleOpen, "capsule", capsule); + setFieldValue(groupCapsuleOpen, "isOpened", isOpened); + setFieldValue(groupCapsuleOpen, "member", member); + return groupCapsuleOpen; + } catch (Exception e) { + throw new RuntimeException(e); + } + } - return Optional.of( - GroupCapsuleOpen.createOf( - MemberFixture.member(dataPrefix), - CapsuleFixture.capsule(member, capsuleSkin, CapsuleType.GROUP), - Boolean.FALSE - ) - ); + private static void setFieldValue(Object instance, String fieldName, Object value) { + try { + Field field = instance.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + field.set(instance, value); + } catch (Exception e) { + throw new RuntimeException(e); + } } public static List groupCapsuleOpensNotAllOpened( + Group group, Capsule capsule, List groupMembers ) { int mid = groupMembers.size() / 2; - List opened = groupCapsuleOpens(true, capsule, + List opened = groupCapsuleOpens(group, true, capsule, groupMembers.subList(0, mid)); - List notOpened = groupCapsuleOpens(false, capsule, + List notOpened = groupCapsuleOpens(group, false, capsule, groupMembers.subList(mid, groupMembers.size() - 1)); return Stream.of(opened, notOpened) @@ -53,6 +72,7 @@ public static List groupCapsuleOpensNotAllOpened( } public static List groupCapsuleOpensNotOpenSpecificMemberId( + Group group, Capsule capsule, List groupMembers, Long memberId @@ -72,8 +92,8 @@ public static List groupCapsuleOpensNotOpenSpecificMemberId( } List result = new ArrayList<>(); - result.add(GroupCapsuleOpen.createOf(specificMember, capsule, false)); - result.addAll(groupCapsuleOpens(true, capsule, filteredMember)); + result.add(getGroupCapsuleOpen(group, false, capsule, specificMember)); + result.addAll(groupCapsuleOpens(group, true, capsule, filteredMember)); return result; } diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepositoryTest.java index 4a9c6c10d..59c07797f 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepositoryTest.java @@ -2,7 +2,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import java.util.List; import javax.sql.DataSource; @@ -19,12 +18,12 @@ 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.domain.capsule.entity.Capsule; -import site.timecapsulearchive.core.domain.capsule.entity.CapsuleType; import site.timecapsulearchive.core.domain.capsule.entity.GroupCapsuleOpen; -import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleOpenQueryRepository; import site.timecapsulearchive.core.domain.capsuleskin.entity.CapsuleSkin; +import site.timecapsulearchive.core.domain.group.entity.Group; import site.timecapsulearchive.core.domain.member.entity.Member; @TestConstructor(autowireMode = AutowireMode.ALL) @@ -32,6 +31,8 @@ class GroupCapsuleOpenQueryRepositoryTest extends RepositoryTest { private final NamedParameterJdbcTemplate namedParameterJdbcTemplate; private final GroupCapsuleOpenQueryRepository groupCapsuleOpenRepository; + + private Long groupId; private Capsule capsule; private List groupMembers; private List groupCapsuleOpens; @@ -47,6 +48,10 @@ public GroupCapsuleOpenQueryRepositoryTest( @Transactional @BeforeEach void setUp(@Autowired EntityManager entityManager) { + Group group = GroupFixture.group(); + entityManager.persist(group); + groupId = group.getId(); + groupMembers = MemberFixture.members(1, 5); groupMembers.forEach(entityManager::persist); @@ -55,10 +60,10 @@ void setUp(@Autowired EntityManager entityManager) { CapsuleSkin capsuleSkin = CapsuleSkinFixture.capsuleSkin(groupLeader); entityManager.persist(capsuleSkin); - capsule = CapsuleFixture.capsule(groupLeader, capsuleSkin, CapsuleType.GROUP); + capsule = CapsuleFixture.groupCapsule(groupLeader, capsuleSkin, group); entityManager.persist(capsule); - groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(false, capsule, groupMembers); + groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(group, false, capsule, groupMembers); } @Test @@ -68,7 +73,7 @@ void setUp(@Autowired EntityManager entityManager) { Long capsuleId = capsule.getId(); // when - groupCapsuleOpenRepository.bulkSave(groupMemberIds, capsule); + groupCapsuleOpenRepository.bulkSave(groupId, groupMemberIds, capsule); //then String sql = "SELECT count(*) from group_capsule_open WHERE capsule_id = (:capsuleId) and member_id in (:groupMemberIds)"; 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 47f1036fa..0ed08cdf1 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 @@ -76,7 +76,7 @@ void setup(@Autowired EntityManager entityManager) { capsuleId = capsule.getId(); //그룹 캡슐 오픈 여부 - List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(false, + List groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(group, false, capsule, groupMember); groupCapsuleOpens.forEach(entityManager::persist); } From 109e727599fbf8730f574e46966f617f0eb4f9a7 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 9 Jun 2024 09:51:16 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix=20:=20=EA=B7=B8=EB=A3=B9=EC=9B=90?= =?UTF-8?q?=EB=93=A4=EC=9D=98=20=EA=B7=B8=EB=A3=B9=20=EC=BA=A1=EC=8A=90=20?= =?UTF-8?q?=EA=B0=9C=EB=B4=89=20=EC=83=81=ED=83=9C=20=EC=A1=B0=ED=9A=8C=20?= =?UTF-8?q?api=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../group_capsule/api/GroupCapsuleApi.java | 32 ++++++++++++++++++- .../api/GroupCapsuleApiController.java | 21 ++++++++++++ .../dto/GroupMemberCapsuleOpenStatusDto.java | 20 ++++++++++++ ...upMemberCapsuleOpenStatusListResponse.java | 20 ++++++++++++ .../GroupMemberCapsuleOpenStatusResponse.java | 23 +++++++++++++ .../GroupCapsuleOpenQueryRepository.java | 30 +++++++++++++++++ .../service/GroupCapsuleService.java | 25 +++++++++++++-- .../MemberGroupQueryRepository.java | 2 ++ .../MemberGroupQueryRepositoryImpl.java | 11 +++++++ 9 files changed, 181 insertions(+), 3 deletions(-) create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupMemberCapsuleOpenStatusDto.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupMemberCapsuleOpenStatusListResponse.java create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupMemberCapsuleOpenStatusResponse.java 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 06fb9b364..94e4b1f22 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 @@ -19,6 +19,7 @@ import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupMemberCapsuleOpenStatusListResponse; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleCreateRequest; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleUpdateRequest; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleDetailResponse; @@ -154,6 +155,35 @@ ResponseEntity> getMyGroupCapsules( ZonedDateTime createAt ); + @Operation( + summary = "그룹원의 그룹 캡슐 개봉 상태 확인", + description = """ + 그룹원의 그룹 캡슐 개봉 상태를 확인한다. + """, + security = {@SecurityRequirement(name = "user_token")}, + tags = {"group capsule"} + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "처리 완료" + ), + @ApiResponse( + responseCode = "404", + description = "그룹 캡슐의 개봉 상태를 찾을 수 없는 경우 예외가 발생한다.", + content = @Content(schema = @Schema(implementation = ErrorResponse.class)) + ) + }) + ResponseEntity> getGroupCapsuleOpenStatus( + Long memberId, + + @Parameter(in = ParameterIn.PATH, description = "생성할 그룹 아이디", required = true) + Long groupId, + + @Parameter(in = ParameterIn.PATH, description = "개봉 상태를 확인할 캡슐 아이디", required = true) + Long capsuleId + ); + @Operation( summary = "그룹 캡슐 개봉", description = """ @@ -177,7 +207,7 @@ ResponseEntity> openCapsule( Long memberId, @Parameter(in = ParameterIn.PATH, description = "개봉할 그룹 캡슐 아이디", required = true) - @PathVariable("capsule_id") Long capsuleId + Long capsuleId ); @Operation( 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 63f19c19a..43476dd14 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 @@ -2,6 +2,7 @@ import jakarta.validation.Valid; import java.time.ZonedDateTime; +import java.util.List; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Slice; import org.springframework.http.ResponseEntity; @@ -16,6 +17,7 @@ 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.GroupCapsuleSummaryDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.MyGroupCapsuleDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleCreateRequest; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.reqeust.GroupCapsuleUpdateRequest; @@ -23,6 +25,7 @@ import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleOpenStateResponse; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsulePageResponse; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupCapsuleSummaryResponse; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupMemberCapsuleOpenStatusListResponse; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.MyGroupCapsuleSliceResponse; import site.timecapsulearchive.core.domain.capsule.group_capsule.facade.GroupCapsuleFacade; import site.timecapsulearchive.core.domain.capsule.group_capsule.service.GroupCapsuleService; @@ -139,6 +142,24 @@ public ResponseEntity> getMyGroupCapsules( ); } + @GetMapping(value = "/{capsule_id}/open-status", produces = {"application/json"}) + @Override + public ResponseEntity> getGroupCapsuleOpenStatus( + @AuthenticationPrincipal final Long memberId, + @PathVariable("capsule_id") final Long capsuleId, + @RequestParam("group_id") final Long groupId + ) { + List groupMemberCapsuleOpenStatus = groupCapsuleService.findGroupMemberCapsuleOpenStatus( + memberId, capsuleId, groupId); + + return ResponseEntity.ok( + ApiSpec.success( + SuccessCode.SUCCESS, + GroupMemberCapsuleOpenStatusListResponse.create(groupMemberCapsuleOpenStatus) + ) + ); + } + @PostMapping("/{capsule_id}/open") @Override public ResponseEntity> openCapsule( diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupMemberCapsuleOpenStatusDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupMemberCapsuleOpenStatusDto.java new file mode 100644 index 000000000..ee9481f1b --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/dto/GroupMemberCapsuleOpenStatusDto.java @@ -0,0 +1,20 @@ +package site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto; + +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.response.GroupMemberCapsuleOpenStatusResponse; + +public record GroupMemberCapsuleOpenStatusDto( + Long memberId, + String nickname, + String profileUrl, + boolean isOpened +) { + + public GroupMemberCapsuleOpenStatusResponse toResponse() { + return GroupMemberCapsuleOpenStatusResponse.builder() + .memberId(memberId) + .nickname(nickname) + .profileUrl(profileUrl) + .isOpened(isOpened) + .build(); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupMemberCapsuleOpenStatusListResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupMemberCapsuleOpenStatusListResponse.java new file mode 100644 index 000000000..6aabc3fd7 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupMemberCapsuleOpenStatusListResponse.java @@ -0,0 +1,20 @@ +package site.timecapsulearchive.core.domain.capsule.group_capsule.data.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto; + +@Schema(description = "그룹원들 캡슐 개봉 상태") +public record GroupMemberCapsuleOpenStatusListResponse( + List groupMemberCapsuleOpenStatus +) { + + public static GroupMemberCapsuleOpenStatusListResponse create( + List groupMemberCapsuleOpenStatus) { + List groupMemberCapsuleOpenStatusResponses = groupMemberCapsuleOpenStatus.stream() + .map(GroupMemberCapsuleOpenStatusDto::toResponse) + .toList(); + + return new GroupMemberCapsuleOpenStatusListResponse(groupMemberCapsuleOpenStatusResponses); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupMemberCapsuleOpenStatusResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupMemberCapsuleOpenStatusResponse.java new file mode 100644 index 000000000..fc4a98fae --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/data/response/GroupMemberCapsuleOpenStatusResponse.java @@ -0,0 +1,23 @@ +package site.timecapsulearchive.core.domain.capsule.group_capsule.data.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; + +@Schema(description = "그룹원별 캡슐 개봉 상태") +@Builder +public record GroupMemberCapsuleOpenStatusResponse( + + @Schema(description = "회원 아이디") + Long memberId, + + @Schema(description = "회원 닉네임") + String nickname, + + @Schema(description = "회원 프로필") + String profileUrl, + + @Schema(description = "개봉 상태") + boolean isOpened +) { + +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepository.java index ff92ac3ae..31f6e152f 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepository.java @@ -1,5 +1,10 @@ package site.timecapsulearchive.core.domain.capsule.group_capsule.repository; +import static site.timecapsulearchive.core.domain.capsule.entity.QGroupCapsuleOpen.groupCapsuleOpen; +import static site.timecapsulearchive.core.domain.member.entity.QMember.member; + +import com.querydsl.core.types.Projections; +import com.querydsl.jpa.impl.JPAQueryFactory; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Timestamp; @@ -11,12 +16,15 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import site.timecapsulearchive.core.domain.capsule.entity.Capsule; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto; +import site.timecapsulearchive.core.domain.member.entity.QMember; @Repository @RequiredArgsConstructor public class GroupCapsuleOpenQueryRepository { private final JdbcTemplate jdbcTemplate; + private final JPAQueryFactory jpaQueryFactory; public void bulkSave( final Long groupId, @@ -50,4 +58,26 @@ public int getBatchSize() { } ); } + + public List findGroupMemberCapsuleOpenStatus( + final Long capsuleId, + final Long groupId + ) { + return jpaQueryFactory + .select( + Projections.constructor( + GroupMemberCapsuleOpenStatusDto.class, + groupCapsuleOpen.member.id, + groupCapsuleOpen.member.nickname, + groupCapsuleOpen.member.profileUrl, + groupCapsuleOpen.isOpened + ) + ) + .from(groupCapsuleOpen) + .join(groupCapsuleOpen.member, member) + .where(groupCapsuleOpen.group.id.eq(groupId) + .and(groupCapsuleOpen.capsule.id.eq(capsuleId)) + ) + .fetch(); + } } 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 d7123fe1c..6f6659f7f 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 @@ -2,6 +2,7 @@ import java.time.ZoneOffset; import java.time.ZonedDateTime; +import java.util.List; import lombok.RequiredArgsConstructor; import org.locationtech.jts.geom.Point; import org.springframework.data.domain.Slice; @@ -13,13 +14,17 @@ import site.timecapsulearchive.core.domain.capsule.generic_capsule.repository.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.GroupCapsuleSummaryDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupMemberCapsuleOpenStatusDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.MyGroupCapsuleDto; -import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.GroupCapsuleOpenStateDto; +import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleOpenQueryRepository; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleQueryRepository; 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.exception.NoGroupAuthorityException; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; @Service @Transactional(readOnly = true) @@ -28,6 +33,8 @@ public class GroupCapsuleService { private final CapsuleRepository capsuleRepository; private final GroupCapsuleQueryRepository groupCapsuleQueryRepository; + private final GroupCapsuleOpenQueryRepository groupCapsuleOpenQueryRepository; + private final MemberGroupRepository memberGroupRepository; @Transactional public Capsule saveGroupCapsule( @@ -98,7 +105,8 @@ public Slice findMyGroupCapsuleSlice( */ @Transactional public GroupCapsuleOpenStateDto openGroupCapsule(final Long memberId, final Long capsuleId) { - Capsule groupCapsule = capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(memberId, + Capsule groupCapsule = capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId( + memberId, capsuleId) .orElseThrow(CapsuleNotFondException::new); @@ -119,5 +127,18 @@ public GroupCapsuleOpenStateDto openGroupCapsule(final Long memberId, final Long groupCapsule.open(); return GroupCapsuleOpenStateDto.opened(); } + + public List findGroupMemberCapsuleOpenStatus( + final Long memberId, + final Long capsuleId, + final Long groupId + ) { + boolean isGroupMember = memberGroupRepository.existMemberGroupByMemberIdAndGroupId(memberId, groupId); + if (!isGroupMember) { + throw new NoGroupAuthorityException(); + } + + return groupCapsuleOpenQueryRepository.findGroupMemberCapsuleOpenStatus(capsuleId, groupId); + } } 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 b11a3eade..c8aebdf57 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 @@ -20,4 +20,6 @@ public interface MemberGroupQueryRepository { Optional findGroupMembersCount(Long groupId); List findGroupMemberIdsByGroupId(final Long groupId); + + boolean existMemberGroupByMemberIdAndGroupId(Long memberId, Long groupId); } 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 84eb64bfe..51fec1240 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 @@ -103,6 +103,7 @@ public Optional findGroupMembersCount(final Long groupId) { ); } + @Override public List findGroupMemberIdsByGroupId(final Long groupId) { return jpaQueryFactory .select(memberGroup.member.id) @@ -110,4 +111,14 @@ public List findGroupMemberIdsByGroupId(final Long groupId) { .where(memberGroup.group.id.eq(groupId)) .fetch(); } + + @Override + public boolean existMemberGroupByMemberIdAndGroupId(Long memberId, Long groupId) { + final Integer count = jpaQueryFactory.selectOne() + .from(memberGroup) + .where(memberGroup.member.id.eq(memberId).and(memberGroup.group.id.eq(groupId))) + .fetchFirst(); + + return count != null; + } } From 0c6b1d7724e929d338a35ab8f9b8392654387e5c Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 9 Jun 2024 14:41:08 +0900 Subject: [PATCH 3/5] =?UTF-8?q?fix=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../GroupCapsuleOpenQueryRepositoryTest.java | 10 ++++-- .../service/GroupCapsuleServiceTest.java | 32 +++++++++++++------ 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepositoryTest.java index 59c07797f..5637192d6 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/capsule/group_capsule/repository/GroupCapsuleOpenQueryRepositoryTest.java @@ -2,6 +2,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import java.util.List; import javax.sql.DataSource; @@ -39,10 +40,12 @@ class GroupCapsuleOpenQueryRepositoryTest extends RepositoryTest { public GroupCapsuleOpenQueryRepositoryTest( JdbcTemplate jdbcTemplate, - DataSource dataSource + DataSource dataSource, + JPAQueryFactory jpaQueryFactory ) { this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(dataSource); - this.groupCapsuleOpenRepository = new GroupCapsuleOpenQueryRepository(jdbcTemplate); + this.groupCapsuleOpenRepository = new GroupCapsuleOpenQueryRepository(jdbcTemplate, + jpaQueryFactory); } @Transactional @@ -63,7 +66,8 @@ void setUp(@Autowired EntityManager entityManager) { capsule = CapsuleFixture.groupCapsule(groupLeader, capsuleSkin, group); entityManager.persist(capsule); - groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(group, false, capsule, groupMembers); + groupCapsuleOpens = GroupCapsuleOpenFixture.groupCapsuleOpens(group, false, capsule, + groupMembers); } @Test 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 31e5d2ca5..faf823fd2 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 @@ -22,9 +22,11 @@ import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.CapsuleOpenStatus; 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.repository.GroupCapsuleOpenQueryRepository; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleQueryRepository; import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberSummaryDto; import site.timecapsulearchive.core.domain.member.entity.Member; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.error.ErrorCode; class GroupCapsuleServiceTest { @@ -36,9 +38,13 @@ class GroupCapsuleServiceTest { private final CapsuleRepository capsuleRepository = mock(CapsuleRepository.class); private final GroupCapsuleQueryRepository groupCapsuleQueryRepository = mock( GroupCapsuleQueryRepository.class); + private final GroupCapsuleOpenQueryRepository groupCapsuleOpenQueryRepository = mock( + GroupCapsuleOpenQueryRepository.class); + private final MemberGroupRepository memberGroupRepository = mock(MemberGroupRepository.class); private final GroupCapsuleService groupCapsuleService = new GroupCapsuleService( - capsuleRepository, groupCapsuleQueryRepository); + capsuleRepository, groupCapsuleQueryRepository, groupCapsuleOpenQueryRepository, + memberGroupRepository); @Test void 개봉된_그룹_캡슐의_상세_내용을_볼_수_있다() { @@ -196,7 +202,8 @@ class GroupCapsuleServiceTest { @Test void 그룹_캡슐이_없는_경우_그룹_캡슐_개봉_시_예외가_발생한다() { //given - given(capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) + given( + capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) .willReturn(Optional.empty()); //when @@ -212,7 +219,8 @@ class GroupCapsuleServiceTest { ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")); Optional groupCapsule = CapsuleFixture.groupCapsuleSpecificTime(memberId, capsuleId, now.plusYears(5)); - given(capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) + given( + capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) .willReturn(groupCapsule); //when @@ -232,7 +240,8 @@ class GroupCapsuleServiceTest { //given Optional groupCapsule = CapsuleFixture.groupCapsuleSpecificTime(memberId, capsuleId, null); - given(capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) + given( + capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) .willReturn(groupCapsule); //when @@ -254,7 +263,8 @@ class GroupCapsuleServiceTest { Optional groupCapsule = CapsuleFixture.groupCapsuleNotAllMemberOpen(memberId, capsuleId, groupMembers); - given(capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) + given( + capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) .willReturn(groupCapsule); //when @@ -276,7 +286,8 @@ class GroupCapsuleServiceTest { Optional groupCapsule = CapsuleFixture.groupCapsuleHalfMemberOpen(memberId, capsuleId, groupMembers); - given(capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) + given( + capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) .willReturn(groupCapsule); //when @@ -295,7 +306,8 @@ class GroupCapsuleServiceTest { void 그룹_캡슐_개봉이_없는_경우_예외가_발생한다() { //given Optional groupCapsule = CapsuleFixture.groupCapsuleEmptyOpen(memberId, capsuleId); - given(capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) + given( + capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) .willReturn(groupCapsule); //when @@ -312,7 +324,8 @@ class GroupCapsuleServiceTest { Optional groupCapsule = CapsuleFixture.groupCapsuleAllMemberOpen(memberId, capsuleId, groupMembers); - given(capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) + given( + capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) .willReturn(groupCapsule); //when @@ -334,7 +347,8 @@ class GroupCapsuleServiceTest { Optional groupCapsule = CapsuleFixture.groupCapsuleExcludeSpecificMember(memberId, capsuleId, groupMembers); - given(capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) + given( + capsuleRepository.findNotOpenedGroupCapsuleByMemberIdAndCapsuleId(anyLong(), anyLong())) .willReturn(groupCapsule); //when From 957654a0000d739c4522f6a91973488df7c14087 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 9 Jun 2024 15:40:36 +0900 Subject: [PATCH 4/5] =?UTF-8?q?fix=20:=20api=20docs=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/capsule/group_capsule/api/GroupCapsuleApi.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 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 94e4b1f22..376efced6 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 @@ -177,11 +177,11 @@ ResponseEntity> getMyGroupCapsules( ResponseEntity> getGroupCapsuleOpenStatus( Long memberId, - @Parameter(in = ParameterIn.PATH, description = "생성할 그룹 아이디", required = true) - Long groupId, - @Parameter(in = ParameterIn.PATH, description = "개봉 상태를 확인할 캡슐 아이디", required = true) - Long capsuleId + Long capsuleId, + + @Parameter(in = ParameterIn.QUERY, description = "생성할 그룹 아이디", required = true) + Long groupId ); @Operation( From bb936017846de9e8016805c3087d0bdf98049345 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 9 Jun 2024 15:52:36 +0900 Subject: [PATCH 5/5] =?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?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...roupMemberCapsuleOpenStatusDtoFixture.java | 21 ++++++++++ .../service/GroupCapsuleServiceTest.java | 38 +++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupMemberCapsuleOpenStatusDtoFixture.java diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupMemberCapsuleOpenStatusDtoFixture.java b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupMemberCapsuleOpenStatusDtoFixture.java new file mode 100644 index 000000000..695ef1c7b --- /dev/null +++ b/backend/core/src/test/java/site/timecapsulearchive/core/common/fixture/dto/GroupMemberCapsuleOpenStatusDtoFixture.java @@ -0,0 +1,21 @@ +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.GroupMemberCapsuleOpenStatusDto; + +public class GroupMemberCapsuleOpenStatusDtoFixture { + + public static List groupMemberCapsuleOpenStatusDto( + Long memberId, + int size + ) { + List result = new ArrayList<>(); + for (long count = memberId; count < size; count++) { + result.add(new GroupMemberCapsuleOpenStatusDto(count, count + "test-nickname", + count + "test-profile", true)); + } + + 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 faf823fd2..4d9721f51 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 @@ -1,5 +1,6 @@ package site.timecapsulearchive.core.domain.capsule.group_capsule.service; +import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.SoftAssertions.assertSoftly; import static org.mockito.ArgumentMatchers.anyLong; @@ -14,6 +15,7 @@ import site.timecapsulearchive.core.common.fixture.domain.CapsuleFixture; import site.timecapsulearchive.core.common.fixture.domain.MemberFixture; import site.timecapsulearchive.core.common.fixture.dto.CapsuleDtoFixture; +import site.timecapsulearchive.core.common.fixture.dto.GroupMemberCapsuleOpenStatusDtoFixture; import site.timecapsulearchive.core.domain.capsule.entity.Capsule; import site.timecapsulearchive.core.domain.capsule.exception.CapsuleNotFondException; import site.timecapsulearchive.core.domain.capsule.exception.GroupCapsuleOpenNotFoundException; @@ -22,10 +24,12 @@ import site.timecapsulearchive.core.domain.capsule.group_capsule.data.dto.CapsuleOpenStatus; 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.GroupMemberCapsuleOpenStatusDto; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleOpenQueryRepository; import site.timecapsulearchive.core.domain.capsule.group_capsule.repository.GroupCapsuleQueryRepository; import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberSummaryDto; 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; import site.timecapsulearchive.core.global.error.ErrorCode; @@ -362,4 +366,38 @@ class GroupCapsuleServiceTest { CapsuleOpenStatus.OPEN); }); } + + @Test + void 그룹원이_아닌_사용자가_그룹_캡슐_개봉_상태를_조회하면_오류가_발생한다() throws Exception { + //given + Long groupId = 1L; + + //when + //then + assertThatThrownBy( + () -> groupCapsuleService.findGroupMemberCapsuleOpenStatus(memberId, capsuleId, + groupId)) + .isInstanceOf(NoGroupAuthorityException.class) + .hasMessageContaining(ErrorCode.NO_GROUP_AUTHORITY_ERROR.getMessage()); + } + + @Test + void 그룹원이_그룹_캡슐_개봉_상태를_조회하면_그룹_캡슐_개봉_상태를_조회할_수_있다() throws Exception { + //given + Long groupId = 1L; + int size = 20; + given(memberGroupRepository.existMemberGroupByMemberIdAndGroupId(memberId, groupId)) + .willReturn(true); + given(groupCapsuleOpenQueryRepository.findGroupMemberCapsuleOpenStatus(capsuleId, groupId)) + .willReturn( + GroupMemberCapsuleOpenStatusDtoFixture.groupMemberCapsuleOpenStatusDto(memberId, + size)); + + //when + List groupMemberCapsuleOpenStatus = groupCapsuleService.findGroupMemberCapsuleOpenStatus( + memberId, capsuleId, groupId); + + //then + assertThat(groupMemberCapsuleOpenStatus).isNotEmpty(); + } }