diff --git a/src/main/java/com/moabam/api/application/auth/AuthorizationService.java b/src/main/java/com/moabam/api/application/auth/AuthorizationService.java index c2de7a50..df6e2851 100644 --- a/src/main/java/com/moabam/api/application/auth/AuthorizationService.java +++ b/src/main/java/com/moabam/api/application/auth/AuthorizationService.java @@ -12,6 +12,7 @@ import com.moabam.api.application.auth.mapper.AuthMapper; import com.moabam.api.application.auth.mapper.AuthorizationMapper; import com.moabam.api.application.member.MemberService; +import com.moabam.api.domain.auth.repository.TokenRepository; import com.moabam.api.dto.auth.AuthorizationCodeRequest; import com.moabam.api.dto.auth.AuthorizationCodeResponse; import com.moabam.api.dto.auth.AuthorizationTokenInfoResponse; @@ -19,7 +20,6 @@ import com.moabam.api.dto.auth.AuthorizationTokenResponse; import com.moabam.api.dto.auth.LoginResponse; import com.moabam.api.dto.auth.TokenSaveValue; -import com.moabam.api.infrastructure.redis.TokenRepository; import com.moabam.global.auth.model.AuthorizationMember; import com.moabam.global.auth.model.PublicClaim; import com.moabam.global.common.util.GlobalConstant; diff --git a/src/main/java/com/moabam/api/application/notification/NotificationMapper.java b/src/main/java/com/moabam/api/application/notification/NotificationMapper.java index b18156e2..792821e1 100644 --- a/src/main/java/com/moabam/api/application/notification/NotificationMapper.java +++ b/src/main/java/com/moabam/api/application/notification/NotificationMapper.java @@ -13,20 +13,11 @@ public final class NotificationMapper { private static final String NOTIFICATION_TITLE = "모아밤"; - private static final String KNOCK_BODY = "님이 콕 찔렀습니다."; - private static final String CERTIFY_TIME_BODY = "방 인증 시간입니다."; - public static Notification toKnockNotificationEntity(String nickname) { + public static Notification toNotification(String body) { return Notification.builder() .setTitle(NOTIFICATION_TITLE) - .setBody(nickname + KNOCK_BODY) - .build(); - } - - public static Notification toCertifyAuthNotificationEntity(String title) { - return Notification.builder() - .setTitle(NOTIFICATION_TITLE) - .setBody(title + CERTIFY_TIME_BODY) + .setBody(body) .build(); } diff --git a/src/main/java/com/moabam/api/application/notification/NotificationService.java b/src/main/java/com/moabam/api/application/notification/NotificationService.java index 71e094f6..12722c9d 100644 --- a/src/main/java/com/moabam/api/application/notification/NotificationService.java +++ b/src/main/java/com/moabam/api/application/notification/NotificationService.java @@ -12,14 +12,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import com.google.firebase.messaging.FirebaseMessaging; -import com.google.firebase.messaging.Message; -import com.google.firebase.messaging.Notification; 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.repository.ParticipantSearchRepository; import com.moabam.api.dto.notification.KnockNotificationStatusResponse; -import com.moabam.api.infrastructure.redis.NotificationRepository; +import com.moabam.api.infrastructure.fcm.FcmService; import com.moabam.global.auth.model.AuthorizationMember; import com.moabam.global.error.exception.ConflictException; import com.moabam.global.error.exception.NotFoundException; @@ -32,8 +30,12 @@ @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 KNOCK_KEY = "room_%s_member_%s_knocks_%s"; + + private final FcmService fcmService; private final RoomService roomService; - private final FirebaseMessaging firebaseMessaging; private final NotificationRepository notificationRepository; private final ParticipantSearchRepository participantSearchRepository; @@ -45,8 +47,9 @@ public void sendKnockNotification(AuthorizationMember member, Long targetId, Lon validateConflictKnockNotification(knockKey); validateFcmToken(targetId); - Notification notification = NotificationMapper.toKnockNotificationEntity(member.nickname()); - sendAsyncFcm(targetId, notification); + String fcmToken = notificationRepository.findFcmTokenByMemberId(targetId); + String notificationBody = String.format(KNOCK_BODY, member.nickname()); + fcmService.sendAsyncFcm(fcmToken, notificationBody); notificationRepository.saveKnockNotification(knockKey); } @@ -57,8 +60,9 @@ public void sendCertificationTimeNotification() { participants.parallelStream().forEach(participant -> { String roomTitle = participant.getRoom().getTitle(); - Notification notification = NotificationMapper.toCertifyAuthNotificationEntity(roomTitle); - sendAsyncFcm(participant.getMemberId(), notification); + String fcmToken = notificationRepository.findFcmTokenByMemberId(participant.getMemberId()); + String notificationBody = String.format(CERTIFY_TIME_BODY, roomTitle); + fcmService.sendAsyncFcm(fcmToken, notificationBody); }); } @@ -80,15 +84,6 @@ public KnockNotificationStatusResponse checkMyKnockNotificationStatusInRoom(Auth .toKnockNotificationStatusResponse(knockNotificationStatus.get(true), knockNotificationStatus.get(false)); } - private void sendAsyncFcm(Long fcmTokenKey, Notification notification) { - String fcmToken = notificationRepository.findFcmTokenByMemberId(fcmTokenKey); - - if (fcmToken != null) { - Message message = NotificationMapper.toMessageEntity(notification, fcmToken); - firebaseMessaging.sendAsync(message); - } - } - private void validateConflictKnockNotification(String knockKey) { if (notificationRepository.existsByKey(knockKey)) { throw new ConflictException(ErrorMessage.CONFLICT_KNOCK); diff --git a/src/main/java/com/moabam/api/infrastructure/redis/TokenRepository.java b/src/main/java/com/moabam/api/domain/auth/repository/TokenRepository.java similarity index 59% rename from src/main/java/com/moabam/api/infrastructure/redis/TokenRepository.java rename to src/main/java/com/moabam/api/domain/auth/repository/TokenRepository.java index f714d269..3286d0e4 100644 --- a/src/main/java/com/moabam/api/infrastructure/redis/TokenRepository.java +++ b/src/main/java/com/moabam/api/domain/auth/repository/TokenRepository.java @@ -1,4 +1,4 @@ -package com.moabam.api.infrastructure.redis; +package com.moabam.api.domain.auth.repository; import java.time.Duration; @@ -6,33 +6,34 @@ import org.springframework.stereotype.Repository; import com.moabam.api.dto.auth.TokenSaveValue; +import com.moabam.api.infrastructure.redis.HashRedisRepository; @Repository public class TokenRepository { private static final int EXPIRE_DAYS = 14; - private final HashTemplateRepository hashTemplateRepository; + private final HashRedisRepository hashRedisRepository; @Autowired - public TokenRepository(HashTemplateRepository hashTemplateRepository) { - this.hashTemplateRepository = hashTemplateRepository; + public TokenRepository(HashRedisRepository hashRedisRepository) { + this.hashRedisRepository = hashRedisRepository; } public void saveToken(Long memberId, TokenSaveValue tokenSaveRequest) { String tokenKey = parseTokenKey(memberId); - hashTemplateRepository.save(tokenKey, tokenSaveRequest, Duration.ofDays(EXPIRE_DAYS)); + hashRedisRepository.save(tokenKey, tokenSaveRequest, Duration.ofDays(EXPIRE_DAYS)); } public TokenSaveValue getTokenSaveValue(Long memberId) { String tokenKey = parseTokenKey(memberId); - return (TokenSaveValue)hashTemplateRepository.get(tokenKey); + return (TokenSaveValue)hashRedisRepository.get(tokenKey); } public void delete(Long memberId) { String tokenKey = parseTokenKey(memberId); - hashTemplateRepository.delete(tokenKey); + hashRedisRepository.delete(tokenKey); } private String parseTokenKey(Long memberId) { diff --git a/src/main/java/com/moabam/api/infrastructure/redis/NotificationRepository.java b/src/main/java/com/moabam/api/domain/notification/repository/NotificationRepository.java similarity index 80% rename from src/main/java/com/moabam/api/infrastructure/redis/NotificationRepository.java rename to src/main/java/com/moabam/api/domain/notification/repository/NotificationRepository.java index 70b25df9..df41d185 100644 --- a/src/main/java/com/moabam/api/infrastructure/redis/NotificationRepository.java +++ b/src/main/java/com/moabam/api/domain/notification/repository/NotificationRepository.java @@ -1,4 +1,4 @@ -package com.moabam.api.infrastructure.redis; +package com.moabam.api.domain.notification.repository; import static com.moabam.global.common.util.GlobalConstant.*; import static java.util.Objects.*; @@ -7,6 +7,8 @@ import org.springframework.stereotype.Repository; +import com.moabam.api.infrastructure.redis.StringRedisRepository; + import lombok.RequiredArgsConstructor; @Repository @@ -19,17 +21,17 @@ public class NotificationRepository { private final StringRedisRepository stringRedisRepository; // TODO : 세연님 로그인 시, 해당 메서드 사용해서 해당 유저의 FCM TOKEN 저장하면 됩니다. Front와 상의 후 삭제예정 - public void saveFcmToken(Long key, String value) { + public void saveFcmToken(Long memberId, String fcmToken) { stringRedisRepository.save( - String.valueOf(requireNonNull(key)), - requireNonNull(value), + String.valueOf(requireNonNull(memberId)), + requireNonNull(fcmToken), Duration.ofDays(EXPIRE_FCM_TOKEN) ); } - public void saveKnockNotification(String key) { + public void saveKnockNotification(String knockKey) { stringRedisRepository.save( - requireNonNull(key), + requireNonNull(knockKey), BLANK, Duration.ofHours(EXPIRE_KNOCK) ); diff --git a/src/main/java/com/moabam/api/infrastructure/fcm/FcmService.java b/src/main/java/com/moabam/api/infrastructure/fcm/FcmService.java new file mode 100644 index 00000000..e995688c --- /dev/null +++ b/src/main/java/com/moabam/api/infrastructure/fcm/FcmService.java @@ -0,0 +1,26 @@ +package com.moabam.api.infrastructure.fcm; + +import org.springframework.stereotype.Service; + +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.Message; +import com.google.firebase.messaging.Notification; +import com.moabam.api.application.notification.NotificationMapper; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class FcmService { + + private final FirebaseMessaging firebaseMessaging; + + public void sendAsyncFcm(String fcmToken, String notificationBody) { + Notification notification = NotificationMapper.toNotification(notificationBody); + + if (fcmToken != null) { + Message message = NotificationMapper.toMessageEntity(notification, fcmToken); + firebaseMessaging.sendAsync(message); + } + } +} diff --git a/src/main/java/com/moabam/api/infrastructure/redis/HashTemplateRepository.java b/src/main/java/com/moabam/api/infrastructure/redis/HashRedisRepository.java similarity index 85% rename from src/main/java/com/moabam/api/infrastructure/redis/HashTemplateRepository.java rename to src/main/java/com/moabam/api/infrastructure/redis/HashRedisRepository.java index 12b1d291..0af79bc2 100644 --- a/src/main/java/com/moabam/api/infrastructure/redis/HashTemplateRepository.java +++ b/src/main/java/com/moabam/api/infrastructure/redis/HashRedisRepository.java @@ -13,18 +13,19 @@ import com.moabam.global.error.model.ErrorMessage; @Repository -public class HashTemplateRepository { +public class HashRedisRepository { private final RedisTemplate redisTemplate; private final HashOperations hashOperations; private final Jackson2HashMapper hashMapper; - public HashTemplateRepository(RedisTemplate redisTemplate) { + public HashRedisRepository(RedisTemplate redisTemplate) { this.redisTemplate = redisTemplate; hashOperations = redisTemplate.opsForHash(); hashMapper = new Jackson2HashMapper(false); } + // redisTemplate.opsForHash().putAll(key, hashMapper.toHash(value)); public void save(String key, Object value, Duration timeout) { hashOperations.putAll(key, hashMapper.toHash(value)); redisTemplate.expire(key, timeout); @@ -37,7 +38,7 @@ public void delete(String key) { public Object get(String key) { Map memberToken = hashOperations.entries(key); - if (memberToken.size() == 0) { + if (memberToken.isEmpty()) { throw new UnauthorizedException(ErrorMessage.AUTHENTICATE_FAIL); } diff --git a/src/main/java/com/moabam/api/infrastructure/redis/StringRedisRepository.java b/src/main/java/com/moabam/api/infrastructure/redis/StringRedisRepository.java index 9d877dae..0b55a397 100644 --- a/src/main/java/com/moabam/api/infrastructure/redis/StringRedisRepository.java +++ b/src/main/java/com/moabam/api/infrastructure/redis/StringRedisRepository.java @@ -2,7 +2,7 @@ import java.time.Duration; -import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Repository; import lombok.RequiredArgsConstructor; @@ -11,25 +11,25 @@ @RequiredArgsConstructor public class StringRedisRepository { - private final StringRedisTemplate stringRedisTemplate; + private final RedisTemplate redisTemplate; public void save(String key, String value, Duration timeout) { - stringRedisTemplate + redisTemplate .opsForValue() .set(key, value, timeout); } public void delete(String key) { - stringRedisTemplate.delete(key); + redisTemplate.delete(key); } public String get(String key) { - return stringRedisTemplate + return redisTemplate .opsForValue() .get(key); } public Boolean hasKey(String key) { - return stringRedisTemplate.hasKey(key); + return redisTemplate.hasKey(key); } } diff --git a/src/main/java/com/moabam/global/common/util/GlobalConstant.java b/src/main/java/com/moabam/global/common/util/GlobalConstant.java index 8f43ec67..333f0cd5 100644 --- a/src/main/java/com/moabam/global/common/util/GlobalConstant.java +++ b/src/main/java/com/moabam/global/common/util/GlobalConstant.java @@ -14,8 +14,6 @@ public class GlobalConstant { public static final String SPACE = " "; public static final int ONE_HOUR = 1; public static final int HOURS_IN_A_DAY = 24; - public static final String KNOCK_KEY = "room_%s_member_%s_knocks_%s"; - public static final String FIREBASE_PATH = "config/moabam-firebase.json"; public static final int LEVEL_DIVISOR = 10; } diff --git a/src/main/java/com/moabam/global/config/FcmConfig.java b/src/main/java/com/moabam/global/config/FcmConfig.java index 678248b5..115e6091 100644 --- a/src/main/java/com/moabam/global/config/FcmConfig.java +++ b/src/main/java/com/moabam/global/config/FcmConfig.java @@ -1,7 +1,5 @@ package com.moabam.global.config; -import static com.moabam.global.common.util.GlobalConstant.*; - import java.io.IOException; import java.io.InputStream; @@ -24,6 +22,8 @@ @EnableScheduling public class FcmConfig { + private static final String FIREBASE_PATH = "config/moabam-firebase.json"; + @Bean public FirebaseMessaging firebaseMessaging() { try (InputStream inputStream = new ClassPathResource(FIREBASE_PATH).getInputStream()) { diff --git a/src/main/java/com/moabam/global/config/RedisConfig.java b/src/main/java/com/moabam/global/config/RedisConfig.java index 3c154692..fef4a99e 100644 --- a/src/main/java/com/moabam/global/config/RedisConfig.java +++ b/src/main/java/com/moabam/global/config/RedisConfig.java @@ -7,7 +7,6 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; @@ -26,20 +25,11 @@ public RedisConnectionFactory redisConnectionFactory() { return new LettuceConnectionFactory(redisHost, redisPort); } - @Bean - public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) { - StringRedisTemplate stringRedisTemplate = new StringRedisTemplate(); - stringRedisTemplate.setKeySerializer(new StringRedisSerializer()); - stringRedisTemplate.setValueSerializer(new StringRedisSerializer()); - stringRedisTemplate.setConnectionFactory(redisConnectionFactory); - - return stringRedisTemplate; - } - @Bean public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate redisTemplate = new RedisTemplate<>(); - redisTemplate.setDefaultSerializer(new Jackson2JsonRedisSerializer<>(Object.class)); + redisTemplate.setKeySerializer(new StringRedisSerializer()); + redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class)); redisTemplate.setConnectionFactory(redisConnectionFactory); return redisTemplate; diff --git a/src/main/resources/static/docs/coupon.html b/src/main/resources/static/docs/coupon.html index c9cdad6e..432d567d 100644 --- a/src/main/resources/static/docs/coupon.html +++ b/src/main/resources/static/docs/coupon.html @@ -461,7 +461,7 @@

요청

POST /admins/coupons HTTP/1.1
 Content-Type: application/json;charset=UTF-8
-Content-Length: 200
+Content-Length: 192
 Host: localhost:8080
 
 {
@@ -483,7 +483,7 @@ 

응답

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 64 +Content-Length: 62 { "message" : "쿠폰의 이름이 중복되었습니다." @@ -514,7 +514,7 @@

응답

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 58 +Content-Length: 56 { "message" : "존재하지 않는 쿠폰입니다." @@ -546,7 +546,7 @@

응답

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 58 +Content-Length: 56 { "message" : "존재하지 않는 쿠폰입니다." @@ -569,7 +569,7 @@

요청

POST /coupons/search HTTP/1.1
 Content-Type: application/json;charset=UTF-8
-Content-Length: 88
+Content-Length: 84
 Host: localhost:8080
 
 {
diff --git a/src/main/resources/static/docs/notification.html b/src/main/resources/static/docs/notification.html
index c15a126c..d84209a5 100644
--- a/src/main/resources/static/docs/notification.html
+++ b/src/main/resources/static/docs/notification.html
@@ -473,7 +473,7 @@ 

응답

Vary: Access-Control-Request-Method Vary: Access-Control-Request-Headers Content-Type: application/json -Content-Length: 66 +Content-Length: 64 { "message" : "이미 콕 알림을 보낸 대상입니다." diff --git a/src/test/java/com/moabam/api/application/AuthorizationServiceTest.java b/src/test/java/com/moabam/api/application/AuthorizationServiceTest.java index 0cbef779..77cacbc3 100644 --- a/src/test/java/com/moabam/api/application/AuthorizationServiceTest.java +++ b/src/test/java/com/moabam/api/application/AuthorizationServiceTest.java @@ -28,13 +28,13 @@ import com.moabam.api.application.auth.OAuth2AuthorizationServerRequestService; import com.moabam.api.application.auth.mapper.AuthorizationMapper; import com.moabam.api.application.member.MemberService; +import com.moabam.api.domain.auth.repository.TokenRepository; import com.moabam.api.dto.auth.AuthorizationCodeRequest; import com.moabam.api.dto.auth.AuthorizationCodeResponse; import com.moabam.api.dto.auth.AuthorizationTokenInfoResponse; import com.moabam.api.dto.auth.AuthorizationTokenRequest; import com.moabam.api.dto.auth.AuthorizationTokenResponse; import com.moabam.api.dto.auth.LoginResponse; -import com.moabam.api.infrastructure.redis.TokenRepository; import com.moabam.global.auth.model.AuthorizationMember; import com.moabam.global.auth.model.PublicClaim; import com.moabam.global.common.util.cookie.CookieDevUtils; diff --git a/src/test/java/com/moabam/api/application/notification/NotificationServiceTest.java b/src/test/java/com/moabam/api/application/notification/NotificationServiceTest.java index f395e6c8..1dc9b4bc 100644 --- a/src/test/java/com/moabam/api/application/notification/NotificationServiceTest.java +++ b/src/test/java/com/moabam/api/application/notification/NotificationServiceTest.java @@ -14,13 +14,12 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import com.google.firebase.messaging.FirebaseMessaging; -import com.google.firebase.messaging.Message; 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.repository.ParticipantSearchRepository; import com.moabam.api.dto.notification.KnockNotificationStatusResponse; -import com.moabam.api.infrastructure.redis.NotificationRepository; +import com.moabam.api.infrastructure.fcm.FcmService; import com.moabam.global.auth.model.AuthorizationMember; import com.moabam.global.auth.model.AuthorizationThreadLocal; import com.moabam.global.error.exception.ConflictException; @@ -39,7 +38,7 @@ class NotificationServiceTest { private RoomService roomService; @Mock - private FirebaseMessaging firebaseMessaging; + private FcmService fcmService; @Mock private NotificationRepository notificationRepository; @@ -63,7 +62,7 @@ void notificationService_sendKnockNotification() { notificationService.sendKnockNotification(member, 2L, 1L); // Then - verify(firebaseMessaging).sendAsync(any(Message.class)); + verify(fcmService).sendAsyncFcm(any(String.class), any(String.class)); verify(notificationRepository).saveKnockNotification(any(String.class)); } @@ -125,7 +124,7 @@ void notificationService_sendCertificationTimeNotification(List par notificationService.sendCertificationTimeNotification(); // Then - verify(firebaseMessaging, times(3)).sendAsync(any(Message.class)); + verify(fcmService, times(3)).sendAsyncFcm(any(String.class), any(String.class)); } @WithMember @@ -141,7 +140,7 @@ void notificationService_sendCertificationTimeNotification_NoFirebaseMessaging(L notificationService.sendCertificationTimeNotification(); // Then - verify(firebaseMessaging, times(0)).sendAsync(any(Message.class)); + verify(fcmService, times(0)).sendAsyncFcm(any(String.class), any(String.class)); } @WithMember diff --git a/src/test/java/com/moabam/api/infrastructure/redis/NotificationRepositoryTest.java b/src/test/java/com/moabam/api/domain/notification/repository/NotificationRepositoryTest.java similarity index 97% rename from src/test/java/com/moabam/api/infrastructure/redis/NotificationRepositoryTest.java rename to src/test/java/com/moabam/api/domain/notification/repository/NotificationRepositoryTest.java index ae30de5d..6822b175 100644 --- a/src/test/java/com/moabam/api/infrastructure/redis/NotificationRepositoryTest.java +++ b/src/test/java/com/moabam/api/domain/notification/repository/NotificationRepositoryTest.java @@ -1,4 +1,4 @@ -package com.moabam.api.infrastructure.redis; +package com.moabam.api.domain.notification.repository; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; @@ -12,6 +12,8 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import com.moabam.api.infrastructure.redis.StringRedisRepository; + @ExtendWith(MockitoExtension.class) class NotificationRepositoryTest { diff --git a/src/test/java/com/moabam/api/domain/repository/TokenRepostiroyTest.java b/src/test/java/com/moabam/api/domain/repository/TokenRepostiroyTest.java index 5f8a473f..3b5d6863 100644 --- a/src/test/java/com/moabam/api/domain/repository/TokenRepostiroyTest.java +++ b/src/test/java/com/moabam/api/domain/repository/TokenRepostiroyTest.java @@ -14,9 +14,9 @@ import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; +import com.moabam.api.domain.auth.repository.TokenRepository; import com.moabam.api.dto.auth.TokenSaveValue; -import com.moabam.api.infrastructure.redis.HashTemplateRepository; -import com.moabam.api.infrastructure.redis.TokenRepository; +import com.moabam.api.infrastructure.redis.HashRedisRepository; import com.moabam.support.fixture.TokenSaveValueFixture; @ExtendWith(MockitoExtension.class) @@ -26,13 +26,13 @@ class TokenRepostiroyTest { TokenRepository tokenRepository; @Mock - HashTemplateRepository hashTemplateRepository; + HashRedisRepository hashRedisRepository; @DisplayName("토큰 저장 성공") @Test void save_token_suceess() { // Given - willDoNothing().given(hashTemplateRepository).save(any(), any(TokenSaveValue.class), any(Duration.class)); + willDoNothing().given(hashRedisRepository).save(any(), any(TokenSaveValue.class), any(Duration.class)); // When + Then Assertions.assertThatNoException() @@ -44,7 +44,7 @@ void save_token_suceess() { void token_get_success() { // given willReturn(TokenSaveValueFixture.tokenSaveValue("token")) - .given(hashTemplateRepository).get(anyString()); + .given(hashRedisRepository).get(anyString()); // when TokenSaveValue tokenSaveValue = tokenRepository.getTokenSaveValue(123L); diff --git a/src/test/java/com/moabam/api/infrastructure/fcm/FcmServiceTest.java b/src/test/java/com/moabam/api/infrastructure/fcm/FcmServiceTest.java new file mode 100644 index 00000000..c7a331e3 --- /dev/null +++ b/src/test/java/com/moabam/api/infrastructure/fcm/FcmServiceTest.java @@ -0,0 +1,43 @@ +package com.moabam.api.infrastructure.fcm; + +import static org.mockito.Mockito.*; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.mock.mockito.MockBean; + +import com.google.firebase.messaging.FirebaseMessaging; +import com.google.firebase.messaging.Message; +import com.moabam.global.config.FcmConfig; + +@SpringBootTest(classes = {FcmConfig.class, FcmService.class}) +class FcmServiceTest { + + @Autowired + private FcmService fcmService; + + @MockBean + private FirebaseMessaging firebaseMessaging; + + @DisplayName("비동기 FCM 알림을 성공적으로 보낸다. - Void") + @Test + void fcmService_sendAsyncFcm() { + // When + fcmService.sendAsyncFcm("FCM-TOKEN", "알림"); + + // Then + verify(firebaseMessaging).sendAsync(any(Message.class)); + } + + @DisplayName("FCM 토큰이 null이여서 비동기 FCM 알림을 보내지. - Void") + @Test + void fcmService_sendAsyncFcm_null() { + // When + fcmService.sendAsyncFcm(null, "알림"); + + // Then + verify(firebaseMessaging, times(0)).sendAsync(any(Message.class)); + } +} diff --git a/src/test/java/com/moabam/api/infrastructure/redis/HashTemplateRepositoryTest.java b/src/test/java/com/moabam/api/infrastructure/redis/HashRedisRepositoryTest.java similarity index 79% rename from src/test/java/com/moabam/api/infrastructure/redis/HashTemplateRepositoryTest.java rename to src/test/java/com/moabam/api/infrastructure/redis/HashRedisRepositoryTest.java index 9998b667..ab0cd833 100644 --- a/src/test/java/com/moabam/api/infrastructure/redis/HashTemplateRepositoryTest.java +++ b/src/test/java/com/moabam/api/infrastructure/redis/HashRedisRepositoryTest.java @@ -19,11 +19,11 @@ import com.moabam.global.error.model.ErrorMessage; import com.moabam.support.fixture.TokenSaveValueFixture; -@SpringBootTest(classes = {RedisConfig.class, EmbeddedRedisConfig.class, HashTemplateRepository.class}) -class HashTemplateRepositoryTest { +@SpringBootTest(classes = {RedisConfig.class, EmbeddedRedisConfig.class, HashRedisRepository.class}) +class HashRedisRepositoryTest { @Autowired - private HashTemplateRepository hashTemplateRepository; + private HashRedisRepository hashRedisRepository; String key = "auth_123"; String token = "token"; @@ -33,19 +33,19 @@ class HashTemplateRepositoryTest { @BeforeEach void setUp() { - hashTemplateRepository.save(key, (Object)tokenSaveValue, duration); + hashRedisRepository.save(key, (Object)tokenSaveValue, duration); } @AfterEach void delete() { - hashTemplateRepository.delete(key); + hashRedisRepository.delete(key); } @DisplayName("레디스에 hash 저장 성공") @Test void hashTemplate_repository_save_success() { // Given + When - TokenSaveValue object = (TokenSaveValue)hashTemplateRepository.get(key); + TokenSaveValue object = (TokenSaveValue)hashRedisRepository.get(key); // Then assertAll( @@ -58,10 +58,10 @@ void hashTemplate_repository_save_success() { @Test void delete_and_get_null() { // Given - hashTemplateRepository.delete(key); + hashRedisRepository.delete(key); // When + Then - assertThatThrownBy(() -> hashTemplateRepository.get(key)) + assertThatThrownBy(() -> hashRedisRepository.get(key)) .isInstanceOf(UnauthorizedException.class) .hasMessage(ErrorMessage.AUTHENTICATE_FAIL.getMessage()); } @@ -70,7 +70,7 @@ void delete_and_get_null() { @Test void valid_token_failby_token_is_null() { // Given + When + Then - assertThatThrownBy(() -> hashTemplateRepository.get("0")) + assertThatThrownBy(() -> hashRedisRepository.get("0")) .isInstanceOf(UnauthorizedException.class) .hasMessage(ErrorMessage.AUTHENTICATE_FAIL.getMessage()); } diff --git a/src/test/java/com/moabam/api/presentation/NotificationControllerTest.java b/src/test/java/com/moabam/api/presentation/NotificationControllerTest.java index 2b2f8bda..86cd81f5 100644 --- a/src/test/java/com/moabam/api/presentation/NotificationControllerTest.java +++ b/src/test/java/com/moabam/api/presentation/NotificationControllerTest.java @@ -1,6 +1,5 @@ package com.moabam.api.presentation; -import static com.moabam.global.common.util.GlobalConstant.*; import static org.mockito.BDDMockito.*; import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*; import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*; @@ -25,9 +24,9 @@ import com.google.firebase.messaging.Message; import com.moabam.api.domain.member.Member; import com.moabam.api.domain.member.repository.MemberRepository; +import com.moabam.api.domain.notification.repository.NotificationRepository; import com.moabam.api.domain.room.Room; import com.moabam.api.domain.room.repository.RoomRepository; -import com.moabam.api.infrastructure.redis.NotificationRepository; import com.moabam.api.infrastructure.redis.StringRedisRepository; import com.moabam.global.error.model.ErrorMessage; import com.moabam.support.annotation.WithMember; @@ -42,6 +41,8 @@ @AutoConfigureRestDocs class NotificationControllerTest extends WithoutFilterSupporter { + private static final String KNOCK_KEY = "room_%s_member_%s_knocks_%s"; + @Autowired private MockMvc mockMvc;