diff --git a/src/main/java/com/m3pro/groundflip/controller/UserController.java b/src/main/java/com/m3pro/groundflip/controller/UserController.java index e7e7c948..b360b08c 100644 --- a/src/main/java/com/m3pro/groundflip/controller/UserController.java +++ b/src/main/java/com/m3pro/groundflip/controller/UserController.java @@ -5,6 +5,7 @@ import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; @@ -13,9 +14,11 @@ import org.springframework.web.multipart.MultipartFile; import com.m3pro.groundflip.domain.dto.Response; +import com.m3pro.groundflip.domain.dto.user.FcmTokenRequest; import com.m3pro.groundflip.domain.dto.user.UserDeleteRequest; import com.m3pro.groundflip.domain.dto.user.UserInfoRequest; import com.m3pro.groundflip.domain.dto.user.UserInfoResponse; +import com.m3pro.groundflip.service.FcmService; import com.m3pro.groundflip.service.UserService; import io.swagger.v3.oas.annotations.Operation; @@ -31,6 +34,7 @@ @SecurityRequirement(name = "Authorization") public class UserController { private final UserService userService; + private final FcmService fcmService; @Operation(summary = "사용자 기본 정보 조회", description = "닉네임, id, 출생년도, 성별, 프로필 사진, 그룹이름, 그룹 id 를 조회 한다.") @GetMapping("/{userId}") @@ -62,4 +66,13 @@ public Response putUserInfo( userService.deleteUser(userId, userDeleteRequest); return Response.createSuccessWithNoData(); } + + @Operation(summary = "FCM 등록 토큰 등록", description = "푸시 알림을 위한 FCM 등록 토큰을 저장한다.") + @PostMapping("/fcm-token") + public Response postFcmToken( + @RequestBody FcmTokenRequest fcmTokenRequest + ) { + fcmService.registerFcmToken(fcmTokenRequest); + return Response.createSuccessWithNoData(); + } } diff --git a/src/main/java/com/m3pro/groundflip/domain/dto/user/FcmTokenRequest.java b/src/main/java/com/m3pro/groundflip/domain/dto/user/FcmTokenRequest.java new file mode 100644 index 00000000..17dab09f --- /dev/null +++ b/src/main/java/com/m3pro/groundflip/domain/dto/user/FcmTokenRequest.java @@ -0,0 +1,20 @@ +package com.m3pro.groundflip.domain.dto.user; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Schema(title = "FCM 등록 토큰 저장") +public class FcmTokenRequest { + @Schema(description = "사용자 Id", example = "125") + private Long userId; + + @Schema(description = "사용자 fcm token", example = "sdfghweredasdvasdfq/weqwefs;dvsdghrthwdffevdrer") + private String fcmToken; +} diff --git a/src/main/java/com/m3pro/groundflip/domain/entity/FcmToken.java b/src/main/java/com/m3pro/groundflip/domain/entity/FcmToken.java new file mode 100644 index 00000000..b0dd472a --- /dev/null +++ b/src/main/java/com/m3pro/groundflip/domain/entity/FcmToken.java @@ -0,0 +1,37 @@ +package com.m3pro.groundflip.domain.entity; + +import com.m3pro.groundflip.domain.entity.global.BaseTimeEntity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.JoinColumn; +import jakarta.persistence.OneToOne; +import jakarta.persistence.Table; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +@Table(name = "fcm_token") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@Builder +public class FcmToken extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "fcm_token_id") + private Long id; + + private String token; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; +} diff --git a/src/main/java/com/m3pro/groundflip/domain/entity/global/BaseTimeEntity.java b/src/main/java/com/m3pro/groundflip/domain/entity/global/BaseTimeEntity.java index abac1d16..83e0bf94 100644 --- a/src/main/java/com/m3pro/groundflip/domain/entity/global/BaseTimeEntity.java +++ b/src/main/java/com/m3pro/groundflip/domain/entity/global/BaseTimeEntity.java @@ -22,7 +22,11 @@ public class BaseTimeEntity { @LastModifiedDate private LocalDateTime modifiedAt; - public void updateModifiedAt() { + public void updateModifiedAtToNow() { modifiedAt = LocalDateTime.now(); } + + public void updateModifiedAt(LocalDateTime localDateTime) { + modifiedAt = localDateTime; + } } diff --git a/src/main/java/com/m3pro/groundflip/repository/FcmTokenRepository.java b/src/main/java/com/m3pro/groundflip/repository/FcmTokenRepository.java new file mode 100644 index 00000000..b75cadee --- /dev/null +++ b/src/main/java/com/m3pro/groundflip/repository/FcmTokenRepository.java @@ -0,0 +1,14 @@ +package com.m3pro.groundflip.repository; + +import java.util.Optional; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.m3pro.groundflip.domain.entity.FcmToken; +import com.m3pro.groundflip.domain.entity.User; + +public interface FcmTokenRepository extends JpaRepository { + Optional findByUser(User user); + + void deleteByUser(User user); +} diff --git a/src/main/java/com/m3pro/groundflip/service/FcmService.java b/src/main/java/com/m3pro/groundflip/service/FcmService.java new file mode 100644 index 00000000..c47c4aed --- /dev/null +++ b/src/main/java/com/m3pro/groundflip/service/FcmService.java @@ -0,0 +1,43 @@ +package com.m3pro.groundflip.service; + +import java.util.Optional; + +import org.springframework.stereotype.Service; + +import com.m3pro.groundflip.domain.dto.user.FcmTokenRequest; +import com.m3pro.groundflip.domain.entity.FcmToken; +import com.m3pro.groundflip.domain.entity.User; +import com.m3pro.groundflip.exception.AppException; +import com.m3pro.groundflip.exception.ErrorCode; +import com.m3pro.groundflip.repository.FcmTokenRepository; +import com.m3pro.groundflip.repository.UserRepository; + +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +@Service +@RequiredArgsConstructor +@Slf4j +public class FcmService { + private final UserRepository userRepository; + private final FcmTokenRepository fcmTokenRepository; + + @Transactional + public void registerFcmToken(FcmTokenRequest fcmTokenRequest) { + Long userId = fcmTokenRequest.getUserId(); + User user = userRepository.findById(userId).orElseThrow(() -> new AppException(ErrorCode.USER_NOT_FOUND)); + Optional fcmToken = fcmTokenRepository.findByUser(user); + + if (fcmToken.isPresent()) { + fcmToken.get().updateModifiedAtToNow(); + } else { + fcmTokenRepository.save( + FcmToken.builder() + .user(user) + .token(fcmTokenRequest.getFcmToken()) + .build() + ); + } + } +} diff --git a/src/main/java/com/m3pro/groundflip/service/PixelService.java b/src/main/java/com/m3pro/groundflip/service/PixelService.java index 9923ba74..7335af41 100644 --- a/src/main/java/com/m3pro/groundflip/service/PixelService.java +++ b/src/main/java/com/m3pro/groundflip/service/PixelService.java @@ -150,7 +150,7 @@ private void occupyPixel(PixelOccupyRequest pixelOccupyRequest) { Pixel targetPixel = pixelRepository.findByXAndY(pixelOccupyRequest.getX(), pixelOccupyRequest.getY()) .orElseThrow(() -> new AppException(ErrorCode.PIXEL_NOT_FOUND)); - updateRankingOnCache(targetPixel, occupyingUserId); + rankingService.updateRanking(targetPixel, occupyingUserId); updatePixelOwner(targetPixel, occupyingUserId); updatePixelAddress(targetPixel); @@ -159,7 +159,7 @@ private void occupyPixel(PixelOccupyRequest pixelOccupyRequest) { private void updatePixelOwner(Pixel targetPixel, Long occupyingUserId) { if (Objects.equals(targetPixel.getUserId(), occupyingUserId)) { - targetPixel.updateModifiedAt(); + targetPixel.updateModifiedAtToNow(); } else { targetPixel.updateUserId(occupyingUserId); } @@ -178,32 +178,6 @@ private void updatePixelAddress(Pixel targetPixel) { } } - /** - * 레디스 상에서 랭킹을 조정한다. - * @param targetPixel 랭킹을 조정할 픽셀 - * @param occupyingUserId 현재 픽셀을 방문한 유저 - * @return - * @author 김민욱 - */ - private void updateRankingOnCache(Pixel targetPixel, Long occupyingUserId) { - Long originalOwnerUserId = targetPixel.getUserId(); - LocalDateTime thisWeekStart = DateUtils.getThisWeekStartDate().atTime(0, 0); - LocalDateTime modifiedAt = targetPixel.getModifiedAt(); - - if (Objects.equals(originalOwnerUserId, occupyingUserId)) { - if (modifiedAt.isAfter(thisWeekStart)) { - return; - } - rankingService.increaseCurrentPixelCount(occupyingUserId); - } else { - if (originalOwnerUserId == null || modifiedAt.isBefore(thisWeekStart)) { - rankingService.increaseCurrentPixelCount(occupyingUserId); - } else { - rankingService.updateRankingAfterOccupy(occupyingUserId, originalOwnerUserId); - } - } - } - /** * 개인 기록 모드에서 픽셀 방문 기록을 가져온다 * @param pixelId 기록을 조회할 픽셀 diff --git a/src/main/java/com/m3pro/groundflip/service/RankingService.java b/src/main/java/com/m3pro/groundflip/service/RankingService.java index 4ea38f20..49822954 100644 --- a/src/main/java/com/m3pro/groundflip/service/RankingService.java +++ b/src/main/java/com/m3pro/groundflip/service/RankingService.java @@ -1,8 +1,10 @@ package com.m3pro.groundflip.service; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -11,6 +13,7 @@ import com.m3pro.groundflip.domain.dto.ranking.Ranking; import com.m3pro.groundflip.domain.dto.ranking.UserRankingResponse; +import com.m3pro.groundflip.domain.entity.Pixel; import com.m3pro.groundflip.domain.entity.RankingHistory; import com.m3pro.groundflip.domain.entity.User; import com.m3pro.groundflip.exception.AppException; @@ -31,20 +34,23 @@ public class RankingService { private final UserRepository userRepository; private final RankingHistoryRepository rankingHistoryRepository; - /** - * 현재 픽셀의 수를 1 증가 시킨다. - * @param userId 사용자 id - */ - public void increaseCurrentPixelCount(Long userId) { - rankingRedisRepository.increaseCurrentPixelCount(userId); - } + public void updateRanking(Pixel targetPixel, Long occupyingUserId) { + Long originalOwnerUserId = targetPixel.getUserId(); + LocalDateTime thisWeekStart = DateUtils.getThisWeekStartDate().atTime(0, 0); + LocalDateTime modifiedAt = targetPixel.getModifiedAt(); - /** - * 현재 픽셀의 수를 1 감소 시킨다. - * @param userId 사용자 id - */ - public void decreaseCurrentPixelCount(Long userId) { - rankingRedisRepository.decreaseCurrentPixelCount(userId); + if (Objects.equals(originalOwnerUserId, occupyingUserId)) { + if (modifiedAt.isAfter(thisWeekStart)) { + return; + } + rankingRedisRepository.increaseCurrentPixelCount(occupyingUserId); + } else { + if (originalOwnerUserId == null || modifiedAt.isBefore(thisWeekStart)) { + rankingRedisRepository.increaseCurrentPixelCount(occupyingUserId); + } else { + updateRankingAfterOccupy(occupyingUserId, originalOwnerUserId); + } + } } /** @@ -53,8 +59,8 @@ public void decreaseCurrentPixelCount(Long userId) { * @param deprivedUserId 픽셀을 뺴앗긴 유저 */ public void updateRankingAfterOccupy(Long occupyingUserId, Long deprivedUserId) { - increaseCurrentPixelCount(occupyingUserId); - decreaseCurrentPixelCount(deprivedUserId); + rankingRedisRepository.increaseCurrentPixelCount(occupyingUserId); + rankingRedisRepository.decreaseCurrentPixelCount(deprivedUserId); } /** diff --git a/src/main/java/com/m3pro/groundflip/service/UserService.java b/src/main/java/com/m3pro/groundflip/service/UserService.java index 23d7ad3e..a6d88e7e 100644 --- a/src/main/java/com/m3pro/groundflip/service/UserService.java +++ b/src/main/java/com/m3pro/groundflip/service/UserService.java @@ -21,6 +21,7 @@ import com.m3pro.groundflip.exception.ErrorCode; import com.m3pro.groundflip.jwt.JwtProvider; import com.m3pro.groundflip.repository.AppleRefreshTokenRepository; +import com.m3pro.groundflip.repository.FcmTokenRepository; import com.m3pro.groundflip.repository.RankingRedisRepository; import com.m3pro.groundflip.repository.UserCommunityRepository; import com.m3pro.groundflip.repository.UserRepository; @@ -39,6 +40,7 @@ public class UserService { private final UserRepository userRepository; private final AppleRefreshTokenRepository appleRefreshTokenRepository; private final UserCommunityRepository userCommunityRepository; + private final FcmTokenRepository fcmTokenRepository; private final S3Uploader s3Uploader; private final JwtProvider jwtProvider; private final AppleApiClient appleApiClient; @@ -122,6 +124,8 @@ public void deleteUser(Long userId, UserDeleteRequest userDeleteRequest) { if (deletedUser.getProvider() == Provider.APPLE) { revokeAppleToken(deletedUser.getId()); } + fcmTokenRepository.deleteByUser(deletedUser); + deletedUser.updateBirthYear(convertToDate(1900)); deletedUser.updateNickName(null); deletedUser.updateProfileImage(null); diff --git a/src/test/java/com/m3pro/groundflip/service/FcmServiceTest.java b/src/test/java/com/m3pro/groundflip/service/FcmServiceTest.java new file mode 100644 index 00000000..96ce4b4b --- /dev/null +++ b/src/test/java/com/m3pro/groundflip/service/FcmServiceTest.java @@ -0,0 +1,75 @@ +package com.m3pro.groundflip.service; + +import static org.assertj.core.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.*; + +import java.util.Optional; + +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import com.m3pro.groundflip.domain.dto.user.FcmTokenRequest; +import com.m3pro.groundflip.domain.entity.FcmToken; +import com.m3pro.groundflip.domain.entity.User; +import com.m3pro.groundflip.exception.AppException; +import com.m3pro.groundflip.exception.ErrorCode; +import com.m3pro.groundflip.repository.FcmTokenRepository; +import com.m3pro.groundflip.repository.UserRepository; + +@ExtendWith(MockitoExtension.class) +class FcmServiceTest { + private static final Long testUserId = 1L; + private static final String testFcmToken = "test token"; + private static FcmTokenRequest fcmTokenRequest; + @Mock + private UserRepository userRepository; + @Mock + private FcmTokenRepository fcmTokenRepository; + @InjectMocks + private FcmService fcmService; + + @BeforeAll + static void beforeAll() { + fcmTokenRequest = new FcmTokenRequest(testUserId, testFcmToken); + } + + @Test + @DisplayName("[registerFcmToken] user 가 없는 경우 에러 발생") + void registerFcmToken_UserNotFound() { + when(userRepository.findById(testUserId)).thenReturn(Optional.empty()); + + AppException exception = assertThrows(AppException.class, () -> fcmService.registerFcmToken(fcmTokenRequest)); + assertThat(exception.getErrorCode()).isEqualTo(ErrorCode.USER_NOT_FOUND); + } + + @Test + @DisplayName("[registerFcmToken] fcm 토큰 새로 등록") + void registerFcmToken_RegisterNewToken() { + User user = User.builder().id(1L).email("test@test.com").build(); + when(userRepository.findById(testUserId)).thenReturn(Optional.of(user)); + when(fcmTokenRepository.findByUser(user)).thenReturn(Optional.empty()); + + fcmService.registerFcmToken(fcmTokenRequest); + + verify(fcmTokenRepository, times(1)).save(any()); + } + + @Test + @DisplayName("[registerFcmToken] fcm 토큰이 이미 등록된 경우 수정 날짜만 변경") + void registerFcmToken_UpdateModifiedDate() { + User user = User.builder().id(1L).email("test@test.com").build(); + FcmToken fcmToken = FcmToken.builder().id(1L).token(testFcmToken).user(user).build(); + when(userRepository.findById(testUserId)).thenReturn(Optional.of(user)); + when(fcmTokenRepository.findByUser(user)).thenReturn(Optional.of(fcmToken)); + + fcmService.registerFcmToken(fcmTokenRequest); + + assertThat(fcmToken.getModifiedAt()).isNotNull(); + } +} \ No newline at end of file diff --git a/src/test/java/com/m3pro/groundflip/service/RankingServiceTest.java b/src/test/java/com/m3pro/groundflip/service/RankingServiceTest.java index 856a3f47..5113eb7f 100644 --- a/src/test/java/com/m3pro/groundflip/service/RankingServiceTest.java +++ b/src/test/java/com/m3pro/groundflip/service/RankingServiceTest.java @@ -21,6 +21,7 @@ import com.m3pro.groundflip.domain.dto.ranking.Ranking; import com.m3pro.groundflip.domain.dto.ranking.UserRankingResponse; +import com.m3pro.groundflip.domain.entity.Pixel; import com.m3pro.groundflip.domain.entity.RankingHistory; import com.m3pro.groundflip.domain.entity.User; import com.m3pro.groundflip.exception.AppException; @@ -28,6 +29,7 @@ import com.m3pro.groundflip.repository.RankingHistoryRepository; import com.m3pro.groundflip.repository.RankingRedisRepository; import com.m3pro.groundflip.repository.UserRepository; +import com.m3pro.groundflip.util.DateUtils; @ExtendWith(MockitoExtension.class) class RankingServiceTest { @@ -46,27 +48,67 @@ void init() { } @Test - @DisplayName("[increaseCurrentPixelCount] userId 에 해당하는 현재 소유 픽셀의 개수를 1 증가시킨다.") - void increaseCurrentPixelCountTest() { - Long userId = 1L; + @DisplayName("[updateRanking] 이번주에 이미 차지한 땅이라면 랭킹 업데이트 하지 않는다.") + void updateRanking_NoUpdate() { + Long occupyingUserId = 1L; + Pixel targetPixel = Pixel.builder().userId(occupyingUserId).build(); + targetPixel.updateModifiedAt(DateUtils.getThisWeekStartDate().atTime(0, 0, 0).plusDays(1)); - rankingService.increaseCurrentPixelCount(userId); + rankingService.updateRanking(targetPixel, occupyingUserId); - verify(rankingRedisRepository, times(1)).increaseCurrentPixelCount(userId); + verify(rankingRedisRepository, never()).increaseCurrentPixelCount(occupyingUserId); } @Test - @DisplayName("[decreasePixelCount] userId 에 해당하는 현재 소유 픽셀의 개수를 1 감소시킨다.") - void decreasePixelCountTest() { - Long userId = 1L; + @DisplayName("[updateRanking] 저번주에 차지한 땅이고 차지한 사람과 차지하려는 사람이 같다면 랭킹을 업데이트한다.") + void updateRanking_UpdateBeforeThisWeek() { + Long occupyingUserId = 1L; + Pixel targetPixel = Pixel.builder().userId(occupyingUserId).build(); + targetPixel.updateModifiedAt(DateUtils.getThisWeekStartDate().atTime(0, 0, 0).minusDays(3)); + + rankingService.updateRanking(targetPixel, occupyingUserId); + + verify(rankingRedisRepository, times(1)).increaseCurrentPixelCount(occupyingUserId); + } + + @Test + @DisplayName("[updateRanking] 아무도 차지 한 적이 없는 땅이라면 차지하려는 사람의 점수를 추가한다.") + void updateRanking_NeverOccupied() { + Long occupyingUserId = 1L; + Pixel targetPixel = Pixel.builder().userId(null).build(); + + rankingService.updateRanking(targetPixel, occupyingUserId); + + verify(rankingRedisRepository, times(1)).increaseCurrentPixelCount(occupyingUserId); + } - rankingService.decreaseCurrentPixelCount(userId); + @Test + @DisplayName("[updateRanking] 가장 최근에 차지한 시간이 저번주라면 지금 차지하려는 사람의 점수를 추가한다.") + void updateRanking_BeforeThisWeek() { + Long occupyingUserId = 1L; + Pixel targetPixel = Pixel.builder().userId(3L).build(); + targetPixel.updateModifiedAt(DateUtils.getThisWeekStartDate().atTime(0, 0, 0).minusDays(3)); - verify(rankingRedisRepository, times(1)).decreaseCurrentPixelCount(userId); + rankingService.updateRanking(targetPixel, occupyingUserId); + + verify(rankingRedisRepository, times(1)).increaseCurrentPixelCount(occupyingUserId); + } + + @Test + @DisplayName("[updateRanking] 가장 최근에 차지한 시간이 이번주이고 차지하려는 사람과 차지한 사람이 다르면 지금 차지하려는 사람의 점수를 추가하고 차지한 사람의 점수는 감소시킨다.") + void updateRanking_OccupyPixel() { + Long occupyingUserId = 1L; + Pixel targetPixel = Pixel.builder().userId(3L).build(); + targetPixel.updateModifiedAt(DateUtils.getThisWeekStartDate().atTime(0, 0, 0).plusDays(3)); + + rankingService.updateRanking(targetPixel, occupyingUserId); + + verify(rankingRedisRepository, times(1)).increaseCurrentPixelCount(occupyingUserId); + verify(rankingRedisRepository, times(1)).decreaseCurrentPixelCount(3L); } @Test - @DisplayName("[decreasePixelCount] occupyingUserId 에 해당하는 현재 소유 픽셀의 개수를 1 증가시키고 deprivedUserId 에 해당하는 현재 소유 픽셀의 개수를 1 감소시킨다.") + @DisplayName("[updateRankingAfterOccupy] occupyingUserId 에 해당하는 현재 소유 픽셀의 개수를 1 증가시키고 deprivedUserId 에 해당하는 현재 소유 픽셀의 개수를 1 감소시킨다.") void updateRankingAfterOccupyTest() { Long occupyingUserId = 1L; Long deprivedUserId = 2L; diff --git a/src/test/java/com/m3pro/groundflip/service/UserServiceTest.java b/src/test/java/com/m3pro/groundflip/service/UserServiceTest.java index 4a6ec5d2..10f41aa8 100644 --- a/src/test/java/com/m3pro/groundflip/service/UserServiceTest.java +++ b/src/test/java/com/m3pro/groundflip/service/UserServiceTest.java @@ -36,6 +36,7 @@ import com.m3pro.groundflip.exception.ErrorCode; import com.m3pro.groundflip.jwt.JwtProvider; import com.m3pro.groundflip.repository.AppleRefreshTokenRepository; +import com.m3pro.groundflip.repository.FcmTokenRepository; import com.m3pro.groundflip.repository.RankingRedisRepository; import com.m3pro.groundflip.repository.UserCommunityRepository; import com.m3pro.groundflip.repository.UserRepository; @@ -50,6 +51,9 @@ class UserServiceTest { @Mock private RankingRedisRepository rankingRedisRepository; + @Mock + private FcmTokenRepository fcmTokenRepository; + @Mock private S3Uploader s3Uploader; @@ -207,6 +211,7 @@ void deleteUserTest() { Calendar calendar = Calendar.getInstance(); calendar.setTime(deleteUser.getBirthYear()); + verify(fcmTokenRepository, times(1)).deleteByUser(any()); assertThat(deleteUser.getNickname()).isEqualTo(null); assertThat(deleteUser.getProfileImage()).isEqualTo(null); assertThat(calendar.get(Calendar.YEAR)).isEqualTo(1900); @@ -236,6 +241,7 @@ void deleteUserTestInApple() { Calendar calendar = Calendar.getInstance(); calendar.setTime(deleteUser.getBirthYear()); + verify(fcmTokenRepository, times(1)).deleteByUser(any()); verify(appleApiClient, times(1)).revokeToken(any()); verify(appleRefreshTokenRepository, times(1)).delete(any()); assertThat(deleteUser.getNickname()).isEqualTo(null);