diff --git a/Server/src/main/java/JGS/CasperEvent/CasperEventApplication.java b/Server/src/main/java/JGS/CasperEvent/CasperEventApplication.java index 4005d90b..07b2d937 100644 --- a/Server/src/main/java/JGS/CasperEvent/CasperEventApplication.java +++ b/Server/src/main/java/JGS/CasperEvent/CasperEventApplication.java @@ -2,12 +2,14 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.scheduling.annotation.EnableScheduling; @SpringBootApplication @EnableAspectJAutoProxy @EnableScheduling +@EnableCaching public class CasperEventApplication { public static void main(String[] args) { diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/controller/eventController/RushEventController.java b/Server/src/main/java/JGS/CasperEvent/domain/event/controller/eventController/RushEventController.java index 87756424..3ac077e1 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/controller/eventController/RushEventController.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/controller/eventController/RushEventController.java @@ -73,7 +73,7 @@ public ResponseEntity rushEventResult(HttpServletReq @ApiResponse(responseCode = "204", description = "Successfully set today's event in Redis.") @GetMapping("/today/test") public ResponseEntity setTodayEvent() { - rushEventService.setTodayEventToRedis(); + rushEventService.setRushEvents(); return ResponseEntity.noContent().build(); } diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventCacheService.java b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventCacheService.java new file mode 100644 index 00000000..abb551b9 --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventCacheService.java @@ -0,0 +1,39 @@ +package JGS.CasperEvent.domain.event.service.eventService; + +import JGS.CasperEvent.domain.event.dto.ResponseDto.rushEventResponseDto.RushEventResponseDto; +import JGS.CasperEvent.domain.event.entity.event.RushEvent; +import JGS.CasperEvent.domain.event.repository.eventRepository.RushEventRepository; +import JGS.CasperEvent.global.enums.CustomErrorCode; +import JGS.CasperEvent.global.error.exception.CustomException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.stereotype.Service; + +import java.time.LocalDate; +import java.util.List; + +@Service +@RequiredArgsConstructor +@Slf4j +public class RushEventCacheService { + + private final RushEventRepository rushEventRepository; + + @Cacheable(value = "todayEventCache", key = "#today") + public RushEventResponseDto getTodayEvent(LocalDate today) { + log.info("오늘의 이벤트 캐싱 {}", today); + // 오늘 날짜에 해당하는 모든 이벤트 꺼내옴 + List rushEventList = rushEventRepository.findByEventDate(today); + + if (rushEventList.isEmpty()) { + throw new CustomException("선착순 이벤트가 존재하지않습니다.", CustomErrorCode.NO_RUSH_EVENT); + } + + if (rushEventList.size() > 1) { + throw new CustomException("선착순 이벤트가 2개 이상 존재합니다.", CustomErrorCode.MULTIPLE_RUSH_EVENTS_FOUND); + } + + return RushEventResponseDto.of(rushEventList.get(0)); + } +} diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventScheduler.java b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventScheduler.java deleted file mode 100644 index 901e846c..00000000 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventScheduler.java +++ /dev/null @@ -1,37 +0,0 @@ -package JGS.CasperEvent.domain.event.service.eventService; - -import JGS.CasperEvent.domain.event.dto.ResponseDto.rushEventResponseDto.RushEventResponseDto; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.scheduling.annotation.Scheduled; -import org.springframework.stereotype.Service; - -import java.time.LocalDate; -import java.time.LocalDateTime; - -@Service -@EnableScheduling -@RequiredArgsConstructor -@Slf4j -public class RushEventScheduler { - - private final RushEventService rushEventService; - private final RedisTemplate rushEventRedisTemplate; - - // 매일 0시 1분에 스케줄된 작업을 실행합니다. - @Scheduled(cron = "0 1 0 * * ?") - public void fetchDailyEvents() { - // EventService를 통해 오늘의 이벤트를 가져옵니다. - RushEventResponseDto todayEvent = rushEventService.getTodayRushEventFromRDB(); - - // 가져온 이벤트에 대한 추가 작업을 수행합니다. - // 예: 캐싱, 로그 기록, 알림 발송 등 - rushEventRedisTemplate.opsForValue().set("todayEvent", todayEvent); - - // 로그 출력 - log.info("선착순 이벤트 스케줄러 실행: {}", LocalDateTime.now()); - log.info("가져온 이벤트 날짜: {}", todayEvent.startDateTime()); - } -} diff --git a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventService.java b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventService.java index ae2dc171..9c3141a5 100644 --- a/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventService.java +++ b/Server/src/main/java/JGS/CasperEvent/domain/event/service/eventService/RushEventService.java @@ -13,7 +13,6 @@ import JGS.CasperEvent.global.error.exception.CustomException; import JGS.CasperEvent.global.util.RepositoryErrorHandler; import lombok.RequiredArgsConstructor; -import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -29,13 +28,15 @@ public class RushEventService { private final RushEventRepository rushEventRepository; private final RushParticipantsRepository rushParticipantsRepository; - private final RedisTemplate rushEventRedisTemplate; private final RushOptionRepository rushOptionRepository; + private final RushEventCacheService rushEventCacheService; @Transactional public RushEventListResponseDto getAllRushEvents() { + LocalDate today = LocalDate.now(); + // 오늘의 선착순 이벤트 꺼내오기 - RushEventResponseDto todayEvent = getTodayRushEventFromRedis(); + RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today); // DB에서 모든 RushEvent 가져오기 List rushEventList = rushEventRepository.findAll(); @@ -67,13 +68,15 @@ public RushEventListResponseDto getAllRushEvents() { // 응모 여부 조회 public boolean isExists(String userId) { - Long todayEventId = getTodayRushEventFromRedis().rushEventId(); + LocalDate today = LocalDate.now(); + Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId(); return rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(todayEventId, userId); } @Transactional public void apply(BaseUser user, int optionId) { - Long todayEventId = getTodayRushEventFromRedis().rushEventId(); + LocalDate today = LocalDate.now(); + Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId(); // 이미 응모한 회원인지 검증 if (rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(todayEventId, user.getId())) { @@ -90,7 +93,8 @@ public void apply(BaseUser user, int optionId) { // 진행중인 게임의 응모 비율 반환 public RushEventRateResponseDto getRushEventRate(BaseUser user) { - Long todayEventId = getTodayRushEventFromRedis().rushEventId(); + LocalDate today = LocalDate.now(); + Long todayEventId = rushEventCacheService.getTodayEvent(today).rushEventId(); Optional optionId = rushParticipantsRepository.getOptionIdByUserId(user.getId()); long leftOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 1); long rightOptionCount = rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(todayEventId, 2); @@ -104,7 +108,8 @@ public RushEventRateResponseDto getRushEventRate(BaseUser user) { // 응모하지 않은 유저가 요청하는 경우가 존재 -> 응모 비율만 반환하도록 수정 @Transactional public RushEventResultResponseDto getRushEventResult(BaseUser user) { - RushEventResponseDto todayRushEvent = getTodayRushEventFromRedis(); + LocalDate today = LocalDate.now(); + RushEventResponseDto todayRushEvent = rushEventCacheService.getTodayEvent(today); Long todayEventId = todayRushEvent.rushEventId(); // 최종 선택 비율을 조회 @@ -157,39 +162,8 @@ public RushEventResultResponseDto getRushEventResult(BaseUser user) { return new RushEventResultResponseDto(optionId, leftOption, rightOption, rank, totalParticipants, isWinner); } - // 오늘의 이벤트를 DB에 꺼내서 반환 - public RushEventResponseDto getTodayRushEventFromRDB() { - LocalDate today = LocalDate.now(); - - // 오늘 날짜에 해당하는 모든 이벤트 꺼내옴 - List rushEventList = rushEventRepository.findByEventDate(today); - - if (rushEventList.isEmpty()) { - throw new CustomException("선착순 이벤트가 존재하지않습니다.", CustomErrorCode.NO_RUSH_EVENT); - } - - if (rushEventList.size() > 1) { - throw new CustomException("선착순 이벤트가 2개 이상 존재합니다.", CustomErrorCode.MULTIPLE_RUSH_EVENTS_FOUND); - } - - return RushEventResponseDto.of(rushEventList.get(0)); - } - - // 오늘의 이벤트 꺼내오기 - private RushEventResponseDto getTodayRushEventFromRedis() { - RushEventResponseDto todayEvent = rushEventRedisTemplate.opsForValue().get("todayEvent"); - - // Redis에 오늘의 이벤트가 없으면 DB에서 가져와서 Redis에 저장한 후 반환. - if (todayEvent == null) { - todayEvent = getTodayRushEventFromRDB(); - rushEventRedisTemplate.opsForValue().set("todayEvent", todayEvent); - } - - return todayEvent; - } - @Transactional - public void setTodayEventToRedis() { + public void setRushEvents() { // 테이블 초기화 rushParticipantsRepository.deleteAllInBatch(); rushOptionRepository.deleteAllInBatch(); @@ -253,15 +227,13 @@ public void setTodayEventToRedis() { rushEvents.add(rushEvent); } - - // 세 번째로 생성된 RushEvent를 Redis에 저장 - rushEventRedisTemplate.opsForValue().set("todayEvent", RushEventResponseDto.of(rushEvents.get(2))); } // 오늘의 이벤트 옵션 정보를 반환 public MainRushEventOptionsResponseDto getTodayRushEventOptions() { - RushEventResponseDto todayEvent = getTodayRushEventFromRedis(); + LocalDate today = LocalDate.now(); + RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today); Set options = todayEvent.options(); RushEventOptionResponseDto leftOption = options.stream() @@ -282,7 +254,8 @@ public MainRushEventOptionsResponseDto getTodayRushEventOptions() { public ResultRushEventOptionResponseDto getRushEventOptionResult(int optionId) { Position position = Position.of(optionId); - RushEventResponseDto todayEvent = getTodayRushEventFromRedis(); + LocalDate today = LocalDate.now(); + RushEventResponseDto todayEvent = rushEventCacheService.getTodayEvent(today); Set options = todayEvent.options(); if (options.size() != 2) { diff --git a/Server/src/main/java/JGS/CasperEvent/global/config/CacheConfig.java b/Server/src/main/java/JGS/CasperEvent/global/config/CacheConfig.java new file mode 100644 index 00000000..34abdd90 --- /dev/null +++ b/Server/src/main/java/JGS/CasperEvent/global/config/CacheConfig.java @@ -0,0 +1,16 @@ +package JGS.CasperEvent.global.config; + +import org.springframework.cache.CacheManager; +import org.springframework.cache.concurrent.ConcurrentMapCacheManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class CacheConfig { + + @Bean + public CacheManager cacheManager() { + return new ConcurrentMapCacheManager("todayEventCache"); + } + +} diff --git a/Server/src/main/java/JGS/CasperEvent/global/config/RedisConfig.java b/Server/src/main/java/JGS/CasperEvent/global/config/RedisConfig.java index ee04b77d..5b55a3f4 100644 --- a/Server/src/main/java/JGS/CasperEvent/global/config/RedisConfig.java +++ b/Server/src/main/java/JGS/CasperEvent/global/config/RedisConfig.java @@ -37,13 +37,4 @@ public RedisTemplate CasperBotRedisTemplate(){ redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); return redisTemplate; } - - @Bean - public RedisTemplate RushEventRedisTemplate(){ - RedisTemplate redisTemplate = new RedisTemplate<>(); - redisTemplate.setConnectionFactory(redisConnectionFactory()); - redisTemplate.setKeySerializer(new StringRedisSerializer()); - redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); - return redisTemplate; - } } diff --git a/Server/src/test/java/JGS/CasperEvent/domain/event/service/eventService/RushEventSchedulerTest.java b/Server/src/test/java/JGS/CasperEvent/domain/event/service/eventService/RushEventSchedulerTest.java deleted file mode 100644 index 1ef8b649..00000000 --- a/Server/src/test/java/JGS/CasperEvent/domain/event/service/eventService/RushEventSchedulerTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package JGS.CasperEvent.domain.event.service.eventService; - -import JGS.CasperEvent.domain.event.dto.ResponseDto.rushEventResponseDto.RushEventResponseDto; -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 org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.ValueOperations; - -import java.time.LocalDate; -import java.time.LocalDateTime; -import java.util.HashSet; - -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.verify; - -@ExtendWith(MockitoExtension.class) -class RushEventSchedulerTest { - - @Mock - private RushEventService rushEventService; - - @Mock - private RedisTemplate rushEventRedisTemplate; - - @Mock - private ValueOperations valueOperations; - - @InjectMocks - private RushEventScheduler rushEventScheduler; - - @Test - void fetchDailyEvents_ShouldCacheTodayEventInRedis() { - // given - LocalDate today = LocalDate.now(); - RushEventResponseDto todayEvent = new RushEventResponseDto( - 1L, - LocalDateTime.now(), - LocalDateTime.now().plusDays(1), - 315, - "image-url", - "prize-description", - new HashSet<>() - ); - - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventService.getTodayRushEventFromRDB()).willReturn(todayEvent); - - // when - rushEventScheduler.fetchDailyEvents(); - - // then - verify(rushEventService).getTodayRushEventFromRDB(); - verify(rushEventRedisTemplate.opsForValue()).set("todayEvent", todayEvent); - } -} diff --git a/Server/src/test/java/JGS/CasperEvent/domain/event/service/eventService/RushEventServiceTest.java b/Server/src/test/java/JGS/CasperEvent/domain/event/service/eventService/RushEventServiceTest.java index 058ceaf4..2411c420 100644 --- a/Server/src/test/java/JGS/CasperEvent/domain/event/service/eventService/RushEventServiceTest.java +++ b/Server/src/test/java/JGS/CasperEvent/domain/event/service/eventService/RushEventServiceTest.java @@ -17,8 +17,6 @@ import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.jupiter.MockitoExtension; -import org.springframework.data.redis.core.RedisTemplate; -import org.springframework.data.redis.core.ValueOperations; import java.time.LocalDate; import java.time.LocalDateTime; @@ -39,12 +37,10 @@ class RushEventServiceTest { @Mock private RushParticipantsRepository rushParticipantsRepository; @Mock - private RedisTemplate rushEventRedisTemplate; - @Mock private RushOptionRepository rushOptionRepository; - @Mock - private ValueOperations valueOperations; + @Mock + private RushEventCacheService rushEventCacheService; @InjectMocks RushEventService rushEventService; @@ -70,8 +66,7 @@ void getAllRushEvents() { List mainRushEventResponseDtoList = rushEventList.stream() .map(MainRushEventResponseDto::of).toList(); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(valueOperations.get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushEventRepository.findAll()).willReturn(rushEventList); // when @@ -98,8 +93,7 @@ void isExists() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(1L, user.getId())).willReturn(true); // when @@ -124,8 +118,7 @@ void apply() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(1L, user.getId())).willReturn(false); RushEvent rushEvent = new RushEvent(); given(rushEventRepository.findById(1L)).willReturn(Optional.of(rushEvent)); @@ -152,8 +145,7 @@ void apply2() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.existsByRushEvent_RushEventIdAndBaseUser_Id(1L, user.getId())).willReturn(true); // when & then @@ -181,8 +173,7 @@ void getRushEventRate() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.getOptionIdByUserId(user.getId())).willReturn(Optional.of(1)); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 1)).willReturn(100L); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 2)).willReturn(200L); @@ -212,8 +203,7 @@ void getRushEventResult() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.getOptionIdByUserId(user.getId())).willReturn(Optional.of(1)); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 1)).willReturn(700L); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 2)).willReturn(500L); @@ -247,8 +237,7 @@ void getRushEventResult2() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.getOptionIdByUserId(user.getId())).willReturn(Optional.of(2)); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 1)).willReturn(700L); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 2)).willReturn(500L); @@ -282,8 +271,7 @@ void getRushEventResult3() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.getOptionIdByUserId(user.getId())).willReturn(Optional.of(1)); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 1)).willReturn(700L); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 2)).willReturn(500L); @@ -317,8 +305,7 @@ void getRushEventResult4() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.getOptionIdByUserId(user.getId())).willReturn(Optional.of(1)); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 1)).willReturn(500L); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 2)).willReturn(500L); @@ -351,8 +338,7 @@ void getRushEventResult5() { new HashSet<>() ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); given(rushParticipantsRepository.getOptionIdByUserId(user.getId())).willReturn(Optional.of(1)); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 1)).willReturn(500L); given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 2)).willReturn(500L); @@ -371,55 +357,36 @@ void getRushEventResult5() { } @Test - @DisplayName("오늘의 선착순 이벤트 DB에서 가져오기 테스트") - void getTodayRushEvent() { + @DisplayName("선착순 이벤트 결과 조회 테스트 (응모하지 않았는데 결과 조회창으로 넘어가서 호출되는 경우)") + void getRushEventResult6() { // given - LocalDate today = LocalDate.now(); - RushEvent rushEvent = new RushEvent(); - given(rushEventRepository.findByEventDate(today)).willReturn(List.of(rushEvent)); - - // when - RushEventResponseDto result = rushEventService.getTodayRushEventFromRDB(); - - // then - assertNotNull(result); - assertEquals(rushEvent.getRushEventId(), result.rushEventId()); - } - - @Test - @DisplayName("오늘의 선착순 이벤트 DB에서 가져오기 테스트 (RDB에 선착순 이벤트가 없는 경우)") - void getTodayRushEvent2() { - // given - LocalDate today = LocalDate.now(); - given(rushEventRepository.findByEventDate(today)).willReturn(List.of()); - - // when & then - CustomException exception = assertThrows(CustomException.class, () -> - rushEventService.getTodayRushEventFromRDB() + BaseUser user = new BaseUser(); + RushEventResponseDto todayEvent = new RushEventResponseDto( + 1L, + LocalDateTime.now(), + LocalDateTime.now().plusDays(1), + 315, + "image-url", + "prize-description", + new HashSet<>() ); - assertEquals(CustomErrorCode.NO_RUSH_EVENT, exception.getErrorCode()); - assertEquals("선착순 이벤트가 존재하지않습니다.", exception.getMessage()); - } - - @Test - @DisplayName("오늘의 선착순 이벤트 DB에서 가져오기 테스트 (RDB에 선착순 이벤트가 2개 이상인 경우)") - void getTodayRushEvent3() { - // given - LocalDate today = LocalDate.now(); - RushEvent rushEvent1 = new RushEvent(); - RushEvent rushEvent2 = new RushEvent(); - given(rushEventRepository.findByEventDate(today)).willReturn(List.of( - rushEvent1, rushEvent2 - )); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); + given(rushParticipantsRepository.getOptionIdByUserId(user.getId())).willReturn(Optional.empty()); + given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 1)).willReturn(500L); + given(rushParticipantsRepository.countByRushEvent_RushEventIdAndOptionId(1L, 2)).willReturn(500L); // when & then - CustomException exception = assertThrows(CustomException.class, () -> - rushEventService.getTodayRushEventFromRDB() - ); + RushEventResultResponseDto result = rushEventService.getRushEventResult(user); - assertEquals(CustomErrorCode.MULTIPLE_RUSH_EVENTS_FOUND, exception.getErrorCode()); - assertEquals("선착순 이벤트가 2개 이상 존재합니다.", exception.getMessage()); + // then + assertNotNull(result); + assertNull(result.getOptionId()); + assertEquals(500, result.getLeftOption()); + assertEquals(500, result.getRightOption()); + assertNull(result.getTotalParticipants()); + assertNull(result.getRank()); + assertNull(result.getIsWinner()); } @Test @@ -430,16 +397,14 @@ void setTodayEventToRedis() { RushOption rushOption = new RushOption(); given(rushEventRepository.save(any(RushEvent.class))).willReturn(rushEvent); given(rushOptionRepository.save(any(RushOption.class))).willReturn(rushOption); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); // when - rushEventService.setTodayEventToRedis(); + rushEventService.setRushEvents(); // then verify(rushParticipantsRepository).deleteAllInBatch(); verify(rushOptionRepository).deleteAllInBatch(); verify(rushEventRepository).deleteAllInBatch(); - verify(rushEventRedisTemplate.opsForValue()).set(eq("todayEvent"), any(RushEventResponseDto.class)); } @Test @@ -459,8 +424,7 @@ void getTodayRushEventOptions() { ) ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); // when MainRushEventOptionsResponseDto result = rushEventService.getTodayRushEventOptions(); @@ -489,9 +453,7 @@ void getRushEventOptionResult() { ) ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); - + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); // when ResultRushEventOptionResponseDto result = rushEventService.getRushEventOptionResult(optionId); @@ -519,9 +481,7 @@ void getRushEventOptionResult2() { ) ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); - + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); // when & then CustomException exception = assertThrows(CustomException.class, () -> rushEventService.getRushEventOptionResult(optionId) @@ -576,9 +536,7 @@ void getRushEventOptionResult4() { ) ); - given(rushEventRedisTemplate.opsForValue()).willReturn(valueOperations); - given(rushEventRedisTemplate.opsForValue().get("todayEvent")).willReturn(todayEvent); - + given(rushEventCacheService.getTodayEvent(LocalDate.now())).willReturn(todayEvent); // when & then CustomException exception = assertThrows(CustomException.class, () -> rushEventService.getRushEventOptionResult(optionId)