feat(gift): 선물 신청 명령 서비스를 추가한다
This commit is contained in:
@@ -0,0 +1,868 @@
|
||||
package kr.co.vividnext.sodalive.v2.gift
|
||||
|
||||
import kr.co.vividnext.sodalive.can.CanRepository
|
||||
import kr.co.vividnext.sodalive.can.charge.Charge
|
||||
import kr.co.vividnext.sodalive.can.charge.ChargeRepository
|
||||
import kr.co.vividnext.sodalive.can.payment.CanPaymentService
|
||||
import kr.co.vividnext.sodalive.can.payment.Payment
|
||||
import kr.co.vividnext.sodalive.can.payment.PaymentGateway
|
||||
import kr.co.vividnext.sodalive.can.payment.PaymentStatus
|
||||
import kr.co.vividnext.sodalive.can.use.CanUsage
|
||||
import kr.co.vividnext.sodalive.can.use.UseCan
|
||||
import kr.co.vividnext.sodalive.can.use.UseCanCalculate
|
||||
import kr.co.vividnext.sodalive.can.use.UseCanCalculateRepository
|
||||
import kr.co.vividnext.sodalive.can.use.UseCanRepository
|
||||
import kr.co.vividnext.sodalive.common.CountryContext
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.i18n.LangContext
|
||||
import kr.co.vividnext.sodalive.i18n.SodaMessageSource
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRepository
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.Gift
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftCategory
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftCategoryRepository
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftDelivery
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftDeliveryRepository
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftRepository
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftReview
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftReviewRepository
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftSizePrice
|
||||
import kr.co.vividnext.sodalive.v2.gift.adapter.out.persistence.GiftSizePriceRepository
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftApplicationCommand
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftApplicationNoGenerator
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftCancellationResult
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftCommandService
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftDeliveryConfirmationResult
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftPushService
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftRecipientAddressRegistrationCommand
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftRecipientAddressRegistrationResult
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftReviewCommand
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftReviewResult
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftTrackingRegistrationCommand
|
||||
import kr.co.vividnext.sodalive.v2.gift.application.GiftTrackingRegistrationResult
|
||||
import kr.co.vividnext.sodalive.v2.gift.domain.GiftSize
|
||||
import kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Assertions.assertThrows
|
||||
import org.junit.jupiter.api.DisplayName
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.MethodSource
|
||||
import org.mockito.Mockito
|
||||
import java.time.LocalDateTime
|
||||
import java.util.Optional
|
||||
|
||||
class GiftCommandServiceTest {
|
||||
@Test
|
||||
@DisplayName("선물 캔 사용은 한 번만 환불할 수 있다")
|
||||
fun shouldSpendAndRefundGiftCanOnlyOnce() {
|
||||
// Given: 충전 캔을 보유한 선물 발신자와 결제 서비스를 준비한다.
|
||||
val member = Member(password = "password", nickname = "sender")
|
||||
member.id = MEMBER_ID
|
||||
member.pgChargeCan = INITIAL_CAN
|
||||
val charge = Charge(chargeCan = INITIAL_CAN, rewardCan = 0)
|
||||
charge.id = CHARGE_ID
|
||||
charge.member = member
|
||||
charge.payment = Payment(status = PaymentStatus.COMPLETE, paymentGateway = PaymentGateway.PG)
|
||||
val fixture = CanPaymentFixture(member, charge)
|
||||
|
||||
// When: 선물용 캔을 사용한 뒤 해당 사용 내역을 환불한다.
|
||||
val useCanId = fixture.service.spendGiftCan(
|
||||
memberId = MEMBER_ID,
|
||||
needCan = GIFT_PRICE_CAN,
|
||||
container = "web"
|
||||
)
|
||||
val afterSpendCan = member.getChargeCan("web") + member.getRewardCan("web")
|
||||
fixture.service.refundGiftCan(memberId = MEMBER_ID, useCanId = useCanId)
|
||||
val afterRefundCan = member.getChargeCan("web") + member.getRewardCan("web")
|
||||
|
||||
// Then: 발신자와 GIFT 용도가 저장되고, 잔액이 복원되며 재환불은 거부된다.
|
||||
assertEquals(CanUsage.GIFT, fixture.savedUseCan.canUsage)
|
||||
assertEquals(member, fixture.savedUseCan.member)
|
||||
assertEquals(INITIAL_CAN - GIFT_PRICE_CAN, afterSpendCan)
|
||||
assertEquals(INITIAL_CAN, afterRefundCan)
|
||||
assertEquals(true, fixture.savedUseCan.isRefund)
|
||||
assertThrows(SodaException::class.java) {
|
||||
fixture.service.refundGiftCan(memberId = MEMBER_ID, useCanId = useCanId)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("선물 신청은 가격과 약관 동의, 배송 기한을 스냅샷으로 저장하고 캔을 차감한다")
|
||||
fun shouldRegisterGiftWithPriceAgreementAndDeliverySnapshots() {
|
||||
// Given: 활성 선물 카테고리와 가격, 발신자 및 수신 크리에이터를 준비한다.
|
||||
val fixture = GiftApplicationFixture()
|
||||
|
||||
// When: 팬이 선물을 신청한다.
|
||||
val result = fixture.service.registerGift(fixture.sender, validGiftApplicationCommand())
|
||||
|
||||
// Then: 신청 정보와 배송 기한을 저장하고 판매가만큼 캔을 차감한다.
|
||||
assertEquals(APPLICATION_NO, result.applicationNo)
|
||||
assertEquals(GiftStatus.RECEIVED, result.status)
|
||||
assertEquals(GiftStatus.RECEIVED.displayName, result.statusName)
|
||||
assertEquals(SALE_PRICE_CAN, result.priceCan)
|
||||
assertEquals(NOW.plusDays(3), result.trackingDeadlineAt)
|
||||
assertEquals(SENDER_ID, fixture.savedGift.senderMemberId)
|
||||
assertEquals(RECIPIENT_ID, fixture.savedGift.recipientMemberId)
|
||||
assertEquals(GiftStatus.RECEIVED, fixture.savedGift.status)
|
||||
assertEquals(GiftSize.SMALL, fixture.savedGift.sizeCode)
|
||||
assertEquals(CATEGORY_ID, fixture.savedGift.categoryId)
|
||||
assertEquals("인형", fixture.savedGift.categoryNameSnapshot)
|
||||
assertEquals(SALE_PRICE_CAN, fixture.savedGift.salePriceCan)
|
||||
assertEquals(USE_CAN_ID, fixture.savedGift.canUsageId)
|
||||
assertEquals(true, fixture.savedGift.senderTermsAgreed)
|
||||
assertEquals(true, fixture.savedGift.senderPrivacyAgreed)
|
||||
assertEquals(NOW, fixture.savedGift.senderTermsAgreedAt)
|
||||
assertEquals(NOW, fixture.savedGift.senderPrivacyAgreedAt)
|
||||
assertEquals(true, fixture.savedGift.damageWaiverAgreed)
|
||||
assertEquals(GIFT_ID, fixture.savedDelivery.giftId)
|
||||
assertEquals("홍길동", fixture.savedDelivery.senderName)
|
||||
assertEquals("01012345678", fixture.savedDelivery.senderPhoneNumber)
|
||||
assertEquals("06234", fixture.savedDelivery.senderZipCode)
|
||||
assertEquals("서울시 강남구", fixture.savedDelivery.senderAddress)
|
||||
assertEquals("101동 1001호", fixture.savedDelivery.senderAddressDetail)
|
||||
assertEquals(NOW.plusDays(3), fixture.savedDelivery.trackingDeadlineAt)
|
||||
Mockito.verify(fixture.canPaymentService).spendGiftCan(SENDER_ID, SALE_PRICE_CAN, "aos")
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("보낸 팬은 운송장 등록 전 선물을 취소하고 전액 환불받는다")
|
||||
fun shouldCancelReceivedGiftAndRefundOnce() {
|
||||
// Given: 접수 상태의 선물과 발신자 배송 정보를 준비한다.
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForCancellation()
|
||||
|
||||
// When: 보낸 팬이 선물을 취소한다.
|
||||
val result = fixture.service.cancelGift(fixture.sender, APPLICATION_NO)
|
||||
|
||||
// Then: 선물과 배송 정보에 취소 시각을 저장하고 한 번만 환불한다.
|
||||
assertEquals(
|
||||
GiftCancellationResult(
|
||||
applicationNo = APPLICATION_NO,
|
||||
status = GiftStatus.CANCELED,
|
||||
statusName = GiftStatus.CANCELED.displayName,
|
||||
priceCan = SALE_PRICE_CAN,
|
||||
canceledAt = NOW
|
||||
),
|
||||
result
|
||||
)
|
||||
assertEquals(GiftStatus.CANCELED, fixture.cancellationGift.status)
|
||||
assertEquals(NOW, fixture.cancellationDelivery.canceledAt)
|
||||
Mockito.verify(fixture.canPaymentService).refundGiftCan(SENDER_ID, USE_CAN_ID)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("보낸 팬은 접수된 선물의 운송장을 등록하고 크리에이터 배송지 입력 기한을 생성한다")
|
||||
fun shouldRegisterTrackingForReceivedGift() {
|
||||
// Given: 접수 상태의 선물과 발신자 배송 정보를 준비한다.
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForTracking()
|
||||
|
||||
// When: 보낸 팬이 택배사와 운송장 번호를 등록한다.
|
||||
val result = fixture.service.registerTracking(
|
||||
fixture.sender,
|
||||
APPLICATION_NO,
|
||||
validGiftTrackingRegistrationCommand()
|
||||
)
|
||||
|
||||
// Then: 발송 확인 상태와 운송장 정보, 수신자 주소 입력 기한을 저장한다.
|
||||
assertEquals(
|
||||
GiftTrackingRegistrationResult(
|
||||
applicationNo = APPLICATION_NO,
|
||||
status = GiftStatus.TRACKING_REGISTERED,
|
||||
statusName = GiftStatus.TRACKING_REGISTERED.displayName,
|
||||
courierCompanyName = "CJ대한통운",
|
||||
trackingNumber = "1234567890",
|
||||
trackingRegisteredAt = NOW,
|
||||
recipientAddressDeadlineAt = NOW.plusDays(7)
|
||||
),
|
||||
result
|
||||
)
|
||||
assertEquals(GiftStatus.TRACKING_REGISTERED, fixture.trackingGift.status)
|
||||
assertEquals("CJ대한통운", fixture.trackingDelivery.courierCompanyName)
|
||||
assertEquals("1234567890", fixture.trackingDelivery.trackingNumber)
|
||||
assertEquals(NOW, fixture.trackingDelivery.trackingRegisteredAt)
|
||||
assertEquals(NOW.plusDays(7), fixture.trackingDelivery.recipientAddressDeadlineAt)
|
||||
Mockito.verify(fixture.giftPushService).sendTrackingRegisteredToRecipient(APPLICATION_NO, RECIPIENT_ID)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("recipientAddressRegistrableStatuses")
|
||||
@DisplayName("받는 크리에이터는 운송장 등록 이후 종료 전 상태에서 주소와 수령 동의를 등록한다")
|
||||
fun shouldRegisterRecipientAddressAndAgreements(status: GiftStatus) {
|
||||
// Given: 주소 입력이 허용된 선물과 받는 크리에이터를 준비한다.
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForRecipientAddress(status = status)
|
||||
|
||||
// When: 받는 크리에이터가 배송지와 수령 약관 동의를 등록한다.
|
||||
val result = fixture.service.registerRecipientAddress(
|
||||
fixture.creator,
|
||||
APPLICATION_NO,
|
||||
validGiftRecipientAddressRegistrationCommand()
|
||||
)
|
||||
|
||||
// Then: 주소 스냅샷과 두 동의 시각을 저장하고 현재 상태를 반환한다.
|
||||
assertEquals(
|
||||
GiftRecipientAddressRegistrationResult(
|
||||
applicationNo = APPLICATION_NO,
|
||||
status = status,
|
||||
statusName = status.displayName,
|
||||
recipientAddressRegisteredAt = NOW
|
||||
),
|
||||
result
|
||||
)
|
||||
assertEquals("김소다", fixture.recipientAddressDelivery.recipientName)
|
||||
assertEquals("01098765432", fixture.recipientAddressDelivery.recipientPhoneNumber)
|
||||
assertEquals("04524", fixture.recipientAddressDelivery.recipientZipCode)
|
||||
assertEquals("서울시 중구", fixture.recipientAddressDelivery.recipientAddress)
|
||||
assertEquals("202호", fixture.recipientAddressDelivery.recipientAddressDetail)
|
||||
assertEquals(true, fixture.recipientAddressGift.recipientTermsAgreed)
|
||||
assertEquals(true, fixture.recipientAddressGift.recipientPrivacyAgreed)
|
||||
assertEquals(NOW, fixture.recipientAddressGift.recipientTermsAgreedAt)
|
||||
assertEquals(NOW, fixture.recipientAddressGift.recipientPrivacyAgreedAt)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("받는 크리에이터는 검수 완료 선물의 수령을 확인하고 전달 완료 시각을 저장한다")
|
||||
fun shouldConfirmDeliveryForInspectionCompletedGift() {
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForDeliveryConfirmation()
|
||||
|
||||
val result = fixture.service.confirmDelivery(fixture.creator, APPLICATION_NO)
|
||||
|
||||
assertEquals(
|
||||
GiftDeliveryConfirmationResult(
|
||||
applicationNo = APPLICATION_NO,
|
||||
status = GiftStatus.DELIVERED,
|
||||
statusName = GiftStatus.DELIVERED.displayName,
|
||||
deliveredAt = NOW
|
||||
),
|
||||
result
|
||||
)
|
||||
assertEquals(GiftStatus.DELIVERED, fixture.deliveryConfirmationGift.status)
|
||||
assertEquals(NOW, fixture.deliveryConfirmationDelivery.deliveredAt)
|
||||
Mockito.verifyNoInteractions(fixture.giftPushService)
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("보낸 팬은 전달 완료 선물에 리뷰를 한 번 작성한다")
|
||||
fun shouldWriteReviewForDeliveredGiftBySender() {
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForReview()
|
||||
|
||||
val result = fixture.service.writeReview(fixture.sender, APPLICATION_NO, validGiftReviewCommand())
|
||||
|
||||
assertEquals(
|
||||
GiftReviewResult(
|
||||
reviewId = REVIEW_ID,
|
||||
applicationNo = APPLICATION_NO,
|
||||
rating = 5,
|
||||
keywords = listOf("배송이 빨라요", "안내가 친절해요"),
|
||||
comment = "선물 전달 과정이 만족스러웠습니다.",
|
||||
createdAt = NOW
|
||||
),
|
||||
result
|
||||
)
|
||||
assertEquals(GIFT_ID, fixture.savedReview.giftId)
|
||||
assertEquals(SENDER_ID, fixture.savedReview.senderMemberId)
|
||||
assertEquals(5, fixture.savedReview.rating)
|
||||
assertEquals("배송이 빨라요,안내가 친절해요", fixture.savedReview.keywords)
|
||||
assertEquals("선물 전달 과정이 만족스러웠습니다.", fixture.savedReview.comment)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidGiftReviewScenarios")
|
||||
@DisplayName("리뷰 작성은 보낸 팬의 전달 완료 선물, 1회, 유효한 별점과 내용만 허용한다")
|
||||
fun shouldRejectInvalidGiftReview(scenario: InvalidGiftReviewScenario) {
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForReview(
|
||||
status = scenario.status,
|
||||
senderMemberId = scenario.senderMemberId,
|
||||
reviewExists = scenario.reviewExists
|
||||
)
|
||||
val requester = Member(password = "password", nickname = "requester").apply { id = scenario.requesterMemberId }
|
||||
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
fixture.service.writeReview(requester, APPLICATION_NO, scenario.command)
|
||||
}
|
||||
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
Mockito.verify(fixture.reviewRepository, Mockito.never()).save(Mockito.any(GiftReview::class.java))
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidGiftDeliveryConfirmationScenarios")
|
||||
@DisplayName("수령 확인은 받는 크리에이터의 검수 완료 선물에만 가능하고 배송 정보가 필요하다")
|
||||
fun shouldRejectInvalidGiftDeliveryConfirmation(scenario: InvalidGiftDeliveryConfirmationScenario) {
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForDeliveryConfirmation(
|
||||
status = scenario.status,
|
||||
recipientMemberId = scenario.recipientMemberId,
|
||||
deliveryExists = scenario.deliveryExists
|
||||
)
|
||||
val requester = Member(password = "password", nickname = "requester").apply { id = scenario.requesterMemberId }
|
||||
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
fixture.service.confirmDelivery(requester, APPLICATION_NO)
|
||||
}
|
||||
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
assertEquals(scenario.status, fixture.deliveryConfirmationGift.status)
|
||||
assertEquals(null, fixture.deliveryConfirmationDelivery.deliveredAt)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidGiftRecipientAddressRegistrationScenarios")
|
||||
@DisplayName("수령자 주소 등록은 받는 크리에이터, 허용 상태, 필수 주소와 두 동의가 필요하다")
|
||||
fun shouldRejectInvalidGiftRecipientAddressRegistration(scenario: InvalidGiftRecipientAddressRegistrationScenario) {
|
||||
// Given: 권한, 상태 또는 입력값이 유효하지 않은 선물을 준비한다.
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForRecipientAddress(
|
||||
status = scenario.status,
|
||||
recipientMemberId = scenario.recipientMemberId,
|
||||
deliveryExists = scenario.deliveryExists
|
||||
)
|
||||
val requester = Member(password = "password", nickname = "requester").apply { id = scenario.requesterMemberId }
|
||||
|
||||
// When: 배송지 등록을 요청한다.
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
fixture.service.registerRecipientAddress(requester, APPLICATION_NO, scenario.command)
|
||||
}
|
||||
|
||||
// Then: 공통 요청 오류를 반환하고 선물 상태와 수령 동의를 바꾸지 않는다.
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
assertEquals(scenario.status, fixture.recipientAddressGift.status)
|
||||
assertEquals(false, fixture.recipientAddressGift.recipientTermsAgreed)
|
||||
assertEquals(false, fixture.recipientAddressGift.recipientPrivacyAgreed)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidGiftTrackingRegistrationScenarios")
|
||||
@DisplayName("운송장 등록은 보낸 팬의 접수 상태에서 유효한 택배사와 운송장 번호가 있어야 한다")
|
||||
fun shouldRejectInvalidGiftTrackingRegistration(scenario: InvalidGiftTrackingRegistrationScenario) {
|
||||
// Given: 운송장 등록 권한, 상태, 입력값 또는 배송 정보가 유효하지 않은 선물을 준비한다.
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForTracking(scenario.status, scenario.senderMemberId, scenario.deliveryExists)
|
||||
val requester = Member(password = "password", nickname = "requester").apply { id = scenario.requesterMemberId }
|
||||
|
||||
// When: 운송장 등록을 요청한다.
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
fixture.service.registerTracking(requester, APPLICATION_NO, scenario.command)
|
||||
}
|
||||
|
||||
// Then: 공통 요청 오류를 반환하고 선물 상태를 바꾸지 않는다.
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
assertEquals(scenario.status, fixture.trackingGift.status)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidGiftCancellationScenarios")
|
||||
@DisplayName("선물 취소는 보낸 팬의 접수 상태에서만 가능하다")
|
||||
fun shouldRejectGiftCancellationForInvalidSenderOrStatus(scenario: InvalidGiftCancellationScenario) {
|
||||
// Given: 취소 권한 또는 상태가 유효하지 않은 선물을 준비한다.
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.prepareGiftForCancellation(scenario.status, scenario.senderMemberId)
|
||||
val requester = Member(password = "password", nickname = "requester").apply { id = scenario.requesterMemberId }
|
||||
|
||||
// When: 취소를 요청한다.
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
fixture.service.cancelGift(requester, APPLICATION_NO)
|
||||
}
|
||||
|
||||
// Then: 환불하지 않고 공통 요청 오류를 반환한다.
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
Mockito.verify(fixture.canPaymentService, Mockito.never()).refundGiftCan(
|
||||
Mockito.anyLong(),
|
||||
Mockito.anyLong()
|
||||
)
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("invalidGiftApplicationScenarios")
|
||||
@DisplayName("선물 신청은 필수 발신자 정보, 동의, 활성 옵션 및 수신 크리에이터를 검증한다")
|
||||
fun shouldRejectInvalidGiftApplication(scenario: InvalidGiftApplicationScenario) {
|
||||
// Given: 하나의 신청 조건만 유효하지 않은 선물 신청을 준비한다.
|
||||
val fixture = GiftApplicationFixture()
|
||||
fixture.category.isActive = scenario.categoryActive
|
||||
fixture.category.requiresDamageWaiver = scenario.requiresDamageWaiver
|
||||
fixture.sizePrice.isActive = scenario.sizePriceActive
|
||||
fixture.setCreatorExists(scenario.creatorExists)
|
||||
|
||||
// When: 유효하지 않은 신청을 등록한다.
|
||||
val exception = assertThrows(SodaException::class.java) {
|
||||
fixture.service.registerGift(fixture.sender, scenario.command)
|
||||
}
|
||||
|
||||
// Then: 캔을 차감하지 않고 공통 요청 오류를 반환한다.
|
||||
assertEquals("common.error.invalid_request", exception.messageKey)
|
||||
Mockito.verifyNoInteractions(fixture.canPaymentService)
|
||||
}
|
||||
|
||||
private class CanPaymentFixture(member: Member, charge: Charge) {
|
||||
private val canRepository = Mockito.mock(CanRepository::class.java)
|
||||
private val memberRepository = Mockito.mock(MemberRepository::class.java)
|
||||
private val chargeRepository = Mockito.mock(ChargeRepository::class.java)
|
||||
private val useCanRepository = Mockito.mock(UseCanRepository::class.java)
|
||||
private val useCanCalculateRepository = Mockito.mock(UseCanCalculateRepository::class.java)
|
||||
private val useCanCalculates = mutableListOf<UseCanCalculate>()
|
||||
lateinit var savedUseCan: UseCan
|
||||
private set
|
||||
|
||||
val service = CanPaymentService(
|
||||
repository = canRepository,
|
||||
memberRepository = memberRepository,
|
||||
chargeRepository = chargeRepository,
|
||||
useCanRepository = useCanRepository,
|
||||
useCanCalculateRepository = useCanCalculateRepository,
|
||||
messageSource = SodaMessageSource(),
|
||||
langContext = LangContext(),
|
||||
countryContext = CountryContext()
|
||||
)
|
||||
|
||||
init {
|
||||
Mockito.`when`(memberRepository.findById(MEMBER_ID)).thenReturn(Optional.of(member))
|
||||
Mockito.`when`(
|
||||
chargeRepository.getOldestChargeWhereRewardCanGreaterThan0(0L, MEMBER_ID, "web")
|
||||
).thenReturn(null)
|
||||
Mockito.`when`(
|
||||
chargeRepository.getOldestChargeWhereChargeCanGreaterThan0(0L, MEMBER_ID, "web")
|
||||
).thenReturn(charge)
|
||||
Mockito.`when`(useCanRepository.save(Mockito.any(UseCan::class.java))).thenAnswer { invocation ->
|
||||
invocation.getArgument<UseCan>(0).apply {
|
||||
id = USE_CAN_ID
|
||||
savedUseCan = this
|
||||
}
|
||||
}
|
||||
Mockito.`when`(useCanRepository.findById(USE_CAN_ID)).thenAnswer { Optional.of(savedUseCan) }
|
||||
Mockito.`when`(useCanCalculateRepository.save(Mockito.any(UseCanCalculate::class.java))).thenAnswer {
|
||||
invocation ->
|
||||
invocation.getArgument<UseCanCalculate>(0).also(useCanCalculates::add)
|
||||
}
|
||||
Mockito.`when`(useCanCalculateRepository.findByUseCanIdAndStatus(USE_CAN_ID)).thenReturn(useCanCalculates)
|
||||
}
|
||||
}
|
||||
|
||||
private class GiftApplicationFixture {
|
||||
val giftRepository = Mockito.mock(GiftRepository::class.java)
|
||||
val deliveryRepository = Mockito.mock(GiftDeliveryRepository::class.java)
|
||||
val reviewRepository = Mockito.mock(GiftReviewRepository::class.java)
|
||||
val categoryRepository = Mockito.mock(GiftCategoryRepository::class.java)
|
||||
val sizePriceRepository = Mockito.mock(GiftSizePriceRepository::class.java)
|
||||
val memberRepository = Mockito.mock(MemberRepository::class.java)
|
||||
val applicationNoGenerator = Mockito.mock(GiftApplicationNoGenerator::class.java)
|
||||
val canPaymentService = Mockito.mock(CanPaymentService::class.java)
|
||||
val giftPushService = Mockito.mock(GiftPushService::class.java)
|
||||
val sender = Member(password = "password", nickname = "sender", container = "aos").apply { id = SENDER_ID }
|
||||
val creator = Member(password = "password", nickname = "creator").apply { id = RECIPIENT_ID }
|
||||
val category = GiftCategory("DOLL", "인형", false, true).apply { id = CATEGORY_ID }
|
||||
val sizePrice = GiftSizePrice(GiftSize.SMALL, BASE_PRICE_CAN, SALE_PRICE_CAN, true)
|
||||
lateinit var savedGift: Gift
|
||||
lateinit var savedDelivery: GiftDelivery
|
||||
lateinit var cancellationGift: Gift
|
||||
lateinit var cancellationDelivery: GiftDelivery
|
||||
lateinit var trackingGift: Gift
|
||||
lateinit var trackingDelivery: GiftDelivery
|
||||
lateinit var recipientAddressGift: Gift
|
||||
lateinit var recipientAddressDelivery: GiftDelivery
|
||||
lateinit var deliveryConfirmationGift: Gift
|
||||
lateinit var deliveryConfirmationDelivery: GiftDelivery
|
||||
lateinit var reviewGift: Gift
|
||||
lateinit var savedReview: GiftReview
|
||||
|
||||
val service = GiftCommandService(
|
||||
giftRepository = giftRepository,
|
||||
deliveryRepository = deliveryRepository,
|
||||
reviewRepository = reviewRepository,
|
||||
categoryRepository = categoryRepository,
|
||||
sizePriceRepository = sizePriceRepository,
|
||||
memberRepository = memberRepository,
|
||||
applicationNoGenerator = applicationNoGenerator,
|
||||
canPaymentService = canPaymentService,
|
||||
giftPushService = giftPushService,
|
||||
now = { NOW }
|
||||
)
|
||||
|
||||
init {
|
||||
setCreatorExists(true)
|
||||
Mockito.`when`(categoryRepository.findById(CATEGORY_ID)).thenReturn(Optional.of(category))
|
||||
Mockito.`when`(sizePriceRepository.findBySizeCode(GiftSize.SMALL)).thenReturn(sizePrice)
|
||||
Mockito.`when`(applicationNoGenerator.generate(NOW)).thenReturn(APPLICATION_NO)
|
||||
Mockito.`when`(canPaymentService.spendGiftCan(SENDER_ID, SALE_PRICE_CAN, "aos")).thenReturn(USE_CAN_ID)
|
||||
Mockito.`when`(giftRepository.save(Mockito.any(Gift::class.java))).thenAnswer { invocation ->
|
||||
invocation.getArgument<Gift>(0).apply {
|
||||
id = GIFT_ID
|
||||
savedGift = this
|
||||
}
|
||||
}
|
||||
Mockito.`when`(deliveryRepository.save(Mockito.any(GiftDelivery::class.java))).thenAnswer { invocation ->
|
||||
invocation.getArgument<GiftDelivery>(0).also { savedDelivery = it }
|
||||
}
|
||||
Mockito.`when`(reviewRepository.save(Mockito.any(GiftReview::class.java))).thenAnswer { invocation ->
|
||||
invocation.getArgument<GiftReview>(0).apply {
|
||||
id = REVIEW_ID
|
||||
createdAt = NOW
|
||||
savedReview = this
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun setCreatorExists(exists: Boolean) {
|
||||
Mockito.`when`(memberRepository.findCreatorByIdOrNull(RECIPIENT_ID)).thenReturn(creator.takeIf { exists })
|
||||
}
|
||||
|
||||
fun prepareGiftForCancellation(
|
||||
status: GiftStatus = GiftStatus.RECEIVED,
|
||||
senderMemberId: Long = SENDER_ID
|
||||
) {
|
||||
cancellationGift = Gift(
|
||||
applicationNo = APPLICATION_NO,
|
||||
senderMemberId = senderMemberId,
|
||||
recipientMemberId = RECIPIENT_ID,
|
||||
status = status,
|
||||
sizeCode = GiftSize.SMALL,
|
||||
categoryId = CATEGORY_ID,
|
||||
categoryNameSnapshot = "인형",
|
||||
salePriceCan = SALE_PRICE_CAN,
|
||||
canUsageId = USE_CAN_ID,
|
||||
senderTermsAgreed = true,
|
||||
senderPrivacyAgreed = true,
|
||||
senderTermsAgreedAt = NOW,
|
||||
senderPrivacyAgreedAt = NOW,
|
||||
damageWaiverAgreed = true
|
||||
).apply { id = GIFT_ID }
|
||||
cancellationDelivery = GiftDelivery(
|
||||
giftId = GIFT_ID,
|
||||
senderName = "홍길동",
|
||||
senderPhoneNumber = "01012345678",
|
||||
senderZipCode = "06234",
|
||||
senderAddress = "서울시 강남구",
|
||||
trackingDeadlineAt = NOW.plusDays(3)
|
||||
)
|
||||
Mockito.`when`(giftRepository.findByApplicationNo(APPLICATION_NO)).thenReturn(cancellationGift)
|
||||
Mockito.`when`(deliveryRepository.findByGiftId(GIFT_ID)).thenReturn(cancellationDelivery)
|
||||
}
|
||||
|
||||
fun prepareGiftForTracking(
|
||||
status: GiftStatus = GiftStatus.RECEIVED,
|
||||
senderMemberId: Long = SENDER_ID,
|
||||
deliveryExists: Boolean = true
|
||||
) {
|
||||
trackingGift = Gift(
|
||||
applicationNo = APPLICATION_NO,
|
||||
senderMemberId = senderMemberId,
|
||||
recipientMemberId = RECIPIENT_ID,
|
||||
status = status,
|
||||
sizeCode = GiftSize.SMALL,
|
||||
categoryId = CATEGORY_ID,
|
||||
categoryNameSnapshot = "인형",
|
||||
salePriceCan = SALE_PRICE_CAN,
|
||||
canUsageId = USE_CAN_ID,
|
||||
senderTermsAgreed = true,
|
||||
senderPrivacyAgreed = true,
|
||||
senderTermsAgreedAt = NOW,
|
||||
senderPrivacyAgreedAt = NOW,
|
||||
damageWaiverAgreed = true
|
||||
).apply { id = GIFT_ID }
|
||||
trackingDelivery = GiftDelivery(
|
||||
giftId = GIFT_ID,
|
||||
senderName = "홍길동",
|
||||
senderPhoneNumber = "01012345678",
|
||||
senderZipCode = "06234",
|
||||
senderAddress = "서울시 강남구",
|
||||
trackingDeadlineAt = NOW.plusDays(3)
|
||||
)
|
||||
Mockito.`when`(giftRepository.findByApplicationNo(APPLICATION_NO)).thenReturn(trackingGift)
|
||||
Mockito.`when`(deliveryRepository.findByGiftId(GIFT_ID)).thenReturn(
|
||||
trackingDelivery.takeIf { deliveryExists }
|
||||
)
|
||||
}
|
||||
|
||||
fun prepareGiftForRecipientAddress(
|
||||
status: GiftStatus = GiftStatus.TRACKING_REGISTERED,
|
||||
recipientMemberId: Long = RECIPIENT_ID,
|
||||
deliveryExists: Boolean = true
|
||||
) {
|
||||
recipientAddressGift = Gift(
|
||||
applicationNo = APPLICATION_NO,
|
||||
senderMemberId = SENDER_ID,
|
||||
recipientMemberId = recipientMemberId,
|
||||
status = status,
|
||||
sizeCode = GiftSize.SMALL,
|
||||
categoryId = CATEGORY_ID,
|
||||
categoryNameSnapshot = "인형",
|
||||
salePriceCan = SALE_PRICE_CAN,
|
||||
canUsageId = USE_CAN_ID,
|
||||
senderTermsAgreed = true,
|
||||
senderPrivacyAgreed = true,
|
||||
senderTermsAgreedAt = NOW,
|
||||
senderPrivacyAgreedAt = NOW,
|
||||
damageWaiverAgreed = true
|
||||
).apply { id = GIFT_ID }
|
||||
recipientAddressDelivery = GiftDelivery(
|
||||
giftId = GIFT_ID,
|
||||
senderName = "홍길동",
|
||||
senderPhoneNumber = "01012345678",
|
||||
senderZipCode = "06234",
|
||||
senderAddress = "서울시 강남구",
|
||||
trackingDeadlineAt = NOW.plusDays(3)
|
||||
)
|
||||
Mockito.`when`(giftRepository.findByApplicationNo(APPLICATION_NO)).thenReturn(recipientAddressGift)
|
||||
Mockito.`when`(deliveryRepository.findByGiftId(GIFT_ID)).thenReturn(
|
||||
recipientAddressDelivery.takeIf { deliveryExists }
|
||||
)
|
||||
}
|
||||
|
||||
fun prepareGiftForDeliveryConfirmation(
|
||||
status: GiftStatus = GiftStatus.INSPECTION_COMPLETED,
|
||||
recipientMemberId: Long = RECIPIENT_ID,
|
||||
deliveryExists: Boolean = true
|
||||
) {
|
||||
deliveryConfirmationGift = Gift(
|
||||
applicationNo = APPLICATION_NO,
|
||||
senderMemberId = SENDER_ID,
|
||||
recipientMemberId = recipientMemberId,
|
||||
status = status,
|
||||
sizeCode = GiftSize.SMALL,
|
||||
categoryId = CATEGORY_ID,
|
||||
categoryNameSnapshot = "인형",
|
||||
salePriceCan = SALE_PRICE_CAN,
|
||||
canUsageId = USE_CAN_ID,
|
||||
senderTermsAgreed = true,
|
||||
senderPrivacyAgreed = true,
|
||||
senderTermsAgreedAt = NOW,
|
||||
senderPrivacyAgreedAt = NOW,
|
||||
damageWaiverAgreed = true
|
||||
).apply { id = GIFT_ID }
|
||||
deliveryConfirmationDelivery = GiftDelivery(
|
||||
giftId = GIFT_ID,
|
||||
senderName = "홍길동",
|
||||
senderPhoneNumber = "01012345678",
|
||||
senderZipCode = "06234",
|
||||
senderAddress = "서울시 강남구",
|
||||
trackingDeadlineAt = NOW.plusDays(3)
|
||||
)
|
||||
Mockito.`when`(giftRepository.findByApplicationNo(APPLICATION_NO)).thenReturn(deliveryConfirmationGift)
|
||||
Mockito.`when`(deliveryRepository.findByGiftId(GIFT_ID)).thenReturn(
|
||||
deliveryConfirmationDelivery.takeIf { deliveryExists }
|
||||
)
|
||||
}
|
||||
|
||||
fun prepareGiftForReview(
|
||||
status: GiftStatus = GiftStatus.DELIVERED,
|
||||
senderMemberId: Long = SENDER_ID,
|
||||
reviewExists: Boolean = false
|
||||
) {
|
||||
reviewGift = Gift(
|
||||
applicationNo = APPLICATION_NO,
|
||||
senderMemberId = senderMemberId,
|
||||
recipientMemberId = RECIPIENT_ID,
|
||||
status = status,
|
||||
sizeCode = GiftSize.SMALL,
|
||||
categoryId = CATEGORY_ID,
|
||||
categoryNameSnapshot = "인형",
|
||||
salePriceCan = SALE_PRICE_CAN,
|
||||
canUsageId = USE_CAN_ID,
|
||||
senderTermsAgreed = true,
|
||||
senderPrivacyAgreed = true,
|
||||
senderTermsAgreedAt = NOW,
|
||||
senderPrivacyAgreedAt = NOW,
|
||||
damageWaiverAgreed = true
|
||||
).apply { id = GIFT_ID }
|
||||
Mockito.`when`(giftRepository.findByApplicationNo(APPLICATION_NO)).thenReturn(reviewGift)
|
||||
Mockito.`when`(reviewRepository.findByGiftId(GIFT_ID)).thenReturn(
|
||||
GiftReview(GIFT_ID, SENDER_ID, 5).takeIf { reviewExists }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class InvalidGiftApplicationScenario(
|
||||
val command: GiftApplicationCommand,
|
||||
val categoryActive: Boolean = true,
|
||||
val requiresDamageWaiver: Boolean = false,
|
||||
val sizePriceActive: Boolean = true,
|
||||
val creatorExists: Boolean = true
|
||||
)
|
||||
|
||||
data class InvalidGiftCancellationScenario(
|
||||
val requesterMemberId: Long,
|
||||
val senderMemberId: Long,
|
||||
val status: GiftStatus
|
||||
)
|
||||
|
||||
data class InvalidGiftTrackingRegistrationScenario(
|
||||
val requesterMemberId: Long = SENDER_ID,
|
||||
val senderMemberId: Long = SENDER_ID,
|
||||
val status: GiftStatus = GiftStatus.RECEIVED,
|
||||
val command: GiftTrackingRegistrationCommand = validGiftTrackingRegistrationCommand(),
|
||||
val deliveryExists: Boolean = true
|
||||
)
|
||||
|
||||
data class InvalidGiftRecipientAddressRegistrationScenario(
|
||||
val requesterMemberId: Long = RECIPIENT_ID,
|
||||
val recipientMemberId: Long = RECIPIENT_ID,
|
||||
val status: GiftStatus = GiftStatus.TRACKING_REGISTERED,
|
||||
val command: GiftRecipientAddressRegistrationCommand = validGiftRecipientAddressRegistrationCommand(),
|
||||
val deliveryExists: Boolean = true
|
||||
)
|
||||
|
||||
data class InvalidGiftDeliveryConfirmationScenario(
|
||||
val requesterMemberId: Long = RECIPIENT_ID,
|
||||
val recipientMemberId: Long = RECIPIENT_ID,
|
||||
val status: GiftStatus = GiftStatus.INSPECTION_COMPLETED,
|
||||
val deliveryExists: Boolean = true
|
||||
)
|
||||
|
||||
data class InvalidGiftReviewScenario(
|
||||
val requesterMemberId: Long = SENDER_ID,
|
||||
val senderMemberId: Long = SENDER_ID,
|
||||
val status: GiftStatus = GiftStatus.DELIVERED,
|
||||
val command: GiftReviewCommand = validGiftReviewCommand(),
|
||||
val reviewExists: Boolean = false
|
||||
)
|
||||
|
||||
private companion object {
|
||||
const val MEMBER_ID = 1L
|
||||
const val CHARGE_ID = 10L
|
||||
const val USE_CAN_ID = 100L
|
||||
const val INITIAL_CAN = 100
|
||||
const val GIFT_PRICE_CAN = 30
|
||||
const val SENDER_ID = 2L
|
||||
const val OTHER_MEMBER_ID = 4L
|
||||
const val RECIPIENT_ID = 3L
|
||||
const val CATEGORY_ID = 4L
|
||||
const val GIFT_ID = 5L
|
||||
const val REVIEW_ID = 6L
|
||||
const val APPLICATION_NO = "G20260929000001"
|
||||
const val BASE_PRICE_CAN = 100
|
||||
const val SALE_PRICE_CAN = 80
|
||||
val NOW: LocalDateTime = LocalDateTime.of(2026, 9, 29, 12, 0)
|
||||
|
||||
@JvmStatic
|
||||
fun invalidGiftApplicationScenarios() = listOf(
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand().copy(senderName = "")),
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand().copy(senderPhoneNumber = "")),
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand().copy(senderZipCode = "")),
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand().copy(senderAddress = "")),
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand().copy(senderTermsAgreed = false)),
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand().copy(senderPrivacyAgreed = false)),
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand(), categoryActive = false),
|
||||
InvalidGiftApplicationScenario(
|
||||
validGiftApplicationCommand().copy(damageWaiverAgreed = false),
|
||||
requiresDamageWaiver = true
|
||||
),
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand(), sizePriceActive = false),
|
||||
InvalidGiftApplicationScenario(validGiftApplicationCommand(), creatorExists = false)
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun invalidGiftCancellationScenarios() = listOf(
|
||||
InvalidGiftCancellationScenario(OTHER_MEMBER_ID, SENDER_ID, GiftStatus.RECEIVED),
|
||||
InvalidGiftCancellationScenario(SENDER_ID, SENDER_ID, GiftStatus.TRACKING_REGISTERED)
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun invalidGiftTrackingRegistrationScenarios() = listOf(
|
||||
InvalidGiftTrackingRegistrationScenario(requesterMemberId = OTHER_MEMBER_ID),
|
||||
InvalidGiftTrackingRegistrationScenario(status = GiftStatus.TRACKING_REGISTERED),
|
||||
InvalidGiftTrackingRegistrationScenario(
|
||||
command = validGiftTrackingRegistrationCommand().copy(courierCompanyName = "")
|
||||
),
|
||||
InvalidGiftTrackingRegistrationScenario(
|
||||
command = validGiftTrackingRegistrationCommand().copy(courierCompanyName = "a".repeat(51))
|
||||
),
|
||||
InvalidGiftTrackingRegistrationScenario(
|
||||
command = validGiftTrackingRegistrationCommand().copy(trackingNumber = "")
|
||||
),
|
||||
InvalidGiftTrackingRegistrationScenario(deliveryExists = false)
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun recipientAddressRegistrableStatuses() = listOf(
|
||||
GiftStatus.TRACKING_REGISTERED,
|
||||
GiftStatus.ARRIVED_AT_MAILBOX,
|
||||
GiftStatus.INSPECTION_COMPLETED
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun invalidGiftRecipientAddressRegistrationScenarios() = listOf(
|
||||
InvalidGiftRecipientAddressRegistrationScenario(requesterMemberId = OTHER_MEMBER_ID),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(status = GiftStatus.RECEIVED),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(status = GiftStatus.DELIVERED),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(status = GiftStatus.UNDELIVERABLE),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(status = GiftStatus.CANCELED),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(
|
||||
command = validGiftRecipientAddressRegistrationCommand().copy(name = "")
|
||||
),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(
|
||||
command = validGiftRecipientAddressRegistrationCommand().copy(phoneNumber = "")
|
||||
),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(
|
||||
command = validGiftRecipientAddressRegistrationCommand().copy(zipCode = "")
|
||||
),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(
|
||||
command = validGiftRecipientAddressRegistrationCommand().copy(address = "")
|
||||
),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(
|
||||
command = validGiftRecipientAddressRegistrationCommand().copy(recipientTermsAgreed = false)
|
||||
),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(
|
||||
command = validGiftRecipientAddressRegistrationCommand().copy(recipientPrivacyAgreed = false)
|
||||
),
|
||||
InvalidGiftRecipientAddressRegistrationScenario(deliveryExists = false)
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun invalidGiftDeliveryConfirmationScenarios() = listOf(
|
||||
InvalidGiftDeliveryConfirmationScenario(requesterMemberId = OTHER_MEMBER_ID),
|
||||
InvalidGiftDeliveryConfirmationScenario(status = GiftStatus.TRACKING_REGISTERED),
|
||||
InvalidGiftDeliveryConfirmationScenario(status = GiftStatus.DELIVERED),
|
||||
InvalidGiftDeliveryConfirmationScenario(deliveryExists = false)
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
fun invalidGiftReviewScenarios() = listOf(
|
||||
InvalidGiftReviewScenario(requesterMemberId = OTHER_MEMBER_ID),
|
||||
InvalidGiftReviewScenario(status = GiftStatus.INSPECTION_COMPLETED),
|
||||
InvalidGiftReviewScenario(reviewExists = true),
|
||||
InvalidGiftReviewScenario(command = validGiftReviewCommand().copy(rating = 0)),
|
||||
InvalidGiftReviewScenario(command = validGiftReviewCommand().copy(rating = 6)),
|
||||
InvalidGiftReviewScenario(command = validGiftReviewCommand().copy(keywords = listOf("a".repeat(256)))),
|
||||
InvalidGiftReviewScenario(command = validGiftReviewCommand().copy(comment = "a".repeat(256)))
|
||||
)
|
||||
|
||||
fun validGiftApplicationCommand() = GiftApplicationCommand(
|
||||
recipientMemberId = RECIPIENT_ID,
|
||||
senderName = "홍길동",
|
||||
senderPhoneNumber = "01012345678",
|
||||
senderZipCode = "06234",
|
||||
senderAddress = "서울시 강남구",
|
||||
senderAddressDetail = "101동 1001호",
|
||||
sizeCode = GiftSize.SMALL,
|
||||
categoryId = CATEGORY_ID,
|
||||
senderTermsAgreed = true,
|
||||
senderPrivacyAgreed = true,
|
||||
damageWaiverAgreed = true
|
||||
)
|
||||
|
||||
fun validGiftTrackingRegistrationCommand() = GiftTrackingRegistrationCommand(
|
||||
courierCompanyName = "CJ대한통운",
|
||||
trackingNumber = "1234567890"
|
||||
)
|
||||
|
||||
fun validGiftRecipientAddressRegistrationCommand() = GiftRecipientAddressRegistrationCommand(
|
||||
name = "김소다",
|
||||
phoneNumber = "01098765432",
|
||||
zipCode = "04524",
|
||||
address = "서울시 중구",
|
||||
addressDetail = "202호",
|
||||
recipientTermsAgreed = true,
|
||||
recipientPrivacyAgreed = true
|
||||
)
|
||||
|
||||
fun validGiftReviewCommand() = GiftReviewCommand(
|
||||
rating = 5,
|
||||
keywords = listOf("배송이 빨라요", "안내가 친절해요"),
|
||||
comment = "선물 전달 과정이 만족스러웠습니다."
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user