diff --git a/src/main/java/com/moabam/api/application/NotificationService.java b/src/main/java/com/moabam/api/application/NotificationService.java index d70cd57a..12c3ddf9 100644 --- a/src/main/java/com/moabam/api/application/NotificationService.java +++ b/src/main/java/com/moabam/api/application/NotificationService.java @@ -4,6 +4,9 @@ import java.time.LocalDateTime; import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -15,6 +18,7 @@ import com.moabam.api.domain.entity.Participant; import com.moabam.api.domain.repository.NotificationRepository; import com.moabam.api.domain.repository.ParticipantSearchRepository; +import com.moabam.api.dto.KnockNotificationStatusResponse; import com.moabam.api.dto.NotificationMapper; import com.moabam.global.common.annotation.MemberTest; import com.moabam.global.error.exception.ConflictException; @@ -58,6 +62,24 @@ public void sendCertificationTimeNotification() { }); } + /** + * TODO : 영명-재윤님 방 조회하실 때, 특정 사용자의 방 내 참여자들에 대한 콕 찌르기 여부를 반환해주는 메서드이니 사용하시기 바랍니다. + */ + public KnockNotificationStatusResponse checkMyKnockNotificationStatusInRoom(MemberTest member, Long roomId) { + List participants = participantSearchRepository.findOtherParticipantsInRoom(member.memberId(), + roomId); + + Predicate knockPredicate = targetId -> + notificationRepository.existsByKey(generateKnockKey(member.memberId(), targetId, roomId)); + + Map> knockNotificationStatus = participants.stream() + .map(Participant::getMemberId) + .collect(Collectors.partitioningBy(knockPredicate)); + + return NotificationMapper + .toKnockNotificationStatusResponse(knockNotificationStatus.get(true), knockNotificationStatus.get(false)); + } + private void sendAsyncFcm(Long fcmTokenKey, Notification notification) { String fcmToken = notificationRepository.findFcmTokenByMemberId(fcmTokenKey); diff --git a/src/main/java/com/moabam/api/domain/repository/ParticipantSearchRepository.java b/src/main/java/com/moabam/api/domain/repository/ParticipantSearchRepository.java index 768e6946..bff41c2d 100644 --- a/src/main/java/com/moabam/api/domain/repository/ParticipantSearchRepository.java +++ b/src/main/java/com/moabam/api/domain/repository/ParticipantSearchRepository.java @@ -42,6 +42,16 @@ public List findParticipants(Long roomId) { .fetch(); } + public List findOtherParticipantsInRoom(Long memberId, Long roomId) { + return jpaQueryFactory + .selectFrom(participant) + .where( + participant.room.id.eq(roomId), + participant.memberId.ne(memberId) + ) + .fetch(); + } + public List findAllByRoomCertifyTime(int certifyTime) { return jpaQueryFactory .selectFrom(participant) diff --git a/src/main/java/com/moabam/api/dto/KnockNotificationStatusResponse.java b/src/main/java/com/moabam/api/dto/KnockNotificationStatusResponse.java new file mode 100644 index 00000000..fe500e5c --- /dev/null +++ b/src/main/java/com/moabam/api/dto/KnockNotificationStatusResponse.java @@ -0,0 +1,13 @@ +package com.moabam.api.dto; + +import java.util.List; + +import lombok.Builder; + +@Builder +public record KnockNotificationStatusResponse( + List knockedMembersId, + List notKnockedMembersId +) { + +} diff --git a/src/main/java/com/moabam/api/dto/NotificationMapper.java b/src/main/java/com/moabam/api/dto/NotificationMapper.java index b5283825..e3c2b477 100644 --- a/src/main/java/com/moabam/api/dto/NotificationMapper.java +++ b/src/main/java/com/moabam/api/dto/NotificationMapper.java @@ -1,5 +1,7 @@ package com.moabam.api.dto; +import java.util.List; + import com.google.firebase.messaging.Message; import com.google.firebase.messaging.Notification; @@ -33,4 +35,14 @@ public static Message toMessageEntity(Notification notification, String fcmToken .setToken(fcmToken) .build(); } + + public static KnockNotificationStatusResponse toKnockNotificationStatusResponse( + List knockedMembersId, + List notKnockedMembersId + ) { + return KnockNotificationStatusResponse.builder() + .knockedMembersId(knockedMembersId) + .notKnockedMembersId(notKnockedMembersId) + .build(); + } } diff --git a/src/test/java/com/moabam/api/application/NotificationServiceTest.java b/src/test/java/com/moabam/api/application/NotificationServiceTest.java index ec72a657..f06482a4 100644 --- a/src/test/java/com/moabam/api/application/NotificationServiceTest.java +++ b/src/test/java/com/moabam/api/application/NotificationServiceTest.java @@ -20,6 +20,7 @@ import com.moabam.api.domain.entity.Participant; import com.moabam.api.domain.repository.NotificationRepository; import com.moabam.api.domain.repository.ParticipantSearchRepository; +import com.moabam.api.dto.KnockNotificationStatusResponse; import com.moabam.global.common.annotation.MemberTest; import com.moabam.global.error.exception.ConflictException; import com.moabam.global.error.exception.NotFoundException; @@ -134,4 +135,40 @@ void notificationService_sendCertificationTimeNotification_NoFirebaseMessaging(L // Then verify(firebaseMessaging, times(0)).sendAsync(any(Message.class)); } + + @DisplayName("특정 방에서 나 이외의 모든 사용자를 콕 찔렀을 때, - KnockNotificationStatusResponse") + @MethodSource("com.moabam.support.fixture.ParticipantFixture#provideParticipants") + @ParameterizedTest + void notificationService_knocked_checkMyKnockNotificationStatusInRoom(List participants) { + // Given + given(participantSearchRepository.findOtherParticipantsInRoom(any(Long.class), any(Long.class))) + .willReturn(participants); + given(notificationRepository.existsByKey(any(String.class))).willReturn(true); + + // When + KnockNotificationStatusResponse actual = + notificationService.checkMyKnockNotificationStatusInRoom(memberTest, 1L); + + // Then + assertThat(actual.knockedMembersId()).hasSize(3); + assertThat(actual.notKnockedMembersId()).isEmpty(); + } + + @DisplayName("특정 방에서 나 이외의 모든 사용자를 콕 안 찔렀을 때, - KnockNotificationStatusResponse") + @MethodSource("com.moabam.support.fixture.ParticipantFixture#provideParticipants") + @ParameterizedTest + void notificationService_notKnocked_checkMyKnockNotificationStatusInRoom(List participants) { + // Given + given(participantSearchRepository.findOtherParticipantsInRoom(any(Long.class), any(Long.class))) + .willReturn(participants); + given(notificationRepository.existsByKey(any(String.class))).willReturn(false); + + // When + KnockNotificationStatusResponse actual = + notificationService.checkMyKnockNotificationStatusInRoom(memberTest, 1L); + + // Then + assertThat(actual.knockedMembersId()).isEmpty(); + assertThat(actual.notKnockedMembersId()).hasSize(3); + } } diff --git a/src/test/java/com/moabam/api/domain/repository/ParticipantSearchRepositoryTest.java b/src/test/java/com/moabam/api/domain/repository/ParticipantSearchRepositoryTest.java index 5ac95f4a..4039d2c5 100644 --- a/src/test/java/com/moabam/api/domain/repository/ParticipantSearchRepositoryTest.java +++ b/src/test/java/com/moabam/api/domain/repository/ParticipantSearchRepositoryTest.java @@ -40,6 +40,21 @@ void participantSearchRepository_findAllByRoomCertifyTime(Room room, List actual = participantSearchRepository.findAllByRoomCertifyTime(10); // Then - assertThat(actual).hasSize(3); + assertThat(actual).hasSize(5); + } + + @DisplayName("특정 방에서 본인을 제외한 참여자 조회를 성공적으로 했을 때, - List") + @MethodSource("com.moabam.support.fixture.ParticipantFixture#provideRoomAndParticipants") + @ParameterizedTest + void participantSearchRepository_findOtherParticipantsInRoom(Room room, List participants) { + // Given + roomRepository.save(room); + participantRepository.saveAll(participants); + + // When + List actual = participantSearchRepository.findOtherParticipantsInRoom(7L, room.getId()); + + // Then + assertThat(actual).hasSize(4); } } diff --git a/src/test/java/com/moabam/support/fixture/ParticipantFixture.java b/src/test/java/com/moabam/support/fixture/ParticipantFixture.java index c4b2c5c3..08bdcbeb 100644 --- a/src/test/java/com/moabam/support/fixture/ParticipantFixture.java +++ b/src/test/java/com/moabam/support/fixture/ParticipantFixture.java @@ -22,8 +22,8 @@ public static Stream provideParticipants() { return Stream.of(Arguments.of(List.of( ParticipantFixture.participant(room, 1L), - ParticipantFixture.participant(room, 2L), - ParticipantFixture.participant(room, 3L) + ParticipantFixture.participant(room, 3L), + ParticipantFixture.participant(room, 7L) ))); } @@ -35,7 +35,9 @@ public static Stream provideRoomAndParticipants() { List.of( ParticipantFixture.participant(room, 1L), ParticipantFixture.participant(room, 2L), - ParticipantFixture.participant(room, 3L) + ParticipantFixture.participant(room, 3L), + ParticipantFixture.participant(room, 5L), + ParticipantFixture.participant(room, 7L) )) ); }