generated from pricelees/issue-pr-template
refactor: schedule 관련 로직 및 테스트에 한국 시간 반영
This commit is contained in:
parent
6c2e63e35e
commit
844c8b6007
@ -1,6 +1,8 @@
|
||||
package com.sangdol.roomescape.schedule.business
|
||||
|
||||
import com.sangdol.common.persistence.IDGenerator
|
||||
import com.sangdol.common.utils.KoreaDate
|
||||
import com.sangdol.common.utils.KoreaTime
|
||||
import com.sangdol.roomescape.admin.business.AdminService
|
||||
import com.sangdol.roomescape.common.types.AuditingInfo
|
||||
import com.sangdol.roomescape.common.types.Auditor
|
||||
@ -44,7 +46,9 @@ class ScheduleService(
|
||||
@Transactional(readOnly = true)
|
||||
fun getStoreScheduleByDate(storeId: Long, date: LocalDate): ScheduleWithThemeListResponse {
|
||||
log.info { "[getStoreScheduleByDate] 매장 일정 조회: storeId=${storeId}, date=$date" }
|
||||
val currentDate = LocalDate.now()
|
||||
|
||||
val currentDate: LocalDate = KoreaDate.today()
|
||||
val currentTime: LocalTime = KoreaTime.now()
|
||||
|
||||
if (date.isBefore(currentDate)) {
|
||||
log.warn { "[getStoreScheduleByDate] 이전 날짜 선택으로 인한 실패: date=${date}" }
|
||||
@ -53,7 +57,7 @@ class ScheduleService(
|
||||
|
||||
val schedules: List<ScheduleOverview> =
|
||||
scheduleRepository.findStoreSchedulesWithThemeByDate(storeId, date)
|
||||
.filter { it.date.isAfter(date) || (it.date.isEqual(date) && it.time.isAfter(LocalTime.now())) }
|
||||
.filter { it.time.isAfter(currentTime) }
|
||||
|
||||
return schedules.toResponse()
|
||||
.also {
|
||||
@ -89,7 +93,7 @@ class ScheduleService(
|
||||
fun searchSchedules(storeId: Long, date: LocalDate?, themeId: Long?): AdminScheduleSummaryListResponse {
|
||||
log.info { "[searchSchedules] 일정 검색 시작: storeId=$storeId, date=$date, themeId=$themeId" }
|
||||
|
||||
val searchDate = date ?: LocalDate.now()
|
||||
val searchDate = date ?: KoreaDate.today()
|
||||
|
||||
val schedules: List<ScheduleOverview> =
|
||||
scheduleRepository.findStoreSchedulesWithThemeByDate(storeId, searchDate)
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
package com.sangdol.roomescape.schedule.business
|
||||
|
||||
import com.sangdol.common.utils.KoreaDateTime
|
||||
import com.sangdol.roomescape.schedule.exception.ScheduleErrorCode
|
||||
import com.sangdol.roomescape.schedule.exception.ScheduleException
|
||||
import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleEntity
|
||||
@ -13,6 +14,7 @@ import org.springframework.stereotype.Component
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalDateTime
|
||||
import java.time.LocalTime
|
||||
import java.time.temporal.ChronoUnit
|
||||
|
||||
private val log: KLogger = KotlinLogging.logger {}
|
||||
|
||||
@ -56,9 +58,10 @@ class ScheduleValidator(
|
||||
}
|
||||
|
||||
private fun validateNotInPast(date: LocalDate, time: LocalTime) {
|
||||
val dateTime = LocalDateTime.of(date, time)
|
||||
val now = KoreaDateTime.now().truncatedTo(ChronoUnit.MINUTES)
|
||||
val inputDateTime = LocalDateTime.of(date, time).truncatedTo(ChronoUnit.MINUTES)
|
||||
|
||||
if (dateTime.isBefore(LocalDateTime.now())) {
|
||||
if (inputDateTime.isBefore(now)) {
|
||||
log.info {
|
||||
"[ScheduleValidator.validateDateTime] 이전 시간 선택으로 인한 실패: date=${date} / time=${time}"
|
||||
}
|
||||
|
||||
@ -1,10 +1,13 @@
|
||||
package com.sangdol.roomescape.schedule
|
||||
|
||||
import com.sangdol.roomescape.common.types.Auditor
|
||||
import com.sangdol.common.types.web.HttpStatus
|
||||
import com.sangdol.common.utils.KoreaDate
|
||||
import com.sangdol.common.utils.KoreaDateTime
|
||||
import com.sangdol.common.utils.KoreaTime
|
||||
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel
|
||||
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType
|
||||
import com.sangdol.roomescape.auth.exception.AuthErrorCode
|
||||
import com.sangdol.roomescape.common.types.Auditor
|
||||
import com.sangdol.roomescape.schedule.exception.ScheduleErrorCode
|
||||
import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleEntity
|
||||
import com.sangdol.roomescape.schedule.infrastructure.persistence.ScheduleRepository
|
||||
@ -54,7 +57,8 @@ class AdminScheduleApiTest(
|
||||
lateinit var token: String
|
||||
|
||||
beforeTest {
|
||||
val today = LocalDate.now()
|
||||
val now = KoreaDateTime.now()
|
||||
val today = now.toLocalDate()
|
||||
store = dummyInitializer.createStore()
|
||||
val admin = AdminFixture.createStoreAdmin(storeId = store.id)
|
||||
token = testAuthUtil.adminLogin(admin).second
|
||||
@ -66,21 +70,21 @@ class AdminScheduleApiTest(
|
||||
storeId = store.id,
|
||||
request = ScheduleFixture.createRequest.copy(
|
||||
date = today,
|
||||
time = LocalTime.now().plusHours(2)
|
||||
time = now.toLocalTime().plusHours(2)
|
||||
)
|
||||
),
|
||||
dummyInitializer.createSchedule(
|
||||
storeId = store.id,
|
||||
request = ScheduleFixture.createRequest.copy(
|
||||
date = today,
|
||||
time = LocalTime.now().plusHours(1)
|
||||
time = now.toLocalTime().plusHours(1)
|
||||
)
|
||||
),
|
||||
dummyInitializer.createSchedule(
|
||||
storeId = store.id,
|
||||
request = ScheduleFixture.createRequest.copy(
|
||||
date = today.plusDays(1),
|
||||
time = LocalTime.of(11, 0)
|
||||
time = LocalTime.of(10, 0)
|
||||
)
|
||||
)
|
||||
)
|
||||
@ -95,7 +99,7 @@ class AdminScheduleApiTest(
|
||||
},
|
||||
expect = {
|
||||
statusCode(HttpStatus.OK.value())
|
||||
body("data.schedules.size()", equalTo(schedules.filter { it.date.isEqual(LocalDate.now()) }.size))
|
||||
body("data.schedules.size()", equalTo(schedules.filter { it.date.isEqual(KoreaDate.today()) }.size))
|
||||
assertProperties(
|
||||
props = setOf("id", "themeName", "startFrom", "endAt", "status"),
|
||||
propsNameIfList = "schedules"
|
||||
@ -386,8 +390,9 @@ class AdminScheduleApiTest(
|
||||
|
||||
test("과거 시간을 선택하면 실패한다.") {
|
||||
val (admin, token) = testAuthUtil.defaultStoreAdminLogin()
|
||||
val date = LocalDate.now()
|
||||
val time = LocalTime.now().minusMinutes(1)
|
||||
val now = KoreaDateTime.now()
|
||||
val date = now.toLocalDate()
|
||||
val time = now.toLocalTime().minusMinutes(1)
|
||||
val theme = dummyInitializer.createTheme()
|
||||
|
||||
val request = ScheduleFixture.createRequest.copy(date = date, time = time, themeId = theme.id)
|
||||
@ -490,29 +495,50 @@ class AdminScheduleApiTest(
|
||||
}
|
||||
|
||||
context("정상 응답") {
|
||||
test("시간만 변경한다.") {
|
||||
val (admin, token) = testAuthUtil.defaultStoreAdminLogin()
|
||||
val schedule = initialize("수정을 위한 일정 생성") {
|
||||
dummyInitializer.createSchedule()
|
||||
}
|
||||
val updateTime = schedule.time.plusHours(1)
|
||||
|
||||
runTest(
|
||||
token = token,
|
||||
using = {
|
||||
body(ScheduleUpdateRequest(time = updateTime))
|
||||
},
|
||||
on = {
|
||||
patch("/admin/schedules/${schedule.id}")
|
||||
},
|
||||
expect = {
|
||||
statusCode(HttpStatus.OK.value())
|
||||
context("시간만 변경한다.") {
|
||||
test("성공") {
|
||||
val (admin, token) = testAuthUtil.defaultStoreAdminLogin()
|
||||
val schedule = initialize("수정을 위한 일정 생성") {
|
||||
dummyInitializer.createSchedule()
|
||||
}
|
||||
).also {
|
||||
val updated = scheduleRepository.findByIdOrNull(schedule.id)!!
|
||||
updated.time shouldBe updateTime
|
||||
updated.status shouldBe schedule.status
|
||||
updated.updatedAt shouldNotBe schedule.updatedAt
|
||||
val updateTime = schedule.time.plusHours(1)
|
||||
|
||||
runTest(
|
||||
token = token,
|
||||
using = {
|
||||
body(ScheduleUpdateRequest(time = updateTime))
|
||||
},
|
||||
on = {
|
||||
patch("/admin/schedules/${schedule.id}")
|
||||
},
|
||||
expect = {
|
||||
statusCode(HttpStatus.OK.value())
|
||||
}
|
||||
).also {
|
||||
val updated = scheduleRepository.findByIdOrNull(schedule.id)!!
|
||||
updated.time shouldBe updateTime
|
||||
updated.status shouldBe schedule.status
|
||||
updated.updatedAt shouldNotBe schedule.updatedAt
|
||||
}
|
||||
}
|
||||
|
||||
test("지난 시간을 선택하면 실패한다.") {
|
||||
val (admin, token) = testAuthUtil.defaultStoreAdminLogin()
|
||||
val schedule = initialize("수정을 위한 일정 생성") {
|
||||
val request = ScheduleFixture.createRequest.copy(
|
||||
date = KoreaDate.today(),
|
||||
time = KoreaTime.now().plusHours(1)
|
||||
)
|
||||
dummyInitializer.createSchedule(request = request)
|
||||
}
|
||||
|
||||
runExceptionTest(
|
||||
token = token,
|
||||
method = HttpMethod.PATCH,
|
||||
endpoint = "/admin/schedules/${schedule.id}",
|
||||
requestBody = ScheduleUpdateRequest(time = KoreaTime.now().minusMinutes(1)),
|
||||
expectedErrorCode = ScheduleErrorCode.PAST_DATE_TIME
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
package com.sangdol.roomescape.schedule
|
||||
|
||||
import com.sangdol.common.types.web.HttpStatus
|
||||
import com.sangdol.common.utils.KoreaDate
|
||||
import com.sangdol.common.utils.KoreaTime
|
||||
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminPermissionLevel
|
||||
import com.sangdol.roomescape.admin.infrastructure.persistence.AdminType
|
||||
import com.sangdol.roomescape.auth.exception.AuthErrorCode
|
||||
@ -13,16 +15,18 @@ import org.hamcrest.CoreMatchers.equalTo
|
||||
import org.springframework.data.repository.findByIdOrNull
|
||||
import org.springframework.http.HttpMethod
|
||||
import java.time.LocalDate
|
||||
import java.time.LocalTime
|
||||
|
||||
class ScheduleApiTest(
|
||||
private val scheduleRepository: ScheduleRepository
|
||||
) : FunSpecSpringbootTest() {
|
||||
init {
|
||||
context("특정 매장 + 날짜의 일정 및 테마 정보를 조회한다.") {
|
||||
/**
|
||||
* @throws 23시 57분 ~ 59분에 실행하면 실패함.
|
||||
*/
|
||||
test("날짜가 당일이면 현재 시간 이후의 정보만 조회된다.") {
|
||||
val size = 3
|
||||
val date = LocalDate.now()
|
||||
val date = KoreaDate.today()
|
||||
val store = dummyInitializer.createStore()
|
||||
|
||||
initialize("조회를 위한 오늘 날짜의 현재 시간 이후인 ${size}개의 일정, 현재 시간 이전인 1개의 일정 생성") {
|
||||
@ -31,7 +35,7 @@ class ScheduleApiTest(
|
||||
storeId = store.id,
|
||||
request = ScheduleFixture.createRequest.copy(
|
||||
date = date,
|
||||
time = LocalTime.now().plusMinutes(i.toLong())
|
||||
time = KoreaTime.now().plusMinutes(i.toLong())
|
||||
)
|
||||
)
|
||||
}
|
||||
@ -40,22 +44,18 @@ class ScheduleApiTest(
|
||||
storeId = store.id,
|
||||
request = ScheduleFixture.createRequest.copy(
|
||||
date = date,
|
||||
time = LocalTime.now().minusMinutes(1)
|
||||
time = KoreaTime.now().minusMinutes(1)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
val expectedSize = scheduleRepository.findAll().takeIf { it.isNotEmpty() }
|
||||
?.let { it.count { schedule -> schedule.date.isEqual(date) && schedule.time.isAfter(LocalTime.now()) } }
|
||||
?: throw AssertionError("initialize 작업에서 레코드가 저장되지 않음.")
|
||||
|
||||
runTest(
|
||||
on = {
|
||||
get("/stores/${store.id}/schedules?date=${date}")
|
||||
},
|
||||
expect = {
|
||||
statusCode(HttpStatus.OK.value())
|
||||
body("data.schedules.size()", equalTo(expectedSize))
|
||||
body("data.schedules.size()", equalTo(size))
|
||||
assertProperties(
|
||||
props = setOf("id", "startFrom", "endAt", "themeId", "themeName", "themeDifficulty", "status"),
|
||||
propsNameIfList = "schedules"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user