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 ad85af51d..7fe063959 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> findFriendReceivingInvites( + 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..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 @@ -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 = "/receiving-invites", produces = {"application/json"} ) @Override - public ResponseEntity> findFriendRequests( + public ResponseEntity> findFriendReceivingInvites( @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 friendReceivingInvitesSlice = friendQueryService.findFriendReceivingInvitesSlice( memberId, size, createdAt); return ResponseEntity.ok( ApiSpec.success( SuccessCode.SUCCESS, - FriendRequestsSliceResponse.createOf(friendRequestsSlice.getContent(), - friendRequestsSlice.hasNext()) + FriendsSliceResponse.createOf(friendReceivingInvitesSlice.getContent(), + friendReceivingInvitesSlice.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/friend_invite/FriendInviteQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/friend/repository/friend_invite/FriendInviteQueryRepository.java index d8887fb0d..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 @@ -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 findFriendReceivingInvitesSlice( + 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..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 @@ -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,21 @@ 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; +import site.timecapsulearchive.core.global.util.SliceUtil; @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 +58,53 @@ public int getBatchSize() { } ); } + + public Slice findFriendReceivingInvitesSlice( + 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.lt(createdAt))) + .limit(size + 1) + .fetch(); + + return SliceUtil.makeSlice(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.lt(createdAt))) + .limit(size + 1) + .fetch(); + + return SliceUtil.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 8e8c32667..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,12 +18,6 @@ Slice findFriendsSlice( final ZonedDateTime createdAt ); - Slice findFriendRequestsSlice( - 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 7bc29fdd2..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 @@ -102,30 +102,6 @@ public Slice findFriendsBeforeGroupInvite( return getFriendSummaryDtos(request.size(), friends); } - public Slice findFriendRequestsSlice( - 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.lt(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 d34230f0a..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 @@ -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, @@ -34,12 +36,20 @@ public Slice findFriendsBeforeGroupInviteSlice( return memberFriendRepository.findFriendsBeforeGroupInvite(request); } - public Slice findFriendRequestsSlice( + public Slice findFriendReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt ) { - return memberFriendRepository.findFriendRequestsSlice(memberId, size, createdAt); + return friendInviteRepository.findFriendReceivingInvitesSlice(memberId, size, createdAt); + } + + public Slice findFriendSendingInvitesSlice( + final Long memberId, + final int size, + final ZonedDateTime createdAt + ) { + return friendInviteRepository.findFriendSendingInvitesSlice(memberId, size, createdAt); } public List findFriendsByPhone( diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/command/GroupCommandService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/command/GroupCommandService.java index 84571407a..423288cd9 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/command/GroupCommandService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/group/service/command/GroupCommandService.java @@ -18,8 +18,8 @@ import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.error.ErrorCode; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; import site.timecapsulearchive.core.infra.s3.manager.S3ObjectManager; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApi.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApi.java index fcd1a54eb..9d4efaebc 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApi.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApi.java @@ -9,15 +9,16 @@ import java.time.ZonedDateTime; import org.springframework.http.ResponseEntity; import site.timecapsulearchive.core.domain.group.data.response.GroupMemberInfosResponse; -import site.timecapsulearchive.core.domain.member_group.data.response.GroupInviteSummaryResponses; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupReceivingInvitesSliceResponse; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupSendingInvitesResponse; import site.timecapsulearchive.core.global.common.response.ApiSpec; public interface MemberGroupQueryApi { @Operation( - summary = "그룹 요청 목록 조회", - description = "사용자애게 그룹 초대 요청이 온 그룹 목록을 조회한다.", + summary = "그룹 요청 받은 목록 조회", + description = "사용자에게 그룹 초대 요청이 온 모든 그룹 목록을 조회한다.", security = {@SecurityRequirement(name = "user_token")}, tags = {"member group"} ) @@ -27,7 +28,7 @@ public interface MemberGroupQueryApi { description = "ok" ) }) - ResponseEntity> findGroupInvites( + ResponseEntity> findGroupReceivingInvites( Long memberId, @Parameter(in = ParameterIn.QUERY, description = "페이지 크기", required = true) @@ -56,4 +57,22 @@ ResponseEntity> findGroupMemberInfos( Long groupId ); + @Operation( + summary = "그룹 요청 보낸 목록 조회", + description = "그룹장이 그룹 별로 그룹 초대 요청을 보낸 사용자 목록을 조회한다. 최대 30개가 반환된다.", + security = {@SecurityRequirement(name = "user_token")}, + tags = {"member group"} + ) + @ApiResponses(value = { + @ApiResponse( + responseCode = "200", + description = "ok" + ) + }) + ResponseEntity> findGroupSendingInvites( + Long memberId, + + @Parameter(in = ParameterIn.PATH, description = "그룹 아이디", required = true) + Long groupId + ); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApiController.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApiController.java index a8b1c4325..ba7eb7371 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApiController.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/api/query/MemberGroupQueryApiController.java @@ -14,7 +14,9 @@ import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberDto; import site.timecapsulearchive.core.domain.group.data.response.GroupMemberInfosResponse; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; -import site.timecapsulearchive.core.domain.member_group.data.response.GroupInviteSummaryResponses; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupReceivingInvitesSliceResponse; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupSendingInvitesResponse; import site.timecapsulearchive.core.domain.member_group.service.MemberGroupQueryService; import site.timecapsulearchive.core.global.common.response.ApiSpec; import site.timecapsulearchive.core.global.common.response.SuccessCode; @@ -30,24 +32,24 @@ public class MemberGroupQueryApiController implements MemberGroupQueryApi { @GetMapping( - value = "/invites", + value = "/receiving-invites", produces = {"application/json"} ) @Override - public ResponseEntity> findGroupInvites( + public ResponseEntity> findGroupReceivingInvites( @AuthenticationPrincipal final Long memberId, @RequestParam(defaultValue = "20", value = "size") final int size, @RequestParam(value = "created_at") final ZonedDateTime createdAt ) { - final Slice groupInviteSummaryDtos = memberGroupQueryService.findGroupInvites( + final Slice groupReceivingInvitesSlice = memberGroupQueryService.findGroupReceivingInvitesSlice( memberId, size, createdAt); return ResponseEntity.ok( ApiSpec.success( SuccessCode.SUCCESS, - GroupInviteSummaryResponses.createOf( - groupInviteSummaryDtos.getContent(), - groupInviteSummaryDtos.hasNext(), + GroupReceivingInvitesSliceResponse.createOf( + groupReceivingInvitesSlice.getContent(), + groupReceivingInvitesSlice.hasNext(), s3PreSignedUrlManager::getS3PreSignedUrlForGet ) ) @@ -77,4 +79,23 @@ public ResponseEntity> findGroupMemberInfos( ); } + @GetMapping( + value = "/{group_id}/sending-invites", + produces = {"application/json"} + ) + @Override + public ResponseEntity> findGroupSendingInvites( + @AuthenticationPrincipal final Long memberId, + @PathVariable(value = "group_id") final Long groupId + ) { + List groupSendingInvites = memberGroupQueryService.findGroupSendingInvites( + memberId, groupId); + + return ResponseEntity.ok( + ApiSpec.success( + SuccessCode.SUCCESS, + GroupSendingInvitesResponse.createOf(groupSendingInvites) + ) + ); + } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupInviteSummaryDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupInviteSummaryDto.java index 140f58ec7..a5fb7fb54 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupInviteSummaryDto.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupInviteSummaryDto.java @@ -3,7 +3,7 @@ import java.time.ZonedDateTime; import java.util.function.Function; import lombok.Builder; -import site.timecapsulearchive.core.domain.member_group.data.response.GroupInviteSummaryResponse; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupReceivingInviteSummaryResponse; @Builder public record GroupInviteSummaryDto( @@ -12,19 +12,19 @@ public record GroupInviteSummaryDto( String groupName, String groupProfileUrl, String description, - ZonedDateTime createdAt, + ZonedDateTime groupReceivingInviteTime, String groupOwnerName ) { - public GroupInviteSummaryResponse toResponse( + public GroupReceivingInviteSummaryResponse toResponse( final Function preSignedUrlFunction ) { - return GroupInviteSummaryResponse.builder() + return GroupReceivingInviteSummaryResponse.builder() .groupId(groupId) .groupName(groupName) .groupProfileUrl(preSignedUrlFunction.apply(groupProfileUrl)) .description(description) - .createdAt(createdAt) + .groupReceivingInviteTime(groupReceivingInviteTime) .groupOwnerName(groupOwnerName) .build(); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInviteMemberDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInviteMemberDto.java new file mode 100644 index 000000000..2fcb0f82b --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInviteMemberDto.java @@ -0,0 +1,22 @@ +package site.timecapsulearchive.core.domain.member_group.data.dto; + + +import java.time.ZonedDateTime; +import site.timecapsulearchive.core.domain.member_group.data.response.GroupSendingInviteMemberResponse; + +public record GroupSendingInviteMemberDto( + Long id, + String nickname, + String profileUrl, + ZonedDateTime sendingInvitesCreatedAt +) { + + public GroupSendingInviteMemberResponse toResponse() { + return GroupSendingInviteMemberResponse.builder() + .id(id) + .nickname(nickname) + .profileUrl(profileUrl) + .sendingInvitesCreatedAt(sendingInvitesCreatedAt) + .build(); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInvitesRequestDto.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInvitesRequestDto.java new file mode 100644 index 000000000..73138d8d5 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/dto/GroupSendingInvitesRequestDto.java @@ -0,0 +1,20 @@ +package site.timecapsulearchive.core.domain.member_group.data.dto; + +import java.time.ZonedDateTime; + +public record GroupSendingInvitesRequestDto( + Long memberId, + Long groupId, + int size, + ZonedDateTime createdAt +) { + + public static GroupSendingInvitesRequestDto create( + final Long memberId, + final Long groupId, + final int size, + final ZonedDateTime createdAt + ) { + return new GroupSendingInvitesRequestDto(memberId, groupId, size, createdAt); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInviteSummaryResponse.java similarity index 64% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponse.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInviteSummaryResponse.java index 77acf1acf..13d154fff 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponse.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInviteSummaryResponse.java @@ -7,7 +7,7 @@ @Builder @Schema(description = "초대온 그룹 요약 정보") -public record GroupInviteSummaryResponse( +public record GroupReceivingInviteSummaryResponse( @Schema(description = "그룹 아이디") Long groupId, @@ -21,16 +21,17 @@ public record GroupInviteSummaryResponse( @Schema(description = "그룹 설명") String description, - @Schema(description = "그룹 생성일") - ZonedDateTime createdAt, + @Schema(description = "그룹 초대 시간") + ZonedDateTime groupReceivingInviteTime, @Schema(description = "그룹장") String groupOwnerName ) { - public GroupInviteSummaryResponse { - if (createdAt != null) { - createdAt = createdAt.withZoneSameInstant(ResponseMappingConstant.ZONE_ID); + public GroupReceivingInviteSummaryResponse { + if (groupReceivingInviteTime != null) { + groupReceivingInviteTime = groupReceivingInviteTime.withZoneSameInstant( + ResponseMappingConstant.ZONE_ID); } } } \ No newline at end of file diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponses.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInvitesSliceResponse.java similarity index 62% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponses.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInvitesSliceResponse.java index 4dd508058..815b84658 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupInviteSummaryResponses.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupReceivingInvitesSliceResponse.java @@ -5,22 +5,23 @@ import java.util.function.Function; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; -public record GroupInviteSummaryResponses( +public record GroupReceivingInvitesSliceResponse( @Schema(description = "초대 온 그룹 요약 정보 리스트") - List responses, + List responses, @Schema(description = "다음 페이지 유무") Boolean hasNext ) { - public static GroupInviteSummaryResponses createOf( + public static GroupReceivingInvitesSliceResponse createOf( final List dtos, final boolean hasNext, final Function preSignedUrlFunction ) { - List groupInviteSummaryResponses = dtos.stream() + List groupReceivingInviteSummaryResponse = dtos.stream() .map(dto -> dto.toResponse(preSignedUrlFunction)).toList(); - return new GroupInviteSummaryResponses(groupInviteSummaryResponses, hasNext); + return new GroupReceivingInvitesSliceResponse(groupReceivingInviteSummaryResponse, + hasNext); } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInviteMemberResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInviteMemberResponse.java new file mode 100644 index 000000000..b4193f30f --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInviteMemberResponse.java @@ -0,0 +1,19 @@ +package site.timecapsulearchive.core.domain.member_group.data.response; + +import java.time.ZonedDateTime; +import lombok.Builder; +import site.timecapsulearchive.core.global.common.response.ResponseMappingConstant; + +@Builder +public record GroupSendingInviteMemberResponse( + Long id, + String nickname, + String profileUrl, + ZonedDateTime sendingInvitesCreatedAt +) { + public GroupSendingInviteMemberResponse { + if (sendingInvitesCreatedAt != null) { + sendingInvitesCreatedAt = sendingInvitesCreatedAt.withZoneSameInstant(ResponseMappingConstant.ZONE_ID); + } + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInvitesResponse.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInvitesResponse.java new file mode 100644 index 000000000..4be590970 --- /dev/null +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/data/response/GroupSendingInvitesResponse.java @@ -0,0 +1,23 @@ +package site.timecapsulearchive.core.domain.member_group.data.response; + +import io.swagger.v3.oas.annotations.media.Schema; +import java.util.List; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; + +@Schema(description = "그룹 초대 보낸 목록") +public record GroupSendingInvitesResponse( + + @Schema(description = "초대 보낸 그룹원 정보 리스트") + List responses +) { + + public static GroupSendingInvitesResponse createOf( + final List groupSendingInviteMemberDtos + ) { + List groupSendingInviteMemberResponses = groupSendingInviteMemberDtos.stream() + .map(GroupSendingInviteMemberDto::toResponse) + .toList(); + + return new GroupSendingInvitesResponse(groupSendingInviteMemberResponses); + } +} diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepository.java similarity index 65% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepository.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepository.java index 7d1725f84..c9c5c3166 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepository.java @@ -1,9 +1,10 @@ -package site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository; +package site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository; import java.time.ZonedDateTime; import java.util.List; import org.springframework.data.domain.Slice; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; public interface GroupInviteQueryRepository { @@ -11,9 +12,14 @@ public interface GroupInviteQueryRepository { List findGroupInviteIdsByGroupIdAndGroupOwnerId(final Long groupId, final Long memberId); - Slice findGroupInvitesSummary( + Slice findGroupReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt ); + + List findGroupSendingInvites( + final Long memberId, + final Long groupId + ); } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepositoryImpl.java similarity index 74% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepositoryImpl.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepositoryImpl.java index ca2e6566b..7f2b33ec6 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteQueryRepositoryImpl.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository; +package site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository; import static site.timecapsulearchive.core.domain.group.entity.QGroup.group; @@ -21,6 +21,8 @@ import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; +import site.timecapsulearchive.core.global.util.SliceUtil; @Repository @RequiredArgsConstructor @@ -72,7 +74,7 @@ public List findGroupInviteIdsByGroupIdAndGroupOwnerId( } @Override - public Slice findGroupInvitesSummary( + public Slice findGroupReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt @@ -85,24 +87,38 @@ public Slice findGroupInvitesSummary( group.groupName, group.groupProfileUrl, group.groupDescription, - group.createdAt, + groupInvite.createdAt, member.nickname ) - ) .from(groupInvite) .join(groupInvite.group, group) - .join(groupInvite.groupOwner, member).on(groupInvite.groupMember.id.eq(memberId)) - .where(groupInvite.createdAt.lt(createdAt)) + .join(groupInvite.groupOwner, member) + .where(groupInvite.groupMember.id.eq(memberId).and(groupInvite.createdAt.lt(createdAt))) .limit(size + 1) .fetch(); - final boolean hasNext = groupInviteSummaryDtos.size() > size; - if (hasNext) { - groupInviteSummaryDtos.remove(size); - } - - return new SliceImpl<>(groupInviteSummaryDtos, Pageable.ofSize(size), hasNext); + return SliceUtil.makeSlice(size, groupInviteSummaryDtos); } + public List findGroupSendingInvites( + final Long memberId, + final Long groupId + ) { + return jpaQueryFactory + .select( + Projections.constructor( + GroupSendingInviteMemberDto.class, + member.id, + member.nickname, + member.profileUrl, + groupInvite.createdAt + ) + ) + .from(groupInvite) + .join(groupInvite.groupMember, member) + .where(groupInvite.group.id.eq(groupId) + .and(groupInvite.groupOwner.id.eq(memberId))) + .fetch(); + } } diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteRepository.java similarity index 97% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteRepository.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteRepository.java index 009600258..b882c940d 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/groupInviteRepository/GroupInviteRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/group_invite_repository/GroupInviteRepository.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository; +package site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository; import java.util.List; import org.springframework.data.jpa.repository.Modifying; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java similarity index 96% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepository.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java index e44701cb2..f664cc0cc 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepository.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository; +package site.timecapsulearchive.core.domain.member_group.repository.member_group_repository; import java.util.List; import java.util.Optional; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepositoryImpl.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java similarity index 99% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepositoryImpl.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java index 4251ae4ef..9eafc40a2 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupQueryRepositoryImpl.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupQueryRepositoryImpl.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository; +package site.timecapsulearchive.core.domain.member_group.repository.member_group_repository; import static site.timecapsulearchive.core.domain.group.entity.QGroup.group; import static site.timecapsulearchive.core.domain.member.entity.QMember.member; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupRepository.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupRepository.java similarity index 95% rename from backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupRepository.java rename to backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupRepository.java index e5970ae39..39393cb7b 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/memberGroupRepository/MemberGroupRepository.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/repository/member_group_repository/MemberGroupRepository.java @@ -1,4 +1,4 @@ -package site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository; +package site.timecapsulearchive.core.domain.member_group.repository.member_group_repository; import java.util.List; import java.util.Optional; diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandService.java index 5f9e3bbc1..35dc7b94c 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandService.java @@ -20,8 +20,8 @@ import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupKickDuplicatedIdException; import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.config.redis.RedissonLock; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; @@ -96,7 +96,8 @@ public GroupAcceptNotificationDto acceptGroupInvite(final Long memberId, final L return new GroupAcceptNotificationDto(groupMember.getNickname(), groupOwnerId); } - private void deleteGroupInvite(final Long memberId, final Long groupId, final Long groupOwnerId) { + private void deleteGroupInvite(final Long memberId, final Long groupId, + final Long groupOwnerId) { final int isDenyRequest = groupInviteRepository.deleteGroupInviteByGroupIdAndGroupOwnerIdAndGroupMemberId( groupId, groupOwnerId, memberId); if (isDenyRequest != 1) { diff --git a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupQueryService.java b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupQueryService.java index 41fba78a2..dd8141997 100644 --- a/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupQueryService.java +++ b/backend/core/src/main/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupQueryService.java @@ -9,8 +9,9 @@ import site.timecapsulearchive.core.domain.group.data.dto.GroupMemberDto; import site.timecapsulearchive.core.domain.group.exception.GroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; @Service @RequiredArgsConstructor @@ -20,12 +21,12 @@ public class MemberGroupQueryService { private final GroupInviteRepository groupInviteRepository; private final MemberGroupRepository memberGroupRepository; - public Slice findGroupInvites( + public Slice findGroupReceivingInvitesSlice( final Long memberId, final int size, final ZonedDateTime createdAt ) { - return groupInviteRepository.findGroupInvitesSummary(memberId, size, createdAt); + return groupInviteRepository.findGroupReceivingInvitesSlice(memberId, size, createdAt); } public List findGroupMemberIds(final Long groupId) { @@ -40,4 +41,10 @@ public List findGroupMemberInfos( return memberGroupRepository.findGroupMemberInfos(memberId, groupId); } + public List findGroupSendingInvites( + final Long memberId, + final Long groupId + ) { + return groupInviteRepository.findGroupSendingInvites(memberId, groupId); + } } 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 c4c63562f..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 @@ -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_RECEIVING_INVITE_MEMBER_START_ID = + BULK_FRIEND_INVITE_MEMBER_START_ID + MAX_COUNT; + private static final Long FRIEND_SENDING_INVITE_MEMBER_START_ID = + 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; + 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 ownerInviteReceivingStartId; + 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 receivingInviteToOwnerMembers = MemberFixture.members( + FRIEND_RECEIVING_INVITE_MEMBER_START_ID.intValue(), MAX_COUNT); + for (Member member : receivingInviteToOwnerMembers) { + entityManager.persist(member); + + FriendInvite receivingInvite = FriendInviteFixture.friendInvite(owner, member); + entityManager.persist(receivingInvite); + } + ownerInviteReceivingStartId = receivingInviteToOwnerMembers.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() >= ownerInviteReceivingStartId + && dto.id() < ownerInviteReceivingStartId + 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().plusSeconds(1L)); + + //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.findFriendReceivingInvitesSlice( + 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.findFriendReceivingInvitesSlice( + ownerId, size, now); + + //when + FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); + Slice nextSlice = friendInviteQueryRepository.findFriendReceivingInvitesSlice( + ownerId, size, dto.createdAt().plusSeconds(1L)); + + //then + assertThat(nextSlice.getNumberOfElements()).isPositive(); + } + + @Test + void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_받은_목록_조회하면_빈_리스트가_나온다() { + //given + int size = 10; + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); + + //when + Slice slice = friendInviteQueryRepository.findFriendReceivingInvitesSlice( + 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.findFriendReceivingInvitesSlice( + 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 09ae4cf3d..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 @@ -43,8 +43,9 @@ class MemberFriendQueryRepositoryTest extends RepositoryTest { private static final String PROPAGATION_REQUIRES_NEW = "PROPAGATION_REQUIRES_NEW"; private static final int MAX_COUNT = 10; 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_INVITE_START_ID = + NOT_FRIEND_MEMBER_START_ID + NOT_FRIEND_MEMBER_START_ID; 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,18 @@ 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와 친구 초대 관계 멤버 데이터 + Member friendInviteMember = MemberFixture.member(FRIEND_INVITE_START_ID.intValue()); + entityManager.persist(friendInviteMember); + + FriendInvite friendInvite = FriendInviteFixture.friendInvite(owner, friendInviteMember); + entityManager.persist(friendInvite); + friendInviteTag = friendInviteMember.getTag(); }); } @@ -125,8 +124,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); @@ -150,80 +149,51 @@ void clear(@Autowired EntityManager entityManager) { } @Test - void 친구가_친구_목록_조회하면_친구_관계를_맺은_사용자_리스트가_나온다() { - //given - int size = 10; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); - - //when - Slice slice = memberFriendQueryRepository.findFriendsSlice( - friendId, - size, - now - ); - - assertThat(slice.getContent().size()).isEqualTo(1); - } - - @Test - void 친구_요청만_보낸_사용자가_친구_목록_조회하면_리스트가_나온다() { + void 사용자가_첫_페이지_이후의_친구_목록_조회하면_다음_페이지의_친구_관계를_맺은_사용자_리스트가_나온다() { //given int size = 20; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); - - //when - Slice slice = memberFriendQueryRepository.findFriendsSlice( - FRIEND_ID_TO_INVITE_OWNER, + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + Slice firstSlice = memberFriendQueryRepository.findFriendsSlice( + ownerId, size, now ); - //then - assertThat(slice).isEmpty(); - } - - @Test - void 사용자가_유효하지_않은_시간으로_사용자의_친구_목록_조회하면_빈_리스트가_나온다() { - //given - int size = 20; - ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); - //when - Slice slice = memberFriendQueryRepository.findFriendsSlice( + FriendSummaryDto dto = firstSlice.getContent().get(firstSlice.getNumberOfElements() - 1); + Slice nextSlice = memberFriendQueryRepository.findFriendsSlice( ownerId, size, - now + dto.createdAt().plusSeconds(1L) ); - //then - assertThat(slice).isEmpty(); + assertThat(nextSlice.getNumberOfElements()).isPositive(); } @Test - void 친구가_없는_사용자가_친구_목록_조회하면_빈_리스트가_나온다() { + void 친구가_친구_목록_조회하면_친구_관계를_맺은_사용자_리스트가_나온다() { //given - int size = 20; + int size = 10; ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(5); //when Slice slice = memberFriendQueryRepository.findFriendsSlice( - NOT_FRIEND_MEMBER_START_ID, + friendId, size, now ); - //then - assertThat(slice).isEmpty(); + assertThat(slice.getContent().size()).isEqualTo(1); } @Test - void 사용자가_유효하지_않은_시간으로_사용자의_친구_요청_목록_조회하면_빈_리스트가_나온다() { + void 사용자가_유효하지_않은_시간으로_사용자의_친구_목록_조회하면_빈_리스트가_나온다() { //given - int size = 20; + int size = 10; ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).minusDays(5); //when - Slice slice = memberFriendQueryRepository.findFriendRequestsSlice( + Slice slice = memberFriendQueryRepository.findFriendsSlice( ownerId, size, now @@ -234,13 +204,13 @@ 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.findFriendRequestsSlice( + Slice slice = memberFriendQueryRepository.findFriendsSlice( NOT_FRIEND_MEMBER_START_ID, size, now @@ -371,7 +341,7 @@ void clear(@Autowired EntityManager entityManager) { ownerId, friendInviteTag).orElseThrow(); //then - assertThat(dto.isFriendInviteToMe()).isTrue(); + assertThat(dto.isFriendInviteToMe() || dto.isFriendInviteToFriend()).isTrue(); } @Test 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_사용자_리스트를_조회_할_수_있다() { diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/service/GroupCommandServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/service/GroupCommandServiceTest.java index f6b55a63f..248433597 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/service/GroupCommandServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/group/service/GroupCommandServiceTest.java @@ -34,8 +34,8 @@ import site.timecapsulearchive.core.domain.member_group.entity.MemberGroup; import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.error.ErrorCode; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; import site.timecapsulearchive.core.infra.s3.manager.S3ObjectManager; diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/GroupInviteQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/GroupInviteQueryRepositoryTest.java index 52048ddda..5e8522e18 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/GroupInviteQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/GroupInviteQueryRepositoryTest.java @@ -1,12 +1,12 @@ package site.timecapsulearchive.core.domain.member_group.repository; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static org.assertj.core.api.Assertions.assertThat; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; +import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.List; -import org.assertj.core.api.Assertions; import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -22,16 +22,21 @@ import site.timecapsulearchive.core.domain.group.entity.Group; import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member_group.data.dto.GroupInviteSummaryDto; +import site.timecapsulearchive.core.domain.member_group.data.dto.GroupSendingInviteMemberDto; import site.timecapsulearchive.core.domain.member_group.entity.GroupInvite; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteQueryRepository; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteQueryRepositoryImpl; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteQueryRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteQueryRepositoryImpl; @TestConstructor(autowireMode = AutowireMode.ALL) class GroupInviteQueryRepositoryTest extends RepositoryTest { private static final int MAX_GROUP_COUNT = 2; + private final GroupInviteQueryRepository groupInviteRepository; - private Member groupMember; + + private Long groupId; + private Long groupOwnerId; + private Long groupMemberId; GroupInviteQueryRepositoryTest( JdbcTemplate jdbcTemplate, @@ -47,14 +52,17 @@ void setUp(@Autowired EntityManager entityManager) { // 그룹 초대 할 그룹장들 List groupOwners = MemberFixture.members(0, MAX_GROUP_COUNT); groupOwners.forEach(entityManager::persist); + groupOwnerId = groupOwners.get(0).getId(); //그룹 초대 올 그룹원 - groupMember = MemberFixture.member(2); + Member groupMember = MemberFixture.member(2); entityManager.persist(groupMember); + groupMemberId = groupMember.getId(); // 그룹들 List groups = GroupFixture.groups(0, MAX_GROUP_COUNT); groups.forEach(entityManager::persist); + groupId = groups.get(0).getId(); // 그룹원에게 초대온 그룹 초대들 for (int i = 0; i < MAX_GROUP_COUNT; i++) { @@ -65,55 +73,87 @@ void setUp(@Autowired EntityManager entityManager) { } @Test - void 사용자는_자신에게_온_그룹_초대_목록을_조회할_수_있다() { + void 사용자는_자신에게_온_그룹_초대_목록을_조회하면_그룹_초대목록이_나온다() { //given - Long memberId = groupMember.getId(); + Long memberId = groupMemberId; int size = 1; ZonedDateTime createAt = ZonedDateTime.now().plusDays(1); //when - Slice groupInvitesSummary = groupInviteRepository.findGroupInvitesSummary( + Slice groupInvitesSummary = groupInviteRepository.findGroupReceivingInvitesSlice( memberId, size, createAt); //then - assertThat(groupInvitesSummary.getContent()).isNotNull(); + assertThat(groupInvitesSummary.getContent()).isNotEmpty(); } @Test void 사용자는_자신에게_온_그룹_초대_목록에서_그룹_정보와_그룹장을_알_수_있다() { //given - Long memberId = groupMember.getId(); + Long memberId = groupMemberId; int size = 1; ZonedDateTime createAt = ZonedDateTime.now().plusDays(1); //when - Slice groupInvitesSummary = groupInviteRepository.findGroupInvitesSummary( + Slice groupInvitesSummary = groupInviteRepository.findGroupReceivingInvitesSlice( memberId, size, createAt); //then SoftAssertions.assertSoftly(softly -> { - Assertions.assertThat(groupInvitesSummary).allMatch(g -> !g.groupName().isEmpty()); - Assertions.assertThat(groupInvitesSummary) + assertThat(groupInvitesSummary).allMatch(g -> !g.groupName().isEmpty()); + assertThat(groupInvitesSummary) .allMatch(g -> !g.groupProfileUrl().isEmpty()); - Assertions.assertThat(groupInvitesSummary).allMatch(g -> !g.description().isEmpty()); - Assertions.assertThat(groupInvitesSummary).allMatch(g -> !g.groupOwnerName().isEmpty()); + assertThat(groupInvitesSummary).allMatch(g -> !g.description().isEmpty()); + assertThat(groupInvitesSummary).allMatch(g -> !g.groupOwnerName().isEmpty()); }); } @Test - void 사용자는_조회한_그룹_초대_목록_후_그룹_초대_존재_여부를_확인_할_수_있다() { + void 사용자는_그룹_초대_받은_목록_첫_페이지를_조회_후_다음_페이지에서_그룹_초대_받은_목록을_조회_할_수_있다() { //given - Long memberId = groupMember.getId(); + Long memberId = groupMemberId; int size = 1; - ZonedDateTime createAt = ZonedDateTime.now().plusDays(1); + ZonedDateTime now = ZonedDateTime.now(ZoneId.of("UTC")).plusDays(3); + Slice firstSlice = groupInviteRepository.findGroupReceivingInvitesSlice( + memberId, size, now); //when - Slice groupInvitesSummary = groupInviteRepository.findGroupInvitesSummary( - memberId, size, createAt); + GroupInviteSummaryDto dto = firstSlice.getContent().get(0); + Slice groupInvitesSummary = groupInviteRepository.findGroupReceivingInvitesSlice( + memberId, size, dto.groupReceivingInviteTime().plusSeconds(1L)); + + //then + assertThat(groupInvitesSummary.getContent()).isNotEmpty(); + } + + @Test + void 그룹장은_자신이_보낸_그룹_초대_목록을_조회하면_그룹_초대목록이_나온다() { + //given + //when + List groupSendingInvites = groupInviteRepository.findGroupSendingInvites( + groupOwnerId, groupId); //then - assertThat(groupInvitesSummary.hasNext()).isTrue(); + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(groupSendingInvites).isNotEmpty(); + softly.assertThat(groupSendingInvites).allMatch(dto -> dto.id() != null); + softly.assertThat(groupSendingInvites) + .allMatch(dto -> dto.nickname() != null && !dto.nickname().isBlank()); + softly.assertThat(groupSendingInvites) + .allMatch(dto -> dto.profileUrl() != null && !dto.profileUrl().isBlank()); + softly.assertThat(groupSendingInvites) + .allMatch(dto -> dto.sendingInvitesCreatedAt() != null); + }); } + @Test + void 그룹원은_자신이_보낸_그룹_초대_목록을_조회하면_빈_리스트가_나온다() { + //given + //when + List groupSendingInvites = groupInviteRepository.findGroupSendingInvites( + groupMemberId, groupId); + //then + assertThat(groupSendingInvites).isEmpty(); + } } diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java index eec20ba04..04e9cfb94 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/repository/MemberGroupQueryRepositoryTest.java @@ -63,10 +63,6 @@ void setup(@Autowired EntityManager entityManager) { groups.add(group); } - //그룹원들 - List members = MemberFixture.members(4, 2); - members.forEach(entityManager::persist); - //그룹에 사용자를 그룹장으로 설정 for (int count = 0; count < GROUP_COUNT; count++) { MemberGroup memberGroup = MemberGroupFixture.memberGroup(member, groups.get(count), @@ -74,6 +70,10 @@ void setup(@Autowired EntityManager entityManager) { entityManager.persist(memberGroup); } + //그룹원들 + List members = MemberFixture.members(4, 2); + members.forEach(entityManager::persist); + //그룹원들 설정 List memberGroups = MemberGroupFixture.memberGroups(members, groups.get(0)); memberGroups.forEach(entityManager::persist); diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandServiceTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandServiceTest.java index a3306a721..955a6eaf4 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandServiceTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/domain/member_group/service/MemberGroupCommandServiceTest.java @@ -38,8 +38,8 @@ import site.timecapsulearchive.core.domain.member_group.exception.MemberGroupNotFoundException; import site.timecapsulearchive.core.domain.member_group.exception.NoGroupAuthorityException; import site.timecapsulearchive.core.domain.member_group.facade.MemberGroupFacade; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.global.error.ErrorCode; import site.timecapsulearchive.core.infra.queue.manager.SocialNotificationManager; @@ -211,7 +211,8 @@ class MemberGroupCommandServiceTest { given(memberRepository.findMemberById(memberId)).willReturn(Optional.of(groupMember)); given(groupRepository.findGroupById(groupId)).willReturn( Optional.of(GroupFixture.group())); - given(memberGroupRepository.findGroupOwnerId(groupId)).willReturn(Optional.of(groupOwnerId)); + given(memberGroupRepository.findGroupOwnerId(groupId)).willReturn( + Optional.of(groupOwnerId)); given(groupInviteRepository.deleteGroupInviteByGroupIdAndGroupOwnerIdAndGroupMemberId( groupId, groupOwnerId, memberId)).willReturn(1); @@ -223,7 +224,8 @@ class MemberGroupCommandServiceTest { //then SoftAssertions.assertSoftly( softly -> { - assertThat(groupAcceptNotificationDto.groupMemberNickname()).isEqualTo(groupMember.getNickname()); + assertThat(groupAcceptNotificationDto.groupMemberNickname()).isEqualTo( + groupMember.getNickname()); assertThat(groupAcceptNotificationDto.groupOwnerId()).isEqualTo(groupOwnerId); } ); diff --git a/backend/core/src/test/java/site/timecapsulearchive/core/infrastructure/RedisConcurrencyTest.java b/backend/core/src/test/java/site/timecapsulearchive/core/infrastructure/RedisConcurrencyTest.java index dfebd87e9..b86d3999b 100644 --- a/backend/core/src/test/java/site/timecapsulearchive/core/infrastructure/RedisConcurrencyTest.java +++ b/backend/core/src/test/java/site/timecapsulearchive/core/infrastructure/RedisConcurrencyTest.java @@ -27,8 +27,8 @@ import site.timecapsulearchive.core.domain.member.entity.Member; import site.timecapsulearchive.core.domain.member.repository.MemberRepository; import site.timecapsulearchive.core.domain.member_group.facade.MemberGroupFacade; -import site.timecapsulearchive.core.domain.member_group.repository.groupInviteRepository.GroupInviteRepository; -import site.timecapsulearchive.core.domain.member_group.repository.memberGroupRepository.MemberGroupRepository; +import site.timecapsulearchive.core.domain.member_group.repository.group_invite_repository.GroupInviteRepository; +import site.timecapsulearchive.core.domain.member_group.repository.member_group_repository.MemberGroupRepository; import site.timecapsulearchive.core.domain.member_group.service.MemberGroupCommandService; import site.timecapsulearchive.core.global.error.ErrorCode; import site.timecapsulearchive.core.global.error.exception.RedisLockException;