From ef809e4695d83fc4307c26e2c259392f9e2ae955 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sat, 1 Jun 2024 16:06:39 +0900 Subject: [PATCH 1/8] =?UTF-8?q?feat=20:=20=EC=B9=9C=EA=B5=AC=20=EC=9A=94?= =?UTF-8?q?=EC=B2=AD=20=EB=AA=A9=EB=A1=9D=20=EC=A1=B0=ED=9A=8C=20=EB=B3=B4?= =?UTF-8?q?=EB=82=B8=EA=B1=B0,=20=EB=B0=9B=EC=9D=80=EA=B1=B0=EB=A1=9C=20?= =?UTF-8?q?=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 기존 API에서 함수 이름 변경 - 친구 요청 보낸 목록 조회 추가 - 쿼리 오류 수정(createdAt.lt -> createdAt.loe) - 테스트 추가 --- .gitignore | 2 +- .../friend/api/query/FriendQueryApi.java | 33 ++++++++++++++++--- .../api/query/FriendQueryApiController.java | 33 +++++++++++++++---- .../response/FriendRequestsSliceResponse.java | 26 --------------- .../MemberFriendQueryRepository.java | 8 ++++- .../MemberFriendQueryRepositoryImpl.java | 33 ++++++++++++++++--- .../service/query/FriendQueryService.java | 12 +++++-- 7 files changed, 103 insertions(+), 44 deletions(-) delete mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/data/response/FriendRequestsSliceResponse.java diff --git a/.gitignore b/.gitignore index 91cd78597..51e94bb56 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .idea -data \ No newline at end of file +backend/data \ No newline at end of file diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApi.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApi.java index 0cd05496a..bf4fa86b9 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApi.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApi.java @@ -9,7 +9,6 @@ import java.time.ZonedDateTime; import org.springframework.http.ResponseEntity; import site.timecapsulearchive.core.domain.friend.data.request.SearchFriendsRequest; -import site.timecapsulearchive.core.domain.friend.data.response.FriendRequestsSliceResponse; import site.timecapsulearchive.core.domain.friend.data.response.FriendsSliceResponse; import site.timecapsulearchive.core.domain.friend.data.response.SearchFriendsResponse; import site.timecapsulearchive.core.domain.friend.data.response.SearchTagFriendSummaryResponse; @@ -65,8 +64,34 @@ ResponseEntity> findFriendsBeforeGroupInvite( ); @Operation( - summary = "소셜 친구 요청 목록 조회", - description = "사용자의 소셜 친구 요청 목록을 보여준다. 수락 대기 중인 요청만 해당한다.", + summary = "소셜 친구 요청 받은 목록 조회", + description = """ + 사용자가 소셜 친구 요청을 받은 목록을 보여준다. +
+ 수락 대기 중인 요청만 해당한다. + """, + security = {@SecurityRequirement(name = "user_token")}, + tags = {"friend"} + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "ok" + ) + }) + ResponseEntity> findFriendReceptionInvites( + Long memberId, + + @Parameter(in = ParameterIn.QUERY, description = "페이지 크기", required = true) + int size, + + @Parameter(in = ParameterIn.QUERY, description = "마지막 데이터의 시간", required = true) + ZonedDateTime createdAt + ); + + @Operation( + summary = "소셜 친구 요청 보낸 목록 조회", + description = "사용자가 소셜 친구 요청을 보낸 목록을 보여준다.", security = {@SecurityRequirement(name = "user_token")}, tags = {"friend"} ) @@ -76,7 +101,7 @@ ResponseEntity> findFriendsBeforeGroupInvite( description = "ok" ) }) - ResponseEntity> findFriendRequests( + ResponseEntity> findFriendSendingInvites( Long memberId, @Parameter(in = ParameterIn.QUERY, description = "페이지 크기", required = true) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApiController.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApiController.java index f9856fb3b..46077f0c9 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApiController.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApiController.java @@ -18,7 +18,6 @@ import site.timecapsulearchive.core.domain.friend.data.dto.SearchFriendSummaryDtoByTag; import site.timecapsulearchive.core.domain.friend.data.request.FriendBeforeGroupInviteRequest; import site.timecapsulearchive.core.domain.friend.data.request.SearchFriendsRequest; -import site.timecapsulearchive.core.domain.friend.data.response.FriendRequestsSliceResponse; import site.timecapsulearchive.core.domain.friend.data.response.FriendsSliceResponse; import site.timecapsulearchive.core.domain.friend.data.response.SearchFriendsResponse; import site.timecapsulearchive.core.domain.friend.data.response.SearchTagFriendSummaryResponse; @@ -77,23 +76,45 @@ public ResponseEntity> findFriendsBeforeGroupInvit } @GetMapping( - value = "/requests", + value = "/reception-invites", produces = {"application/json"} ) @Override - public ResponseEntity> findFriendRequests( + public ResponseEntity> findFriendReceptionInvites( @AuthenticationPrincipal final Long memberId, @RequestParam(defaultValue = "20", value = "size") final int size, @RequestParam(value = "created_at") final ZonedDateTime createdAt ) { - final Slice friendRequestsSlice = friendQueryService.findFriendRequestsSlice( + final Slice friendReceptionInvitesSlice = friendQueryService.findFriendReceptionInvitesSlice( memberId, size, createdAt); return ResponseEntity.ok( ApiSpec.success( SuccessCode.SUCCESS, - FriendRequestsSliceResponse.createOf(friendRequestsSlice.getContent(), - friendRequestsSlice.hasNext()) + FriendsSliceResponse.createOf(friendReceptionInvitesSlice.getContent(), + friendReceptionInvitesSlice.hasNext()) + ) + ); + } + + @GetMapping( + value = "/sending-invites", + produces = {"application/json"} + ) + @Override + public ResponseEntity> findFriendSendingInvites( + @AuthenticationPrincipal final Long memberId, + @RequestParam(defaultValue = "20", value = "size") final int size, + @RequestParam(value = "created_at") final ZonedDateTime createdAt + ) { + final Slice friendSendingInvitesSlice = friendQueryService.findFriendSendingInvitesSlice( + memberId, size, createdAt); + + return ResponseEntity.ok( + ApiSpec.success( + SuccessCode.SUCCESS, + FriendsSliceResponse.createOf(friendSendingInvitesSlice.getContent(), + friendSendingInvitesSlice.hasNext()) ) ); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/data/response/FriendRequestsSliceResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/data/response/FriendRequestsSliceResponse.java deleted file mode 100644 index 731b823e5..000000000 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/data/response/FriendRequestsSliceResponse.java +++ /dev/null @@ -1,26 +0,0 @@ -package site.timecapsulearchive.core.domain.friend.data.response; - -import io.swagger.v3.oas.annotations.media.Schema; -import java.util.List; -import site.timecapsulearchive.core.domain.friend.data.dto.FriendSummaryDto; - -@Schema(description = "친구 요청 리스트") -public record FriendRequestsSliceResponse( - @Schema(description = "친구 요약 정보 리스트") - List friends, - - @Schema(description = "다음 페이지 유무") - Boolean hasNext -) { - - public static FriendRequestsSliceResponse createOf( - List content, - boolean hasNext - ) { - List friends = content.stream() - .map(FriendSummaryDto::toResponse) - .toList(); - - return new FriendRequestsSliceResponse(friends, hasNext); - } -} \ No newline at end of file diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepository.java index 8e8c32667..545cf6434 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepository.java @@ -18,7 +18,13 @@ Slice findFriendsSlice( final ZonedDateTime createdAt ); - Slice findFriendRequestsSlice( + Slice findFriendReceptionInvitesSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ); + + Slice findFriendSendingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java index 7bc29fdd2..270870bc4 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java @@ -56,7 +56,7 @@ public Slice findFriendsSlice( .from(memberFriend) .innerJoin(member).on(memberFriend.owner.id.eq(member.id)) .innerJoin(member).on(memberFriend.friend.id.eq(member.id)) - .where(memberFriend.owner.id.eq(memberId).and(memberFriend.createdAt.lt(createdAt))) + .where(memberFriend.owner.id.eq(memberId).and(memberFriend.createdAt.loe(createdAt))) .limit(size + 1) .fetch(); @@ -89,7 +89,7 @@ public Slice findFriendsBeforeGroupInvite( .innerJoin(member).on(memberFriend.owner.id.eq(member.id)) .innerJoin(member).on(memberFriend.friend.id.eq(member.id)) .where(memberFriend.owner.id.eq(request.memberId()) - .and(memberFriend.createdAt.lt(request.createdAt())) + .and(memberFriend.createdAt.loe(request.createdAt())) .and(memberFriend.friend.id.notIn( select(memberGroup.member.id) .from(memberGroup) @@ -102,7 +102,7 @@ public Slice findFriendsBeforeGroupInvite( return getFriendSummaryDtos(request.size(), friends); } - public Slice findFriendRequestsSlice( + public Slice findFriendReceptionInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt @@ -119,7 +119,32 @@ public Slice findFriendRequestsSlice( ) .from(friendInvite) .join(friendInvite.owner, member) - .where(friendInvite.friend.id.eq(memberId).and(friendInvite.createdAt.lt(createdAt))) + .where(friendInvite.friend.id.eq(memberId).and(friendInvite.createdAt.loe(createdAt))) + .limit(size + 1) + .fetch(); + + return getFriendSummaryDtos(size, friends); + } + + @Override + public Slice findFriendSendingInvitesSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ) { + final List friends = jpaQueryFactory + .select( + Projections.constructor( + FriendSummaryDto.class, + friendInvite.owner.id, + friendInvite.owner.profileUrl, + friendInvite.owner.nickname, + friendInvite.createdAt + ) + ) + .from(friendInvite) + .join(friendInvite.owner, member) + .where(friendInvite.owner.id.eq(memberId).and(friendInvite.createdAt.loe(createdAt))) .limit(size + 1) .fetch(); diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java index d34230f0a..6a179fdc1 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java @@ -34,12 +34,20 @@ public Slice findFriendsBeforeGroupInviteSlice( return memberFriendRepository.findFriendsBeforeGroupInvite(request); } - public Slice findFriendRequestsSlice( + public Slice findFriendReceptionInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt ) { - return memberFriendRepository.findFriendRequestsSlice(memberId, size, createdAt); + return memberFriendRepository.findFriendReceptionInvitesSlice(memberId, size, createdAt); + } + + public Slice findFriendSendingInvitesSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ) { + return memberFriendRepository.findFriendSendingInvitesSlice(memberId, size, createdAt); } public List findFriendsByPhone( From b3a1a1ee85dfddc027d1eb63431e898bdd9fd53e Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sat, 1 Jun 2024 16:06:56 +0900 Subject: [PATCH 2/8] =?UTF-8?q?test=20:=20=EA=B8=B0=EC=A1=B4=20API=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20?= =?UTF-8?q?=EC=B9=9C=EA=B5=AC=20=EB=B3=B4=EB=82=B8=20=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MemberFriendQueryRepositoryTest.java | 178 +++++++++++++++--- 1 file changed, 154 insertions(+), 24 deletions(-) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java index 09ae4cf3d..339194a74 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java @@ -41,10 +41,11 @@ class MemberFriendQueryRepositoryTest extends RepositoryTest { private static final String PROPAGATION_REQUIRES_NEW = "PROPAGATION_REQUIRES_NEW"; - private static final int MAX_COUNT = 10; + private static final int MAX_COUNT = 40; private static final Long FRIEND_START_ID = 2L; - private static final Long FRIEND_ID_TO_INVITE_OWNER = 12L; - private static final Long NOT_FRIEND_MEMBER_START_ID = 13L; + private static final Long NOT_FRIEND_MEMBER_START_ID = FRIEND_START_ID + MAX_COUNT; + private static final Long FRIEND_RECEPTION_INVITE_MEMBER_START_ID = NOT_FRIEND_MEMBER_START_ID + MAX_COUNT; + private static final Long FRIEND_SENDING_INVITE_MEMBER_START_ID = FRIEND_RECEPTION_INVITE_MEMBER_START_ID + MAX_COUNT; private final MemberFriendQueryRepository memberFriendQueryRepository; @@ -91,15 +92,6 @@ void setup(@Autowired EntityManager entityManager, friendId = friends.get(0).getId(); friendTag = friends.get(0).getTag(); - // owner에게 친구 요청만 보낸 멤버 데이터 - Member inviteFriendToOwner = MemberFixture.member(FRIEND_ID_TO_INVITE_OWNER.intValue()); - entityManager.persist(inviteFriendToOwner); - friendInviteTag =inviteFriendToOwner.getTag(); - - FriendInvite friendInvite = FriendInviteFixture.friendInvite(inviteFriendToOwner, - owner); - entityManager.persist(friendInvite); - //owner와 친구가 아닌 멤버 데이터 List notFriendMembers = MemberFixture.members( NOT_FRIEND_MEMBER_START_ID.intValue(), @@ -108,11 +100,31 @@ void setup(@Autowired EntityManager entityManager, entityManager.persist(notFriend); hashedNotFriendPhones.add(notFriend.getPhone_hash()); } - //owner에게 친구 요청을 보내지 않은 데이터 notFriendInviteTag = notFriendMembers.get(0).getTag(); //owner와 친구가 아닌 데이터 notFriendTag = notFriendMembers.get(0).getTag(); + + // owner에게 친구 요청만 받은 멤버 데이터 + List friendReceptionInviteMembers = MemberFixture.members( + FRIEND_RECEPTION_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); + for (Member member : friendReceptionInviteMembers) { + entityManager.persist(member); + + FriendInvite receptionInvite = FriendInviteFixture.friendInvite(owner, member); + entityManager.persist(receptionInvite); + } + friendInviteTag = friendReceptionInviteMembers.get(0).getTag(); + + // owner에게 친구 요청만 보낸 멤버 데이터 + List friendSendingInviteMembers = MemberFixture.members( + FRIEND_SENDING_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); + for (Member member : friendSendingInviteMembers) { + entityManager.persist(member); + + FriendInvite sendingInvite = FriendInviteFixture.friendInvite(member, owner); + entityManager.persist(sendingInvite); + } }); } @@ -125,8 +137,8 @@ void clear(@Autowired EntityManager entityManager) { entityManager.createNativeQuery("SET FOREIGN_KEY_CHECKS=1").executeUpdate(); } - @ParameterizedTest @ValueSource(ints = {2, 7, 10, 5}) + @ParameterizedTest void 사용자가_친구_목록_조회하면_친구_관계를_맺은_사용자_리스트가_나온다(int size) { //given ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); @@ -149,6 +161,28 @@ void clear(@Autowired EntityManager entityManager) { ); } + @Test + void 사용자가_첫_페이지_이후의_친구_목록_조회하면_다음_페이지의_친구_관계를_맺은_사용자_리스트가_나온다() { + //given + int size = 20; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + Slice firstSlice = memberFriendQueryRepository.findFriendsSlice( + ownerId, + size, + now + ); + + //when + FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); + Slice nextSlice = memberFriendQueryRepository.findFriendsSlice( + ownerId, + size, + dto.createdAt() + ); + + assertThat(nextSlice.getNumberOfElements()).isPositive(); + } + @Test void 친구가_친구_목록_조회하면_친구_관계를_맺은_사용자_리스트가_나온다() { //given @@ -166,14 +200,14 @@ void clear(@Autowired EntityManager entityManager) { } @Test - void 친구_요청만_보낸_사용자가_친구_목록_조회하면_리스트가_나온다() { + void 친구_요청만_보낸_사용자가_친구_목록_조회하면_빈_리스트가_나온다() { //given - int size = 20; + int size = 10; ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); //when Slice slice = memberFriendQueryRepository.findFriendsSlice( - FRIEND_ID_TO_INVITE_OWNER, + FRIEND_RECEPTION_INVITE_MEMBER_START_ID, size, now ); @@ -185,7 +219,7 @@ void clear(@Autowired EntityManager entityManager) { @Test void 사용자가_유효하지_않은_시간으로_사용자의_친구_목록_조회하면_빈_리스트가_나온다() { //given - int size = 20; + int size = 10; ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); //when @@ -202,7 +236,7 @@ void clear(@Autowired EntityManager entityManager) { @Test void 친구가_없는_사용자가_친구_목록_조회하면_빈_리스트가_나온다() { //given - int size = 20; + int size = 10; ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); //when @@ -216,14 +250,45 @@ void clear(@Autowired EntityManager entityManager) { assertThat(slice).isEmpty(); } + @ValueSource(ints = {2, 7, 10, 5}) + @ParameterizedTest + void 사용자가_보낸_친구_요청_받은_목록을_조회하면_보낸_친구_요청목록이_나온다(int size) { + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + + Slice slice = memberFriendQueryRepository.findFriendSendingInvitesSlice( + ownerId, + size, + now + ); + + assertThat(slice.getNumberOfElements()).isEqualTo(size); + } + @Test - void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_목록_조회하면_빈_리스트가_나온다() { + void 사용자가_첫_페이지_이후의_친구요청_보낸_목록을_조회하면_다음_페이지의_보낸_친구_요청목록이_나온다() { //given int size = 20; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + Slice firstSlice = memberFriendQueryRepository.findFriendSendingInvitesSlice( + ownerId, size, now); + + //when + FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); + Slice nextSlice = memberFriendQueryRepository.findFriendSendingInvitesSlice( + ownerId, size, dto.createdAt()); + + //then + assertThat(nextSlice.getNumberOfElements()).isPositive(); + } + + @Test + void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_보낸_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); //when - Slice slice = memberFriendQueryRepository.findFriendRequestsSlice( + Slice slice = memberFriendQueryRepository.findFriendSendingInvitesSlice( ownerId, size, now @@ -234,13 +299,78 @@ void clear(@Autowired EntityManager entityManager) { } @Test - void 친구가_없는_사용자가_친구_요청_목록_조회하면_빈_리스트가_나온다() { + void 친구_요청을_보내지_않은_사용자가_친구_요청_보낸_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); + + //when + Slice slice = memberFriendQueryRepository.findFriendSendingInvitesSlice( + NOT_FRIEND_MEMBER_START_ID, + size, + now + ); + + //then + assertThat(slice).isEmpty(); + } + + @ValueSource(ints = {2, 7, 10, 5}) + @ParameterizedTest + void 사용자가_받은_친구_요청_받은_목록을_조회하면_받은_친구_요청목록이_나온다(int size) { + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + + Slice slice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( + ownerId, + size, + now + ); + + assertThat(slice.getNumberOfElements()).isEqualTo(size); + } + + @Test + void 사용자가_첫_페이지_이후의_친구요청_받은_목록을_조회하면_다음_페이지의_받은_친구_요청목록이_나온다() { //given int size = 20; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + Slice firstSlice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( + ownerId, size, now); + + //when + FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); + Slice nextSlice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( + ownerId, size, dto.createdAt()); + + //then + assertThat(nextSlice.getNumberOfElements()).isPositive(); + } + + @Test + void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_받은_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); + + //when + Slice slice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( + ownerId, + size, + now + ); + + //then + assertThat(slice).isEmpty(); + } + + @Test + void 친구_요청을_받지_않은_사용자가_친구_요청_받은_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); //when - Slice slice = memberFriendQueryRepository.findFriendRequestsSlice( + Slice slice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( NOT_FRIEND_MEMBER_START_ID, size, now @@ -371,7 +501,7 @@ void clear(@Autowired EntityManager entityManager) { ownerId, friendInviteTag).orElseThrow(); //then - assertThat(dto.isFriendInviteToMe()).isTrue(); + assertThat(dto.isFriendInviteToMe() || dto.isFriendInviteToFriend()).isTrue(); } @Test From 041faddfd3005a66e8b4c22b6e5a66f9347b3529 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sat, 1 Jun 2024 16:22:12 +0900 Subject: [PATCH 3/8] =?UTF-8?q?fix=20:=20=EC=BF=BC=EB=A6=AC=20=EC=98=A4?= =?UTF-8?q?=EB=A5=98=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=98=A4?= =?UTF-8?q?=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 --- .../MemberFriendQueryRepositoryImpl.java | 6 ++-- .../MemberFriendQueryRepositoryTest.java | 28 +++++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java index 270870bc4..2b436f7cd 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java @@ -136,9 +136,9 @@ public Slice findFriendSendingInvitesSlice( .select( Projections.constructor( FriendSummaryDto.class, - friendInvite.owner.id, - friendInvite.owner.profileUrl, - friendInvite.owner.nickname, + friendInvite.friend.id, + friendInvite.friend.profileUrl, + friendInvite.friend.nickname, friendInvite.createdAt ) ) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java index 339194a74..4c6cf98c0 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java @@ -44,8 +44,10 @@ class MemberFriendQueryRepositoryTest extends RepositoryTest { private static final int MAX_COUNT = 40; private static final Long FRIEND_START_ID = 2L; private static final Long NOT_FRIEND_MEMBER_START_ID = FRIEND_START_ID + MAX_COUNT; - private static final Long FRIEND_RECEPTION_INVITE_MEMBER_START_ID = NOT_FRIEND_MEMBER_START_ID + MAX_COUNT; - private static final Long FRIEND_SENDING_INVITE_MEMBER_START_ID = FRIEND_RECEPTION_INVITE_MEMBER_START_ID + MAX_COUNT; + private static final Long FRIEND_RECEPTION_INVITE_MEMBER_START_ID = + NOT_FRIEND_MEMBER_START_ID + MAX_COUNT; + private static final Long FRIEND_SENDING_INVITE_MEMBER_START_ID = + FRIEND_RECEPTION_INVITE_MEMBER_START_ID + MAX_COUNT; private final MemberFriendQueryRepository memberFriendQueryRepository; @@ -54,6 +56,8 @@ class MemberFriendQueryRepositoryTest extends RepositoryTest { private final List hashedNotFriendPhones = new ArrayList<>(); private Long ownerId; private Long friendId; + private Long ownerInviteSendingStartId; + private Long ownerInviteReceptionStartId; private String friendTag; private String notFriendTag; private String friendInviteTag; @@ -106,25 +110,27 @@ void setup(@Autowired EntityManager entityManager, notFriendTag = notFriendMembers.get(0).getTag(); // owner에게 친구 요청만 받은 멤버 데이터 - List friendReceptionInviteMembers = MemberFixture.members( + List receptionInviteToOwnerMembers = MemberFixture.members( FRIEND_RECEPTION_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); - for (Member member : friendReceptionInviteMembers) { + for (Member member : receptionInviteToOwnerMembers) { entityManager.persist(member); FriendInvite receptionInvite = FriendInviteFixture.friendInvite(owner, member); entityManager.persist(receptionInvite); } - friendInviteTag = friendReceptionInviteMembers.get(0).getTag(); + friendInviteTag = receptionInviteToOwnerMembers.get(0).getTag(); + ownerInviteReceptionStartId = receptionInviteToOwnerMembers.get(0).getId(); // owner에게 친구 요청만 보낸 멤버 데이터 - List friendSendingInviteMembers = MemberFixture.members( + List sendingInviteToOwnerMembers = MemberFixture.members( FRIEND_SENDING_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); - for (Member member : friendSendingInviteMembers) { + for (Member member : sendingInviteToOwnerMembers) { entityManager.persist(member); FriendInvite sendingInvite = FriendInviteFixture.friendInvite(member, owner); entityManager.persist(sendingInvite); } + ownerInviteSendingStartId = sendingInviteToOwnerMembers.get(0).getId(); }); } @@ -261,7 +267,9 @@ void clear(@Autowired EntityManager entityManager) { now ); - assertThat(slice.getNumberOfElements()).isEqualTo(size); + assertThat(slice.getContent()).isNotEmpty(); + assertThat(slice.getContent()).allMatch(dto -> dto.id() >= ownerInviteReceptionStartId + && dto.id() < ownerInviteReceptionStartId + MAX_COUNT); } @Test @@ -326,7 +334,9 @@ void clear(@Autowired EntityManager entityManager) { now ); - assertThat(slice.getNumberOfElements()).isEqualTo(size); + assertThat(slice.getContent()).isNotEmpty(); + assertThat(slice.getContent()).allMatch(dto -> dto.id() >= ownerInviteSendingStartId + && dto.id() < ownerInviteSendingStartId + MAX_COUNT); } @Test From 03637d788f6a134eaaba39fba5afba692b573d7c Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 2 Jun 2024 16:00:26 +0900 Subject: [PATCH 4/8] =?UTF-8?q?fix=20:=20=EB=A0=88=ED=8F=AC=EC=A7=80?= =?UTF-8?q?=ED=86=A0=EB=A6=AC=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EC=9C=84?= =?UTF-8?q?=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FriendInviteQueryRepository.java | 16 +++++ .../FriendInviteQueryRepositoryImpl.java | 68 +++++++++++++++++++ .../MemberFriendQueryRepository.java | 12 ---- .../MemberFriendQueryRepositoryImpl.java | 49 ------------- .../service/query/FriendQueryService.java | 6 +- 5 files changed, 88 insertions(+), 63 deletions(-) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java index d8887fb0d..2b4830a7d 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java @@ -1,8 +1,24 @@ package site.timecapsulearchive.core.domain.friend.repository.friend_invite; +import java.time.ZonedDateTime; import java.util.List; +import org.springframework.data.domain.Slice; +import site.timecapsulearchive.core.domain.friend.data.dto.FriendSummaryDto; public interface FriendInviteQueryRepository { void bulkSave(final Long ownerId, final List friendIds); + + + Slice findFriendReceptionInvitesSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ); + + Slice findFriendSendingInvitesSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java index 136441e2d..8407a4c4f 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java @@ -1,5 +1,10 @@ package site.timecapsulearchive.core.domain.friend.repository.friend_invite; +import static site.timecapsulearchive.core.domain.friend.entity.QFriendInvite.friendInvite; +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; @@ -7,15 +12,20 @@ import java.time.ZonedDateTime; import java.util.List; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; +import site.timecapsulearchive.core.domain.friend.data.dto.FriendSummaryDto; @Repository @RequiredArgsConstructor public class FriendInviteQueryRepositoryImpl implements FriendInviteQueryRepository { private final JdbcTemplate jdbcTemplate; + private final JPAQueryFactory jpaQueryFactory; public void bulkSave(final Long ownerId, final List friendIds) { if (friendIds.isEmpty()) { @@ -47,4 +57,62 @@ public int getBatchSize() { } ); } + + public Slice findFriendReceptionInvitesSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ) { + final List friends = jpaQueryFactory + .select( + Projections.constructor( + FriendSummaryDto.class, + friendInvite.owner.id, + friendInvite.owner.profileUrl, + friendInvite.owner.nickname, + friendInvite.createdAt + ) + ) + .from(friendInvite) + .join(friendInvite.owner, member) + .where(friendInvite.friend.id.eq(memberId).and(friendInvite.createdAt.loe(createdAt))) + .limit(size + 1) + .fetch(); + + return makeSlice(size, friends); + } + + private Slice makeSlice(int size, List dtos) { + final boolean hasNext = dtos.size() > size; + if (hasNext) { + dtos.remove(size); + } + + return new SliceImpl<>(dtos, Pageable.ofSize(size), hasNext); + } + + @Override + public Slice findFriendSendingInvitesSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ) { + final List friends = jpaQueryFactory + .select( + Projections.constructor( + FriendSummaryDto.class, + friendInvite.friend.id, + friendInvite.friend.profileUrl, + friendInvite.friend.nickname, + friendInvite.createdAt + ) + ) + .from(friendInvite) + .join(friendInvite.owner, member) + .where(friendInvite.owner.id.eq(memberId).and(friendInvite.createdAt.loe(createdAt))) + .limit(size + 1) + .fetch(); + + return makeSlice(size, friends); + } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepository.java index 545cf6434..de7021d81 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepository.java @@ -18,18 +18,6 @@ Slice findFriendsSlice( final ZonedDateTime createdAt ); - Slice findFriendReceptionInvitesSlice( - final Long memberId, - final int size, - final ZonedDateTime createdAt - ); - - Slice findFriendSendingInvitesSlice( - final Long memberId, - final int size, - final ZonedDateTime createdAt - ); - List findFriendsByPhone( final Long memberId, final List hashes diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java index 2b436f7cd..4e1eaa17f 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java @@ -102,55 +102,6 @@ public Slice findFriendsBeforeGroupInvite( return getFriendSummaryDtos(request.size(), friends); } - public Slice findFriendReceptionInvitesSlice( - final Long memberId, - final int size, - final ZonedDateTime createdAt - ) { - final List friends = jpaQueryFactory - .select( - Projections.constructor( - FriendSummaryDto.class, - friendInvite.owner.id, - friendInvite.owner.profileUrl, - friendInvite.owner.nickname, - friendInvite.createdAt - ) - ) - .from(friendInvite) - .join(friendInvite.owner, member) - .where(friendInvite.friend.id.eq(memberId).and(friendInvite.createdAt.loe(createdAt))) - .limit(size + 1) - .fetch(); - - return getFriendSummaryDtos(size, friends); - } - - @Override - public Slice findFriendSendingInvitesSlice( - final Long memberId, - final int size, - final ZonedDateTime createdAt - ) { - final List friends = jpaQueryFactory - .select( - Projections.constructor( - FriendSummaryDto.class, - friendInvite.friend.id, - friendInvite.friend.profileUrl, - friendInvite.friend.nickname, - friendInvite.createdAt - ) - ) - .from(friendInvite) - .join(friendInvite.owner, member) - .where(friendInvite.owner.id.eq(memberId).and(friendInvite.createdAt.loe(createdAt))) - .limit(size + 1) - .fetch(); - - return getFriendSummaryDtos(size, friends); - } - public List findFriendsByPhone( final Long memberId, final List hashes diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java index 6a179fdc1..956213f12 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java @@ -11,6 +11,7 @@ import site.timecapsulearchive.core.domain.friend.data.dto.SearchFriendSummaryDtoByTag; import site.timecapsulearchive.core.domain.friend.data.request.FriendBeforeGroupInviteRequest; import site.timecapsulearchive.core.domain.friend.exception.FriendNotFoundException; +import site.timecapsulearchive.core.domain.friend.repository.friend_invite.FriendInviteRepository; import site.timecapsulearchive.core.domain.friend.repository.member_friend.MemberFriendRepository; import site.timecapsulearchive.core.global.common.wrapper.ByteArrayWrapper; @@ -20,6 +21,7 @@ public class FriendQueryService { private final MemberFriendRepository memberFriendRepository; + private final FriendInviteRepository friendInviteRepository; public Slice findFriendsSlice( final Long memberId, @@ -39,7 +41,7 @@ public Slice findFriendReceptionInvitesSlice( final int size, final ZonedDateTime createdAt ) { - return memberFriendRepository.findFriendReceptionInvitesSlice(memberId, size, createdAt); + return friendInviteRepository.findFriendReceptionInvitesSlice(memberId, size, createdAt); } public Slice findFriendSendingInvitesSlice( @@ -47,7 +49,7 @@ public Slice findFriendSendingInvitesSlice( final int size, final ZonedDateTime createdAt ) { - return memberFriendRepository.findFriendSendingInvitesSlice(memberId, size, createdAt); + return friendInviteRepository.findFriendSendingInvitesSlice(memberId, size, createdAt); } public List findFriendsByPhone( From 4d904882488b427e8e0008dcee05f48b03832e15 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Sun, 2 Jun 2024 16:00:57 +0900 Subject: [PATCH 5/8] =?UTF-8?q?fix=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../FriendInviteQueryRepositoryTest.java | 207 +++++++++++++++++- .../MemberFriendQueryRepositoryTest.java | 188 +--------------- .../service/FriendQueryServiceTest.java | 6 +- 3 files changed, 211 insertions(+), 190 deletions(-) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java index c4c63562f..7ea22854c 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java @@ -2,17 +2,25 @@ import static org.assertj.core.api.Assertions.assertThat; +import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; import jakarta.persistence.Query; +import java.time.ZoneId; +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.data.domain.Slice; import org.springframework.jdbc.core.JdbcTemplate; 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.FriendInviteFixture; import site.timecapsulearchive.core.common.fixture.domain.MemberFixture; +import site.timecapsulearchive.core.domain.friend.data.dto.FriendSummaryDto; import site.timecapsulearchive.core.domain.friend.entity.FriendInvite; import site.timecapsulearchive.core.domain.friend.repository.friend_invite.FriendInviteQueryRepository; import site.timecapsulearchive.core.domain.friend.repository.friend_invite.FriendInviteQueryRepositoryImpl; @@ -21,39 +29,85 @@ @TestConstructor(autowireMode = AutowireMode.ALL) class FriendInviteQueryRepositoryTest extends RepositoryTest { + private static final int MAX_COUNT = 40; + private static final Long BULK_FRIEND_INVITE_MEMBER_START_ID = 2L; + private static final Long FRIEND_RECEPTION_INVITE_MEMBER_START_ID = + BULK_FRIEND_INVITE_MEMBER_START_ID + MAX_COUNT; + private static final Long FRIEND_SENDING_INVITE_MEMBER_START_ID = + FRIEND_RECEPTION_INVITE_MEMBER_START_ID + MAX_COUNT; + private static final Long NOT_FRIEND_INVITE_START_ID = + FRIEND_SENDING_INVITE_MEMBER_START_ID + MAX_COUNT; + private final FriendInviteQueryRepository friendInviteQueryRepository; private final EntityManager entityManager; private final List friends = new ArrayList<>(); - private Member owner; + private Long bulkOwnerId; + private Long ownerId; + private Long ownerInviteReceptionStartId; + private Long ownerInviteSendingStartId; - FriendInviteQueryRepositoryTest(EntityManager entityManager, JdbcTemplate jdbcTemplate) { + FriendInviteQueryRepositoryTest(EntityManager entityManager, JdbcTemplate jdbcTemplate, + JPAQueryFactory jpaQueryFactory) { this.entityManager = entityManager; - this.friendInviteQueryRepository = new FriendInviteQueryRepositoryImpl(jdbcTemplate); + this.friendInviteQueryRepository = new FriendInviteQueryRepositoryImpl(jdbcTemplate, + jpaQueryFactory); } @BeforeEach void setup() { - owner = MemberFixture.member(0); - entityManager.persist(owner); + // 벌크 저장 시 owner 멤버 데이터 + Member bulkOwner = MemberFixture.member(0); + entityManager.persist(bulkOwner); + bulkOwnerId = bulkOwner.getId(); - friends.addAll(MemberFixture.members(1, 11)); + // 벌크 저장 시 owner 친구 데이터 + friends.addAll(MemberFixture.members(2, BULK_FRIEND_INVITE_MEMBER_START_ID.intValue())); friends.forEach(entityManager::persist); + + // 친구 초대 owner 멤버 데이터 + Member owner = MemberFixture.member(1); + entityManager.persist(owner); + ownerId = owner.getId(); + + // owner에게 친구 요청만 받은 멤버 데이터 + List receptionInviteToOwnerMembers = MemberFixture.members( + FRIEND_RECEPTION_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); + for (Member member : receptionInviteToOwnerMembers) { + entityManager.persist(member); + + FriendInvite receptionInvite = FriendInviteFixture.friendInvite(owner, member); + entityManager.persist(receptionInvite); + } + ownerInviteReceptionStartId = receptionInviteToOwnerMembers.get(0).getId(); + + // owner에게 친구 요청만 보낸 멤버 데이터 + List sendingInviteToOwnerMembers = MemberFixture.members( + FRIEND_SENDING_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); + for (Member member : sendingInviteToOwnerMembers) { + entityManager.persist(member); + + FriendInvite sendingInvite = FriendInviteFixture.friendInvite(member, owner); + entityManager.persist(sendingInvite); + } + ownerInviteSendingStartId = sendingInviteToOwnerMembers.get(0).getId(); + + entityManager.flush(); + entityManager.clear(); } @Test void 대량의_친구_초대를_저장하면_조회하면_친구_초대를_볼_수_있다() { //given - Long ownerId = owner.getId(); List friendIds = friends.stream() .map(Member::getId) .toList(); //when - friendInviteQueryRepository.bulkSave(ownerId, friendIds); + friendInviteQueryRepository.bulkSave(bulkOwnerId, friendIds); //then - List friendInvites = getFriendInvites(entityManager, ownerId); + List friendInvites = getFriendInvites(entityManager, bulkOwnerId); assertThat(friendInvites.size()).isEqualTo(friendIds.size()); } @@ -63,4 +117,139 @@ private List getFriendInvites(EntityManager entityManager, Long ow query.setParameter("ownerId", ownerId); return query.getResultList(); } + + + @ValueSource(ints = {2, 7, 10, 5}) + @ParameterizedTest + void 사용자가_보낸_친구_요청_받은_목록을_조회하면_보낸_친구_요청목록이_나온다(int size) { + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + + Slice slice = friendInviteQueryRepository.findFriendSendingInvitesSlice( + ownerId, + size, + now + ); + + assertThat(slice.getContent()).isNotEmpty(); + assertThat(slice.getContent()).allMatch(dto -> dto.id() >= ownerInviteReceptionStartId + && dto.id() < ownerInviteReceptionStartId + MAX_COUNT); + } + + @Test + void 사용자가_첫_페이지_이후의_친구요청_보낸_목록을_조회하면_다음_페이지의_보낸_친구_요청목록이_나온다() { + //given + int size = 20; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + Slice firstSlice = friendInviteQueryRepository.findFriendSendingInvitesSlice( + ownerId, size, now); + + //when + FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); + Slice nextSlice = friendInviteQueryRepository.findFriendSendingInvitesSlice( + ownerId, size, dto.createdAt()); + + //then + assertThat(nextSlice.getNumberOfElements()).isPositive(); + } + + @Test + void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_보낸_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); + + //when + Slice slice = friendInviteQueryRepository.findFriendSendingInvitesSlice( + ownerId, + size, + now + ); + + //then + assertThat(slice).isEmpty(); + } + + @Test + void 친구_요청을_보내지_않은_사용자가_친구_요청_보낸_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); + + //when + Slice slice = friendInviteQueryRepository.findFriendSendingInvitesSlice( + NOT_FRIEND_INVITE_START_ID, + size, + now + ); + + //then + assertThat(slice).isEmpty(); + } + + @ValueSource(ints = {2, 7, 10, 5}) + @ParameterizedTest + void 사용자가_받은_친구_요청_받은_목록을_조회하면_받은_친구_요청목록이_나온다(int size) { + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + + Slice slice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + ownerId, + size, + now + ); + + assertThat(slice.getContent()).isNotEmpty(); + assertThat(slice.getContent()).allMatch(dto -> dto.id() >= ownerInviteSendingStartId + && dto.id() < ownerInviteSendingStartId + MAX_COUNT); + } + + @Test + void 사용자가_첫_페이지_이후의_친구요청_받은_목록을_조회하면_다음_페이지의_받은_친구_요청목록이_나온다() { + //given + int size = 20; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + Slice firstSlice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + ownerId, size, now); + + //when + FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); + Slice nextSlice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + ownerId, size, dto.createdAt()); + + //then + assertThat(nextSlice.getNumberOfElements()).isPositive(); + } + + @Test + void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_받은_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); + + //when + Slice slice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + ownerId, + size, + now + ); + + //then + assertThat(slice).isEmpty(); + } + + @Test + void 친구_요청을_받지_않은_사용자가_친구_요청_받은_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); + + //when + Slice slice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + NOT_FRIEND_INVITE_START_ID, + size, + now + ); + + //then + assertThat(slice).isEmpty(); + } } \ No newline at end of file diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java index 4c6cf98c0..662d030b5 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java @@ -41,13 +41,11 @@ class MemberFriendQueryRepositoryTest extends RepositoryTest { private static final String PROPAGATION_REQUIRES_NEW = "PROPAGATION_REQUIRES_NEW"; - private static final int MAX_COUNT = 40; + private static final int MAX_COUNT = 10; private static final Long FRIEND_START_ID = 2L; private static final Long NOT_FRIEND_MEMBER_START_ID = FRIEND_START_ID + MAX_COUNT; - private static final Long FRIEND_RECEPTION_INVITE_MEMBER_START_ID = - NOT_FRIEND_MEMBER_START_ID + MAX_COUNT; - private static final Long FRIEND_SENDING_INVITE_MEMBER_START_ID = - FRIEND_RECEPTION_INVITE_MEMBER_START_ID + MAX_COUNT; + private static final Long FRIEND_INVITE_START_ID = + NOT_FRIEND_MEMBER_START_ID + NOT_FRIEND_MEMBER_START_ID; private final MemberFriendQueryRepository memberFriendQueryRepository; @@ -56,8 +54,6 @@ class MemberFriendQueryRepositoryTest extends RepositoryTest { private final List hashedNotFriendPhones = new ArrayList<>(); private Long ownerId; private Long friendId; - private Long ownerInviteSendingStartId; - private Long ownerInviteReceptionStartId; private String friendTag; private String notFriendTag; private String friendInviteTag; @@ -109,28 +105,13 @@ void setup(@Autowired EntityManager entityManager, //owner와 친구가 아닌 데이터 notFriendTag = notFriendMembers.get(0).getTag(); - // owner에게 친구 요청만 받은 멤버 데이터 - List receptionInviteToOwnerMembers = MemberFixture.members( - FRIEND_RECEPTION_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); - for (Member member : receptionInviteToOwnerMembers) { - entityManager.persist(member); + //owner와 친구 초대 관계 멤버 데이터 + Member friendInviteMember = MemberFixture.member(FRIEND_INVITE_START_ID.intValue()); + entityManager.persist(friendInviteMember); - FriendInvite receptionInvite = FriendInviteFixture.friendInvite(owner, member); - entityManager.persist(receptionInvite); - } - friendInviteTag = receptionInviteToOwnerMembers.get(0).getTag(); - ownerInviteReceptionStartId = receptionInviteToOwnerMembers.get(0).getId(); - - // owner에게 친구 요청만 보낸 멤버 데이터 - List sendingInviteToOwnerMembers = MemberFixture.members( - FRIEND_SENDING_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); - for (Member member : sendingInviteToOwnerMembers) { - entityManager.persist(member); - - FriendInvite sendingInvite = FriendInviteFixture.friendInvite(member, owner); - entityManager.persist(sendingInvite); - } - ownerInviteSendingStartId = sendingInviteToOwnerMembers.get(0).getId(); + FriendInvite friendInvite = FriendInviteFixture.friendInvite(owner, friendInviteMember); + entityManager.persist(friendInvite); + friendInviteTag = friendInviteMember.getTag(); }); } @@ -205,23 +186,6 @@ void clear(@Autowired EntityManager entityManager) { assertThat(slice.getContent().size()).isEqualTo(1); } - @Test - void 친구_요청만_보낸_사용자가_친구_목록_조회하면_빈_리스트가_나온다() { - //given - int size = 10; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); - - //when - Slice slice = memberFriendQueryRepository.findFriendsSlice( - FRIEND_RECEPTION_INVITE_MEMBER_START_ID, - size, - now - ); - - //then - assertThat(slice).isEmpty(); - } - @Test void 사용자가_유효하지_않은_시간으로_사용자의_친구_목록_조회하면_빈_리스트가_나온다() { //given @@ -256,140 +220,6 @@ void clear(@Autowired EntityManager entityManager) { assertThat(slice).isEmpty(); } - @ValueSource(ints = {2, 7, 10, 5}) - @ParameterizedTest - void 사용자가_보낸_친구_요청_받은_목록을_조회하면_보낸_친구_요청목록이_나온다(int size) { - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); - - Slice slice = memberFriendQueryRepository.findFriendSendingInvitesSlice( - ownerId, - size, - now - ); - - assertThat(slice.getContent()).isNotEmpty(); - assertThat(slice.getContent()).allMatch(dto -> dto.id() >= ownerInviteReceptionStartId - && dto.id() < ownerInviteReceptionStartId + MAX_COUNT); - } - - @Test - void 사용자가_첫_페이지_이후의_친구요청_보낸_목록을_조회하면_다음_페이지의_보낸_친구_요청목록이_나온다() { - //given - int size = 20; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); - Slice firstSlice = memberFriendQueryRepository.findFriendSendingInvitesSlice( - ownerId, size, now); - - //when - FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); - Slice nextSlice = memberFriendQueryRepository.findFriendSendingInvitesSlice( - ownerId, size, dto.createdAt()); - - //then - assertThat(nextSlice.getNumberOfElements()).isPositive(); - } - - @Test - void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_보낸_목록_조회하면_빈_리스트가_나온다() { - //given - int size = 10; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); - - //when - Slice slice = memberFriendQueryRepository.findFriendSendingInvitesSlice( - ownerId, - size, - now - ); - - //then - assertThat(slice).isEmpty(); - } - - @Test - void 친구_요청을_보내지_않은_사용자가_친구_요청_보낸_목록_조회하면_빈_리스트가_나온다() { - //given - int size = 10; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); - - //when - Slice slice = memberFriendQueryRepository.findFriendSendingInvitesSlice( - NOT_FRIEND_MEMBER_START_ID, - size, - now - ); - - //then - assertThat(slice).isEmpty(); - } - - @ValueSource(ints = {2, 7, 10, 5}) - @ParameterizedTest - void 사용자가_받은_친구_요청_받은_목록을_조회하면_받은_친구_요청목록이_나온다(int size) { - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); - - Slice slice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( - ownerId, - size, - now - ); - - assertThat(slice.getContent()).isNotEmpty(); - assertThat(slice.getContent()).allMatch(dto -> dto.id() >= ownerInviteSendingStartId - && dto.id() < ownerInviteSendingStartId + MAX_COUNT); - } - - @Test - void 사용자가_첫_페이지_이후의_친구요청_받은_목록을_조회하면_다음_페이지의_받은_친구_요청목록이_나온다() { - //given - int size = 20; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); - Slice firstSlice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( - ownerId, size, now); - - //when - FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); - Slice nextSlice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( - ownerId, size, dto.createdAt()); - - //then - assertThat(nextSlice.getNumberOfElements()).isPositive(); - } - - @Test - void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_받은_목록_조회하면_빈_리스트가_나온다() { - //given - int size = 10; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); - - //when - Slice slice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( - ownerId, - size, - now - ); - - //then - assertThat(slice).isEmpty(); - } - - @Test - void 친구_요청을_받지_않은_사용자가_친구_요청_받은_목록_조회하면_빈_리스트가_나온다() { - //given - int size = 10; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); - - //when - Slice slice = memberFriendQueryRepository.findFriendReceptionInvitesSlice( - NOT_FRIEND_MEMBER_START_ID, - size, - now - ); - - //then - assertThat(slice).isEmpty(); - } - @Test void 사용자가_앱_사용자의_전화번호가_아닌_경우_주소록_기반_사용자_리스트_조회하면_빈_리스트가_나온다() { //given diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/service/FriendQueryServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/service/FriendQueryServiceTest.java index 6c940d657..97e83bb9f 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/service/FriendQueryServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/service/FriendQueryServiceTest.java @@ -18,8 +18,8 @@ import site.timecapsulearchive.core.common.fixture.dto.FriendDtoFixture; import site.timecapsulearchive.core.domain.friend.data.dto.SearchFriendSummaryDto; import site.timecapsulearchive.core.domain.friend.data.dto.SearchFriendSummaryDtoByTag; -import site.timecapsulearchive.core.domain.friend.data.response.SearchTagFriendSummaryResponse; import site.timecapsulearchive.core.domain.friend.exception.FriendNotFoundException; +import site.timecapsulearchive.core.domain.friend.repository.friend_invite.FriendInviteRepository; import site.timecapsulearchive.core.domain.friend.repository.member_friend.MemberFriendRepository; import site.timecapsulearchive.core.domain.friend.service.query.FriendQueryService; import site.timecapsulearchive.core.global.common.wrapper.ByteArrayWrapper; @@ -28,9 +28,11 @@ class FriendQueryServiceTest { private final MemberFriendRepository memberFriendRepository = mock( MemberFriendRepository.class); + private final FriendInviteRepository friendInviteRepository = mock( + FriendInviteRepository.class); private final FriendQueryService friendQueryService = new FriendQueryService( - memberFriendRepository); + memberFriendRepository, friendInviteRepository); @Test void 사용자는_주소록_기반_핸드폰_번호로_Ahchive_사용자_리스트를_조회_할_수_있다() { From 01c0b9c1a800b29079a66df105c52dbaefd6d4a5 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Mon, 3 Jun 2024 19:05:22 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix=20:=20loe=20->=20lt=EB=A1=9C=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 - 페이징 시 시간 조건을 loe에서 lt로 수정 --- .../friend_invite/FriendInviteQueryRepositoryImpl.java | 4 ++-- .../member_friend/MemberFriendQueryRepositoryImpl.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java index 8407a4c4f..2bd2f9261 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java @@ -75,7 +75,7 @@ public Slice findFriendReceptionInvitesSlice( ) .from(friendInvite) .join(friendInvite.owner, member) - .where(friendInvite.friend.id.eq(memberId).and(friendInvite.createdAt.loe(createdAt))) + .where(friendInvite.friend.id.eq(memberId).and(friendInvite.createdAt.lt(createdAt))) .limit(size + 1) .fetch(); @@ -109,7 +109,7 @@ public Slice findFriendSendingInvitesSlice( ) .from(friendInvite) .join(friendInvite.owner, member) - .where(friendInvite.owner.id.eq(memberId).and(friendInvite.createdAt.loe(createdAt))) + .where(friendInvite.owner.id.eq(memberId).and(friendInvite.createdAt.lt(createdAt))) .limit(size + 1) .fetch(); diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java index 4e1eaa17f..63cb8d93f 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/member_friend/MemberFriendQueryRepositoryImpl.java @@ -56,7 +56,7 @@ public Slice findFriendsSlice( .from(memberFriend) .innerJoin(member).on(memberFriend.owner.id.eq(member.id)) .innerJoin(member).on(memberFriend.friend.id.eq(member.id)) - .where(memberFriend.owner.id.eq(memberId).and(memberFriend.createdAt.loe(createdAt))) + .where(memberFriend.owner.id.eq(memberId).and(memberFriend.createdAt.lt(createdAt))) .limit(size + 1) .fetch(); @@ -89,7 +89,7 @@ public Slice findFriendsBeforeGroupInvite( .innerJoin(member).on(memberFriend.owner.id.eq(member.id)) .innerJoin(member).on(memberFriend.friend.id.eq(member.id)) .where(memberFriend.owner.id.eq(request.memberId()) - .and(memberFriend.createdAt.loe(request.createdAt())) + .and(memberFriend.createdAt.lt(request.createdAt())) .and(memberFriend.friend.id.notIn( select(memberGroup.member.id) .from(memberGroup) From e0d850eb3b416c73c90f6d919d21a0eb77a15652 Mon Sep 17 00:00:00 2001 From: hong seokho Date: Mon, 3 Jun 2024 19:13:25 +0900 Subject: [PATCH 7/8] =?UTF-8?q?fix=20:=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EC=B6=A9=EB=8F=8C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 시간 기반 페이징의 로직 상 오류로 테스트 실패 - 아이디 기반 커서 페이징으로 변경해야 함 --- .../friend/repository/FriendInviteQueryRepositoryTest.java | 4 ++-- .../friend/repository/MemberFriendQueryRepositoryTest.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java index 7ea22854c..bba643e30 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java @@ -146,7 +146,7 @@ private List getFriendInvites(EntityManager entityManager, Long ow //when FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); Slice nextSlice = friendInviteQueryRepository.findFriendSendingInvitesSlice( - ownerId, size, dto.createdAt()); + ownerId, size, dto.createdAt().plusSeconds(1L)); //then assertThat(nextSlice.getNumberOfElements()).isPositive(); @@ -213,7 +213,7 @@ private List getFriendInvites(EntityManager entityManager, Long ow //when FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); Slice nextSlice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( - ownerId, size, dto.createdAt()); + ownerId, size, dto.createdAt().plusSeconds(1L)); //then assertThat(nextSlice.getNumberOfElements()).isPositive(); diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java index 662d030b5..86842d9c4 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/MemberFriendQueryRepositoryTest.java @@ -164,7 +164,7 @@ void clear(@Autowired EntityManager entityManager) { Slice nextSlice = memberFriendQueryRepository.findFriendsSlice( ownerId, size, - dto.createdAt() + dto.createdAt().plusSeconds(1L) ); assertThat(nextSlice.getNumberOfElements()).isPositive(); From c0038d472ce835cef4ecbc7cf7488edb501dea5d Mon Sep 17 00:00:00 2001 From: hong seokho Date: Tue, 4 Jun 2024 22:54:13 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix=20:=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20SliceUtil?= =?UTF-8?q?=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../friend/api/query/FriendQueryApi.java | 2 +- .../api/query/FriendQueryApiController.java | 10 +++--- .../FriendInviteQueryRepository.java | 2 +- .../FriendInviteQueryRepositoryImpl.java | 16 +++------- .../service/query/FriendQueryService.java | 4 +-- .../core/global/util/SliceUtil.java | 22 +++++++++++++ .../FriendInviteQueryRepositoryTest.java | 32 +++++++++---------- 7 files changed, 51 insertions(+), 37 deletions(-) create mode 100644 backend/core/src/main/java/site/timecapsulearchive/core/global/util/SliceUtil.java diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApi.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApi.java index bf4fa86b9..14cd4c0d6 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApi.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApi.java @@ -79,7 +79,7 @@ ResponseEntity> findFriendsBeforeGroupInvite( description = "ok" ) }) - ResponseEntity> findFriendReceptionInvites( + ResponseEntity> findFriendReceivingInvites( Long memberId, @Parameter(in = ParameterIn.QUERY, description = "페이지 크기", required = true) diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApiController.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApiController.java index 46077f0c9..f963efba8 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApiController.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/api/query/FriendQueryApiController.java @@ -76,23 +76,23 @@ public ResponseEntity> findFriendsBeforeGroupInvit } @GetMapping( - value = "/reception-invites", + value = "/receiving-invites", produces = {"application/json"} ) @Override - public ResponseEntity> findFriendReceptionInvites( + public ResponseEntity> findFriendReceivingInvites( @AuthenticationPrincipal final Long memberId, @RequestParam(defaultValue = "20", value = "size") final int size, @RequestParam(value = "created_at") final ZonedDateTime createdAt ) { - final Slice friendReceptionInvitesSlice = friendQueryService.findFriendReceptionInvitesSlice( + final Slice friendReceivingInvitesSlice = friendQueryService.findFriendReceivingInvitesSlice( memberId, size, createdAt); return ResponseEntity.ok( ApiSpec.success( SuccessCode.SUCCESS, - FriendsSliceResponse.createOf(friendReceptionInvitesSlice.getContent(), - friendReceptionInvitesSlice.hasNext()) + FriendsSliceResponse.createOf(friendReceivingInvitesSlice.getContent(), + friendReceivingInvitesSlice.hasNext()) ) ); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java index 2b4830a7d..40ba418cc 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java @@ -10,7 +10,7 @@ public interface FriendInviteQueryRepository { void bulkSave(final Long ownerId, final List friendIds); - Slice findFriendReceptionInvitesSlice( + Slice findFriendReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java index 2bd2f9261..ae6aeceef 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepositoryImpl.java @@ -19,6 +19,7 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import site.timecapsulearchive.core.domain.friend.data.dto.FriendSummaryDto; +import site.timecapsulearchive.core.global.util.SliceUtil; @Repository @RequiredArgsConstructor @@ -58,7 +59,7 @@ public int getBatchSize() { ); } - public Slice findFriendReceptionInvitesSlice( + public Slice findFriendReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt @@ -79,16 +80,7 @@ public Slice findFriendReceptionInvitesSlice( .limit(size + 1) .fetch(); - return makeSlice(size, friends); - } - - private Slice makeSlice(int size, List dtos) { - final boolean hasNext = dtos.size() > size; - if (hasNext) { - dtos.remove(size); - } - - return new SliceImpl<>(dtos, Pageable.ofSize(size), hasNext); + return SliceUtil.makeSlice(size, friends); } @Override @@ -113,6 +105,6 @@ public Slice findFriendSendingInvitesSlice( .limit(size + 1) .fetch(); - return makeSlice(size, friends); + return SliceUtil.makeSlice(size, friends); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java index 956213f12..2e0ecc5e8 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/service/query/FriendQueryService.java @@ -36,12 +36,12 @@ public Slice findFriendsBeforeGroupInviteSlice( return memberFriendRepository.findFriendsBeforeGroupInvite(request); } - public Slice findFriendReceptionInvitesSlice( + public Slice findFriendReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt ) { - return friendInviteRepository.findFriendReceptionInvitesSlice(memberId, size, createdAt); + return friendInviteRepository.findFriendReceivingInvitesSlice(memberId, size, createdAt); } public Slice findFriendSendingInvitesSlice( diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/global/util/SliceUtil.java b/backend/core/src/main/java/site/timecapsulearchive/core/global/util/SliceUtil.java new file mode 100644 index 000000000..be393648a --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/global/util/SliceUtil.java @@ -0,0 +1,22 @@ +package site.timecapsulearchive.core.global.util; + +import java.util.List; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import org.springframework.data.domain.SliceImpl; + +public final class SliceUtil { + + private SliceUtil() { + + } + + public static Slice makeSlice(final int size, final List dtos) { + final boolean hasNext = dtos.size() > size; + if (hasNext) { + dtos.remove(size); + } + + return new SliceImpl<>(dtos, Pageable.ofSize(size), hasNext); + } +} diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java index bba643e30..8233b0761 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/friend/repository/FriendInviteQueryRepositoryTest.java @@ -31,10 +31,10 @@ class FriendInviteQueryRepositoryTest extends RepositoryTest { private static final int MAX_COUNT = 40; private static final Long BULK_FRIEND_INVITE_MEMBER_START_ID = 2L; - private static final Long FRIEND_RECEPTION_INVITE_MEMBER_START_ID = + private static final Long FRIEND_RECEIVING_INVITE_MEMBER_START_ID = BULK_FRIEND_INVITE_MEMBER_START_ID + MAX_COUNT; private static final Long FRIEND_SENDING_INVITE_MEMBER_START_ID = - FRIEND_RECEPTION_INVITE_MEMBER_START_ID + MAX_COUNT; + FRIEND_RECEIVING_INVITE_MEMBER_START_ID + MAX_COUNT; private static final Long NOT_FRIEND_INVITE_START_ID = FRIEND_SENDING_INVITE_MEMBER_START_ID + MAX_COUNT; @@ -44,7 +44,7 @@ class FriendInviteQueryRepositoryTest extends RepositoryTest { private Long bulkOwnerId; private Long ownerId; - private Long ownerInviteReceptionStartId; + private Long ownerInviteReceivingStartId; private Long ownerInviteSendingStartId; FriendInviteQueryRepositoryTest(EntityManager entityManager, JdbcTemplate jdbcTemplate, @@ -71,15 +71,15 @@ void setup() { ownerId = owner.getId(); // owner에게 친구 요청만 받은 멤버 데이터 - List receptionInviteToOwnerMembers = MemberFixture.members( - FRIEND_RECEPTION_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); - for (Member member : receptionInviteToOwnerMembers) { + List receivingInviteToOwnerMembers = MemberFixture.members( + FRIEND_RECEIVING_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); + for (Member member : receivingInviteToOwnerMembers) { entityManager.persist(member); - FriendInvite receptionInvite = FriendInviteFixture.friendInvite(owner, member); - entityManager.persist(receptionInvite); + FriendInvite receivingInvite = FriendInviteFixture.friendInvite(owner, member); + entityManager.persist(receivingInvite); } - ownerInviteReceptionStartId = receptionInviteToOwnerMembers.get(0).getId(); + ownerInviteReceivingStartId = receivingInviteToOwnerMembers.get(0).getId(); // owner에게 친구 요청만 보낸 멤버 데이터 List sendingInviteToOwnerMembers = MemberFixture.members( @@ -131,8 +131,8 @@ private List getFriendInvites(EntityManager entityManager, Long ow ); assertThat(slice.getContent()).isNotEmpty(); - assertThat(slice.getContent()).allMatch(dto -> dto.id() >= ownerInviteReceptionStartId - && dto.id() < ownerInviteReceptionStartId + MAX_COUNT); + assertThat(slice.getContent()).allMatch(dto -> dto.id() >= ownerInviteReceivingStartId + && dto.id() < ownerInviteReceivingStartId + MAX_COUNT); } @Test @@ -191,7 +191,7 @@ private List getFriendInvites(EntityManager entityManager, Long ow void 사용자가_받은_친구_요청_받은_목록을_조회하면_받은_친구_요청목록이_나온다(int size) { ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); - Slice slice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + Slice slice = friendInviteQueryRepository.findFriendReceivingInvitesSlice( ownerId, size, now @@ -207,12 +207,12 @@ private List getFriendInvites(EntityManager entityManager, Long ow //given int size = 20; ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); - Slice firstSlice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + Slice firstSlice = friendInviteQueryRepository.findFriendReceivingInvitesSlice( ownerId, size, now); //when FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); - Slice nextSlice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + Slice nextSlice = friendInviteQueryRepository.findFriendReceivingInvitesSlice( ownerId, size, dto.createdAt().plusSeconds(1L)); //then @@ -226,7 +226,7 @@ private List getFriendInvites(EntityManager entityManager, Long ow ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); //when - Slice slice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + Slice slice = friendInviteQueryRepository.findFriendReceivingInvitesSlice( ownerId, size, now @@ -243,7 +243,7 @@ private List getFriendInvites(EntityManager entityManager, Long ow ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); //when - Slice slice = friendInviteQueryRepository.findFriendReceptionInvitesSlice( + Slice slice = friendInviteQueryRepository.findFriendReceivingInvitesSlice( NOT_FRIEND_INVITE_START_ID, size, now