diff --git a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt index 3adfedcb..1bd6491c 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/schedule/business/ScheduleService.kt @@ -18,6 +18,8 @@ import org.springframework.data.repository.findByIdOrNull import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import java.time.LocalDate +import java.time.LocalDateTime +import java.time.LocalTime private val log: KLogger = KotlinLogging.logger {} @@ -43,9 +45,16 @@ class ScheduleService( @Transactional(readOnly = true) fun getStoreScheduleByDate(storeId: Long, date: LocalDate): ScheduleWithThemeListResponse { log.info { "[ScheduleService.getStoreScheduleByDate] 매장 일정 조회: storeId=${storeId}, date=$date" } + val currentDate = LocalDate.now() + + if (date.isBefore(currentDate)) { + log.warn { "[ScheduleService.getStoreScheduleByDate] 이전 날짜 선택으로 인한 실패: date=${date}" } + throw ScheduleException(ScheduleErrorCode.PAST_DATE_TIME) + } val schedules: List = scheduleRepository.findStoreSchedulesWithThemeByDate(storeId, date) + .filter { it.date.isAfter(date) || (it.date.isEqual(date) && it.time.isAfter(LocalTime.now())) } return schedules.toResponse() .also { diff --git a/service/src/main/kotlin/com/sangdol/roomescape/schedule/infrastructure/persistence/ScheduleRepository.kt b/service/src/main/kotlin/com/sangdol/roomescape/schedule/infrastructure/persistence/ScheduleRepository.kt index 82080181..abf9484a 100644 --- a/service/src/main/kotlin/com/sangdol/roomescape/schedule/infrastructure/persistence/ScheduleRepository.kt +++ b/service/src/main/kotlin/com/sangdol/roomescape/schedule/infrastructure/persistence/ScheduleRepository.kt @@ -17,8 +17,8 @@ interface ScheduleRepository : JpaRepository { WHERE s.storeId = :storeId AND s.date = :date - AND s.themeId = :themeId AND s.time = :time + AND s.themeId = :themeId """ ) fun existsDuplicate(storeId: Long, date: LocalDate, themeId: Long, time: LocalTime): Boolean @@ -41,11 +41,13 @@ interface ScheduleRepository : JpaRepository { FROM ScheduleEntity s JOIN - ThemeEntity t ON t._id = s.themeId and (:themeId IS NULL OR t._id = :themeId) + ThemeEntity t ON t._id = s.themeId JOIN - StoreEntity st ON st._id = s.storeId and st._id = :storeId + StoreEntity st ON st._id = s.storeId WHERE - s.date = :date + s.storeId = :storeId + AND s.date = :date + AND (:themeId IS NULL OR t._id = :themeId) """ ) fun findStoreSchedulesWithThemeByDate( diff --git a/service/src/test/kotlin/com/sangdol/roomescape/schedule/ScheduleApiTest.kt b/service/src/test/kotlin/com/sangdol/roomescape/schedule/ScheduleApiTest.kt index 1f8103c4..bbc55575 100644 --- a/service/src/test/kotlin/com/sangdol/roomescape/schedule/ScheduleApiTest.kt +++ b/service/src/test/kotlin/com/sangdol/roomescape/schedule/ScheduleApiTest.kt @@ -20,11 +20,12 @@ class ScheduleApiTest( ) : FunSpecSpringbootTest() { init { context("특정 매장 + 날짜의 일정 및 테마 정보를 조회한다.") { - test("정상 응답") { - val size = 2 - val date = LocalDate.now().plusDays(1) + test("날짜가 오늘이면 현재 시간 이후의 정보만 조회된다.") { + val size = 3 + val date = LocalDate.now() val store = dummyInitializer.createStore() - initialize("조회를 위한 같은 날짜의 ${size}개의 일정 생성") { + + initialize("조회를 위한 오늘 날짜의 현재 시간 이후인 ${size}개의 일정, 현재 시간 이전인 1개의 일정 생성") { for (i in 1..size) { dummyInitializer.createSchedule( storeId = store.id, @@ -34,6 +35,14 @@ class ScheduleApiTest( ) ) } + + dummyInitializer.createSchedule( + storeId = store.id, + request = ScheduleFixture.createRequest.copy( + date = date, + time = LocalTime.now().minusMinutes(1) + ) + ) } runTest( @@ -50,6 +59,22 @@ class ScheduleApiTest( } ) } + + test("날짜가 오늘 이전이면 실패한다.") { + val store = initialize("매장 생성") { + dummyInitializer.createStore() + } + + runTest( + on = { + get("/stores/${store.id}/schedules?date=${LocalDate.now().minusDays(1)}") + }, + expect = { + statusCode(HttpStatus.BAD_REQUEST.value()) + body("code", equalTo(ScheduleErrorCode.PAST_DATE_TIME.errorCode)) + } + ) + } } context("일정을 ${ScheduleStatus.HOLD} 상태로 변경한다.") {