Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: 알림 메시지 형식 변경 #203

Merged
merged 5 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@
@Transactional(readOnly = true)
public class NotificationService {

private static final String KNOCK_BODY = "%s님이 콕 찔렀습니다.";
private static final String CERTIFY_TIME_BODY = "%s방 인증 시간입니다.";
private static final String COMMON_TITLE = "모아밤";
private static final String KNOCK_BODY = "%s방에서 %s님이 콕 찔렀어요~";
private static final String CERTIFY_TIME_BODY = "%s방 인증 시간~";

private final ClockHolder clockHolder;
private final FcmService fcmService;
Expand All @@ -40,18 +41,21 @@ public class NotificationService {

@Transactional
public void sendKnock(Long roomId, Long targetId, Long memberId, String memberNickname) {
roomService.validateRoomById(roomId);
String roomTitle = roomService.findRoom(roomId).getTitle();
validateConflictKnock(roomId, targetId, memberId);
String fcmToken = fcmService.findTokenByMemberId(targetId)
.orElseThrow(() -> new NotFoundException(ErrorMessage.NOT_FOUND_FCM_TOKEN));

fcmService.sendAsync(fcmToken, String.format(KNOCK_BODY, memberNickname));
String notificationTitle = roomId.toString();
String notificationBody = String.format(KNOCK_BODY, roomTitle, memberNickname);
fcmService.sendAsync(fcmToken, notificationTitle, notificationBody);
notificationRepository.saveKnock(roomId, targetId, memberId);
}

public void sendCouponIssueResult(Long memberId, String couponName, String body) {
String fcmToken = fcmService.findTokenByMemberId(memberId).orElse(null);
fcmService.sendAsync(fcmToken, String.format(body, couponName));
String notificationBody = String.format(body, couponName);
fcmService.sendAsync(fcmToken, COMMON_TITLE, notificationBody);
}

@Scheduled(cron = "0 50 * * * *")
Expand All @@ -61,9 +65,10 @@ public void sendCertificationTime() {

participants.parallelStream().forEach(participant -> {
String roomTitle = participant.getRoom().getTitle();
String notificationTitle = participant.getRoom().getId().toString();
String notificationBody = String.format(CERTIFY_TIME_BODY, roomTitle);
String fcmToken = fcmService.findTokenByMemberId(participant.getMemberId()).orElse(null);
fcmService.sendAsync(fcmToken, notificationBody);
fcmService.sendAsync(fcmToken, notificationTitle, notificationBody);
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,12 +161,6 @@ public boolean checkIfParticipant(Long memberId, Long roomId) {
}
}

public void validateRoomById(Long roomId) {
if (!roomRepository.existsById(roomId)) {
throw new NotFoundException(ROOM_NOT_FOUND);
}
}

public Room findRoom(Long roomId) {
return roomRepository.findById(roomId)
.orElseThrow(() -> new NotFoundException(ROOM_NOT_FOUND));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class FcmMapper {

private static final String NOTIFICATION_TITLE = "모아밤";

public static Notification toNotification(String body) {
public static Notification toNotification(String title, String body) {
return Notification.builder()
.setTitle(NOTIFICATION_TITLE)
.setTitle(title)
.setBody(body)
.build();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public Optional<String> findTokenByMemberId(Long targetId) {
return Optional.ofNullable(fcmRepository.findTokenByMemberId(targetId));
}

public void sendAsync(String fcmToken, String notificationBody) {
Notification notification = FcmMapper.toNotification(notificationBody);
public void sendAsync(String fcmToken, String notificationTitle, String notificationBody) {
Notification notification = FcmMapper.toNotification(notificationTitle, notificationBody);

if (fcmToken != null) {
Message message = FcmMapper.toMessage(notification, fcmToken);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import com.moabam.api.application.room.RoomService;
import com.moabam.api.domain.notification.repository.NotificationRepository;
import com.moabam.api.domain.room.Participant;
import com.moabam.api.domain.room.Room;
import com.moabam.api.domain.room.repository.ParticipantSearchRepository;
import com.moabam.api.infrastructure.fcm.FcmService;
import com.moabam.global.auth.model.AuthMember;
Expand All @@ -29,6 +30,7 @@
import com.moabam.global.error.model.ErrorMessage;
import com.moabam.support.annotation.WithMember;
import com.moabam.support.common.FilterProcessExtension;
import com.moabam.support.fixture.RoomFixture;

@ExtendWith({MockitoExtension.class, FilterProcessExtension.class})
class NotificationServiceTest {
Expand Down Expand Up @@ -57,7 +59,9 @@ class NotificationServiceTest {
@Test
void sendKnock_success() {
// Given
willDoNothing().given(roomService).validateRoomById(any(Long.class));
Room room = RoomFixture.room();

given(roomService.findRoom(any(Long.class))).willReturn(room);
given(fcmService.findTokenByMemberId(any(Long.class))).willReturn(Optional.of("FCM-TOKEN"));
given(notificationRepository.existsKnockByKey(any(Long.class), any(Long.class), any(Long.class)))
.willReturn(false);
Expand All @@ -66,15 +70,15 @@ void sendKnock_success() {
notificationService.sendKnock(1L, 1L, 2L, "nickName");

// Then
verify(fcmService).sendAsync(any(String.class), any(String.class));
verify(fcmService).sendAsync(any(String.class), any(String.class), any(String.class));
verify(notificationRepository).saveKnock(any(Long.class), any(Long.class), any(Long.class));
}

@DisplayName("콕 찌를 상대의 방이 존재하지 않는다. - NotFoundException")
@Test
void sendKnock_Room_NotFoundException() {
// Given
willThrow(NotFoundException.class).given(roomService).validateRoomById(any(Long.class));
given(roomService.findRoom(any(Long.class))).willThrow(NotFoundException.class);

// When & Then
assertThatThrownBy(() -> notificationService.sendKnock(1L, 1L, 2L, "nickName"))
Expand All @@ -85,7 +89,9 @@ void sendKnock_Room_NotFoundException() {
@Test
void sendKnock_FcmToken_NotFoundException() {
// Given
willDoNothing().given(roomService).validateRoomById(any(Long.class));
Room room = RoomFixture.room();

given(roomService.findRoom(any(Long.class))).willReturn(room);
given(fcmService.findTokenByMemberId(any(Long.class))).willReturn(Optional.empty());
given(notificationRepository.existsKnockByKey(any(Long.class), any(Long.class), any(Long.class)))
.willReturn(false);
Expand All @@ -100,7 +106,9 @@ void sendKnock_FcmToken_NotFoundException() {
@Test
void sendKnock_ConflictException() {
// Given
willDoNothing().given(roomService).validateRoomById(any(Long.class));
Room room = RoomFixture.room();

given(roomService.findRoom(any(Long.class))).willReturn(room);
given(notificationRepository.existsKnockByKey(any(Long.class), any(Long.class), any(Long.class)))
.willReturn(true);

Expand All @@ -120,7 +128,7 @@ void sendCouponIssueResult_success() {
notificationService.sendCouponIssueResult(1L, "couponName", successIssueResult);

// Then
verify(fcmService).sendAsync(any(String.class), any(String.class));
verify(fcmService).sendAsync(any(String.class), any(String.class), any(String.class));
}

@DisplayName("로그아웃된 사용자에게 쿠폰 이슈 결과를 성공적으로 전송한다. - Void")
Expand All @@ -133,7 +141,7 @@ void sendCouponIssueResult_fcmToken_null() {
notificationService.sendCouponIssueResult(1L, "couponName", successIssueResult);

// Then
verify(fcmService).sendAsync(isNull(), any(String.class));
verify(fcmService).sendAsync(isNull(), any(String.class), any(String.class));
}

@DisplayName("특정 인증 시간에 해당하는 방 사용자들에게 알림을 성공적으로 보낸다. - Void")
Expand All @@ -149,7 +157,8 @@ void sendCertificationTime_success(List<Participant> participants) {
notificationService.sendCertificationTime();

// Then
verify(fcmService, times(3)).sendAsync(any(String.class), any(String.class));
verify(fcmService, times(3))
.sendAsync(any(String.class), any(String.class), any(String.class));
}

@DisplayName("특정 인증 시간에 해당하는 방 사용자들의 토큰값이 없다. - Void")
Expand All @@ -165,7 +174,8 @@ void sendCertificationTime_NoFirebaseMessaging(List<Participant> participants) {
notificationService.sendCertificationTime();

// Then
verify(fcmService, times(0)).sendAsync(any(String.class), any(String.class));
verify(fcmService, times(0))
.sendAsync(any(String.class), any(String.class), any(String.class));
}

@WithMember
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ void findTokenByMemberId_success() {
@Test
void sendAsync_success() {
// When
fcmService.sendAsync("FCM-TOKEN", "알림");
fcmService.sendAsync("FCM-TOKEN", "title", "body");

// Then
verify(firebaseMessaging).sendAsync(any(Message.class));
Expand All @@ -89,7 +89,7 @@ void sendAsync_success() {
@Test
void sendAsync_null() {
// When
fcmService.sendAsync(null, "알림");
fcmService.sendAsync(null, "titile", "body");

// Then
verify(firebaseMessaging, times(0)).sendAsync(any(Message.class));
Expand Down
1 change: 1 addition & 0 deletions src/test/java/com/moabam/support/fixture/RoomFixture.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public static Room room() {

public static Room room(int certifyTime) {
return Room.builder()
.id(1L)
.title("testTitle")
.roomType(RoomType.MORNING)
.certifyTime(certifyTime)
Expand Down