diff --git a/src/test/kotlin/roomescape/reservation/business/ReservationServiceTest.kt b/src/test/kotlin/roomescape/reservation/business/ReservationServiceTest.kt index 408718d4..32efd17d 100644 --- a/src/test/kotlin/roomescape/reservation/business/ReservationServiceTest.kt +++ b/src/test/kotlin/roomescape/reservation/business/ReservationServiceTest.kt @@ -5,10 +5,10 @@ import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import io.mockk.every import io.mockk.mockk -import roomescape.common.exception.ErrorType -import roomescape.common.exception.RoomescapeException import roomescape.member.business.MemberService import roomescape.member.infrastructure.persistence.Role +import roomescape.reservation.exception.ReservationErrorCode +import roomescape.reservation.exception.ReservationException import roomescape.reservation.infrastructure.persistence.ReservationRepository import roomescape.theme.business.ThemeService import roomescape.time.business.TimeService @@ -39,10 +39,10 @@ class ReservationServiceTest : FunSpec({ val reservationRequest = ReservationFixture.createRequest() - shouldThrow { - reservationService.addReservation(reservationRequest, 1L) + shouldThrow { + reservationService.createConfirmedReservation(reservationRequest, 1L) }.also { - it.errorType shouldBe ErrorType.RESERVATION_DUPLICATED + it.errorCode shouldBe ReservationErrorCode.RESERVATION_DUPLICATED } } @@ -69,10 +69,10 @@ class ReservationServiceTest : FunSpec({ timeService.findById(any()) } returns TimeFixture.create() - shouldThrow { - reservationService.addReservation(reservationRequest, 1L) + shouldThrow { + reservationService.createConfirmedReservation(reservationRequest, 1L) }.also { - it.errorType shouldBe ErrorType.RESERVATION_PERIOD_IN_PAST + it.errorCode shouldBe ReservationErrorCode.PAST_REQUEST_DATETIME } } @@ -87,10 +87,10 @@ class ReservationServiceTest : FunSpec({ startAt = LocalTime.now().minusMinutes(1) ) - shouldThrow { - reservationService.addReservation(reservationRequest, 1L) + shouldThrow { + reservationService.createConfirmedReservation(reservationRequest, 1L) }.also { - it.errorType shouldBe ErrorType.RESERVATION_PERIOD_IN_PAST + it.errorCode shouldBe ReservationErrorCode.PAST_REQUEST_DATETIME } } } @@ -108,7 +108,7 @@ class ReservationServiceTest : FunSpec({ reservationRepository.exists(any()) } returns true - shouldThrow { + shouldThrow { val waitingRequest = ReservationFixture.createWaitingRequest( date = reservationRequest.date, themeId = reservationRequest.themeId, @@ -116,7 +116,7 @@ class ReservationServiceTest : FunSpec({ ) reservationService.createWaiting(waitingRequest, 1L) }.also { - it.errorType shouldBe ErrorType.HAS_RESERVATION_OR_WAITING + it.errorCode shouldBe ReservationErrorCode.ALREADY_RESERVE } } } @@ -126,7 +126,7 @@ class ReservationServiceTest : FunSpec({ val startFrom = LocalDate.now() val endAt = startFrom.minusDays(1) - shouldThrow { + shouldThrow { reservationService.searchReservations( null, null, @@ -134,7 +134,7 @@ class ReservationServiceTest : FunSpec({ endAt ) }.also { - it.errorType shouldBe ErrorType.INVALID_DATE_RANGE + it.errorCode shouldBe ReservationErrorCode.INVALID_SEARCH_DATE_RANGE } } } @@ -147,10 +147,10 @@ class ReservationServiceTest : FunSpec({ memberService.findById(any()) } returns member - shouldThrow { + shouldThrow { reservationService.confirmWaiting(1L, member.id!!) }.also { - it.errorType shouldBe ErrorType.PERMISSION_DOES_NOT_EXIST + it.errorCode shouldBe ReservationErrorCode.NO_PERMISSION } } @@ -166,10 +166,10 @@ class ReservationServiceTest : FunSpec({ reservationRepository.isExistConfirmedReservation(reservationId) } returns true - shouldThrow { + shouldThrow { reservationService.confirmWaiting(reservationId, member.id!!) }.also { - it.errorType shouldBe ErrorType.RESERVATION_DUPLICATED + it.errorCode shouldBe ReservationErrorCode.CONFIRMED_RESERVATION_ALREADY_EXISTS } } } diff --git a/src/test/kotlin/roomescape/reservation/business/ReservationWithPaymentServiceTest.kt b/src/test/kotlin/roomescape/reservation/business/ReservationWithPaymentServiceTest.kt index dcbf069b..c9c5af68 100644 --- a/src/test/kotlin/roomescape/reservation/business/ReservationWithPaymentServiceTest.kt +++ b/src/test/kotlin/roomescape/reservation/business/ReservationWithPaymentServiceTest.kt @@ -48,7 +48,7 @@ class ReservationWithPaymentServiceTest : FunSpec({ context("addReservationWithPayment") { test("예약 및 결제 정보를 저장한다.") { every { - reservationService.addReservation(reservationCreateWithPaymentRequest, memberId) + reservationService.createConfirmedReservation(reservationCreateWithPaymentRequest, memberId) } returns reservationEntity every { diff --git a/src/test/kotlin/roomescape/reservation/infrastructure/persistence/ReservationRepositoryTest.kt b/src/test/kotlin/roomescape/reservation/infrastructure/persistence/ReservationRepositoryTest.kt index 0ae319ae..c41da6b3 100644 --- a/src/test/kotlin/roomescape/reservation/infrastructure/persistence/ReservationRepositoryTest.kt +++ b/src/test/kotlin/roomescape/reservation/infrastructure/persistence/ReservationRepositoryTest.kt @@ -168,7 +168,7 @@ class ReservationRepositoryTest( entityManager.clear() } - val result: List = reservationRepository.findAllById(reservation.member.id!!) + val result: List = reservationRepository.findAllByMemberId(reservation.member.id!!) result shouldHaveSize 1 assertSoftly(result.first()) { @@ -179,7 +179,7 @@ class ReservationRepositoryTest( } test("결제 정보가 없다면 paymentKey와 amount는 null로 반환한다.") { - val result: List = reservationRepository.findAllById(reservation.member.id!!) + val result: List = reservationRepository.findAllByMemberId(reservation.member.id!!) result shouldHaveSize 1 assertSoftly(result.first()) { diff --git a/src/test/kotlin/roomescape/reservation/web/ReservationControllerTest.kt b/src/test/kotlin/roomescape/reservation/web/ReservationControllerTest.kt index 5a94cae9..04e3fb2a 100644 --- a/src/test/kotlin/roomescape/reservation/web/ReservationControllerTest.kt +++ b/src/test/kotlin/roomescape/reservation/web/ReservationControllerTest.kt @@ -19,13 +19,14 @@ import org.springframework.http.MediaType import org.springframework.transaction.support.TransactionTemplate import roomescape.auth.infrastructure.jwt.JwtHandler import roomescape.auth.web.support.MemberIdResolver -import roomescape.common.exception.ErrorType -import roomescape.common.exception.RoomescapeException import roomescape.member.business.MemberService import roomescape.member.infrastructure.persistence.MemberEntity import roomescape.member.infrastructure.persistence.Role +import roomescape.payment.exception.PaymentErrorCode +import roomescape.payment.exception.PaymentException import roomescape.payment.infrastructure.client.TossPaymentClient import roomescape.payment.infrastructure.persistence.PaymentEntity +import roomescape.reservation.exception.ReservationErrorCode import roomescape.reservation.infrastructure.persistence.ReservationEntity import roomescape.reservation.infrastructure.persistence.ReservationStatus import roomescape.theme.exception.ThemeErrorCode @@ -89,10 +90,7 @@ class ReservationControllerTest( test("결제 과정에서 발생하는 에러는 그대로 응답") { val reservationRequest = createRequest() - val paymentException = RoomescapeException( - ErrorType.PAYMENT_SERVER_ERROR, - HttpStatus.INTERNAL_SERVER_ERROR - ) + val paymentException = PaymentException(PaymentErrorCode.PAYMENT_PROVIDER_ERROR) every { paymentClient.confirm(any()) @@ -105,8 +103,8 @@ class ReservationControllerTest( }.When { post("/reservations") }.Then { - statusCode(paymentException.httpStatus.value()) - body("errorType", equalTo(paymentException.errorType.name)) + statusCode(paymentException.errorCode.httpStatus.value()) + body("code", equalTo(paymentException.errorCode.errorCode)) } } @@ -235,6 +233,7 @@ class ReservationControllerTest( val startDate = LocalDate.now().plusDays(1) val endDate = LocalDate.now() + val expectedError = ReservationErrorCode.INVALID_SEARCH_DATE_RANGE Given { port(port) @@ -244,8 +243,8 @@ class ReservationControllerTest( }.When { get("/reservations/search") }.Then { - statusCode(HttpStatus.BAD_REQUEST.value()) - body("errorType", equalTo(ErrorType.INVALID_DATE_RANGE.name)) + statusCode(expectedError.httpStatus.value()) + body("code", equalTo(expectedError.errorCode)) } } @@ -501,6 +500,7 @@ class ReservationControllerTest( themeId = reservationRequest.themeId, timeId = reservationRequest.timeId ) + val expectedError = ReservationErrorCode.ALREADY_RESERVE Given { port(port) @@ -509,8 +509,8 @@ class ReservationControllerTest( }.When { post("/reservations/waiting") }.Then { - statusCode(HttpStatus.BAD_REQUEST.value()) - body("errorType", equalTo(ErrorType.HAS_RESERVATION_OR_WAITING.name)) + statusCode(expectedError.httpStatus.value()) + body("code", equalTo(expectedError.errorCode)) } } } @@ -544,20 +544,21 @@ class ReservationControllerTest( } } - test("이미 완료된 예약은 삭제할 수 없다.") { + test("이미 확정된 예약을 삭제하면 예외 응답") { val member = login(MemberFixture.create(role = Role.MEMBER)) val reservation: ReservationEntity = createSingleReservation( member = member, status = ReservationStatus.CONFIRMED_PAYMENT_REQUIRED ) + val expectedError = ReservationErrorCode.ALREADY_CONFIRMED Given { port(port) }.When { delete("/reservations/waiting/{id}", reservation.id) }.Then { - body("errorType", equalTo(ErrorType.RESERVATION_NOT_FOUND.name)) - statusCode(HttpStatus.NOT_FOUND.value()) + statusCode(expectedError.httpStatus.value()) + body("code", equalTo(expectedError.errorCode)) } } } @@ -600,6 +601,42 @@ class ReservationControllerTest( } ?: throw AssertionError("Reservation not found") } } + + test("다른 확정된 예약을 승인하면 예외 응답") { + val admin = login(MemberFixture.create(role = Role.ADMIN)) + val alreadyReserved = createSingleReservation( + member = admin, + status = ReservationStatus.CONFIRMED + ) + + val member = MemberFixture.create(account = "account", role = Role.MEMBER).also { it -> + transactionTemplate.executeWithoutResult { _ -> + entityManager.persist(it) + } + } + val waiting = ReservationFixture.create( + date = alreadyReserved.date, + time = alreadyReserved.time, + theme = alreadyReserved.theme, + member = member, + status = ReservationStatus.WAITING + ).also { + transactionTemplate.executeWithoutResult { _ -> + entityManager.persist(it) + } + } + + val expectedError = ReservationErrorCode.CONFIRMED_RESERVATION_ALREADY_EXISTS + Given { + port(port) + }.When { + post("/reservations/waiting/${waiting.id!!}/confirm") + }.Then { + log().all() + statusCode(expectedError.httpStatus.value()) + body("code", equalTo(expectedError.errorCode)) + } + } } context("POST /reservations/waiting/{id}/reject") {