fix(gift): 배송지 미입력 만료 상태 범위를 확장한다

This commit is contained in:
2026-10-02 20:08:05 +09:00
parent 112ad755e5
commit 124a615a85
3 changed files with 73 additions and 5 deletions
@@ -80,7 +80,11 @@ interface GiftRepository : JpaRepository<Gift, Long> {
""" """
select g select g
from Gift g from Gift g
where g.status = kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.TRACKING_REGISTERED where g.status in (
kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.TRACKING_REGISTERED,
kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.ARRIVED_AT_MAILBOX,
kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.INSPECTION_COMPLETED
)
and exists ( and exists (
select d.id select d.id
from GiftDelivery d from GiftDelivery d
@@ -90,7 +94,7 @@ interface GiftRepository : JpaRepository<Gift, Long> {
) )
""" """
) )
fun findTrackingRegisteredGiftsWithRecipientAddressDeadlineBefore( fun findGiftsWithRecipientAddressDeadlineBefore(
@Param("now") now: LocalDateTime @Param("now") now: LocalDateTime
): List<Gift> ): List<Gift>
@@ -51,7 +51,7 @@ class GiftScheduler(
@Transactional @Transactional
fun markExpiredRecipientAddressGiftsUndeliverable(now: LocalDateTime): Int { fun markExpiredRecipientAddressGiftsUndeliverable(now: LocalDateTime): Int {
val expiredGifts = giftRepository.findTrackingRegisteredGiftsWithRecipientAddressDeadlineBefore(now) val expiredGifts = giftRepository.findGiftsWithRecipientAddressDeadlineBefore(now)
expiredGifts.forEach { gift -> expiredGifts.forEach { gift ->
gift.status = GiftStatus.UNDELIVERABLE gift.status = GiftStatus.UNDELIVERABLE
val delivery = requireNotNull(giftDeliveryRepository.findByGiftId(requireNotNull(gift.id))) val delivery = requireNotNull(giftDeliveryRepository.findByGiftId(requireNotNull(gift.id)))
@@ -117,6 +117,29 @@ class GiftSchedulerTest @Autowired constructor(
assertEquals("배송지 미입력 기한 초과", delivery.undeliverableReason) assertEquals("배송지 미입력 기한 초과", delivery.undeliverableReason)
} }
@Test
@DisplayName("배송지 입력 기한이 지난 진행 중 선물은 현재 상태와 무관하게 전달 불가 처리한다")
fun shouldMarkOverdueInProgressGiftsWithoutRecipientAddressUndeliverable() {
val now = LocalDateTime.of(2026, 10, 9, 12, 0)
val gifts = listOf(GiftStatus.ARRIVED_AT_MAILBOX, GiftStatus.INSPECTION_COMPLETED).mapIndexed { index, status ->
saveGift(
status = status,
trackingDeadlineAt = now.minusDays(7),
recipientAddressDeadlineAt = now.minusSeconds(1),
applicationNo = "$APPLICATION_NO-$index"
)
}
val updatedCount = scheduler.markExpiredRecipientAddressGiftsUndeliverable(now)
assertEquals(2, updatedCount)
gifts.forEach { (gift, delivery) ->
assertEquals(GiftStatus.UNDELIVERABLE, gift.status)
assertEquals(now, delivery.undeliverableAt)
assertEquals("배송지 미입력 기한 초과", delivery.undeliverableReason)
}
}
@Test @Test
@DisplayName("배송지 입력 기한과 같은 발송 확인 선물은 전달 불가 처리하지 않는다") @DisplayName("배송지 입력 기한과 같은 발송 확인 선물은 전달 불가 처리하지 않는다")
fun shouldIgnoreTrackingRegisteredGiftWhoseRecipientAddressDeadlineIsNotPast() { fun shouldIgnoreTrackingRegisteredGiftWhoseRecipientAddressDeadlineIsNotPast() {
@@ -154,6 +177,46 @@ class GiftSchedulerTest @Autowired constructor(
assertEquals(null, delivery.undeliverableReason) assertEquals(null, delivery.undeliverableReason)
} }
@Test
@DisplayName("미래 또는 미설정 기한과 대상 외 상태는 배송지 미입력 전달 불가 처리하지 않는다")
fun shouldIgnoreUnexpiredAndOutOfScopeGiftsWithoutRecipientAddress() {
val now = LocalDateTime.of(2026, 10, 9, 12, 0)
val unexpiredGifts = listOf(
saveGift(
GiftStatus.ARRIVED_AT_MAILBOX,
now.minusDays(7),
now.plusSeconds(1),
applicationNo = "A-1002609302001"
),
saveGift(
GiftStatus.INSPECTION_COMPLETED,
now.minusDays(7),
applicationNo = "A-1002609302002"
)
)
val terminalGifts = listOf(
GiftStatus.RECEIVED,
GiftStatus.DELIVERED,
GiftStatus.UNDELIVERABLE,
GiftStatus.CANCELED
).mapIndexed { index, status ->
saveGift(
status,
now.minusDays(7),
now.minusSeconds(1),
applicationNo = "A-100260930201$index"
)
}
val updatedCount = scheduler.markExpiredRecipientAddressGiftsUndeliverable(now)
assertEquals(0, updatedCount)
(unexpiredGifts + terminalGifts).forEach { (_, delivery) ->
assertEquals(null, delivery.undeliverableAt)
assertEquals(null, delivery.undeliverableReason)
}
}
@Test @Test
@DisplayName("배송지 미입력 전달 불가를 다시 실행해도 이미 전달 불가인 선물은 처리하지 않는다") @DisplayName("배송지 미입력 전달 불가를 다시 실행해도 이미 전달 불가인 선물은 처리하지 않는다")
fun shouldNotUpdateAlreadyUndeliverableGiftOnSecondRun() { fun shouldNotUpdateAlreadyUndeliverableGiftOnSecondRun() {
@@ -240,11 +303,12 @@ class GiftSchedulerTest @Autowired constructor(
status: GiftStatus, status: GiftStatus,
trackingDeadlineAt: LocalDateTime, trackingDeadlineAt: LocalDateTime,
recipientAddressDeadlineAt: LocalDateTime? = null, recipientAddressDeadlineAt: LocalDateTime? = null,
recipientAddress: String? = null recipientAddress: String? = null,
applicationNo: String = APPLICATION_NO
): Pair<Gift, GiftDelivery> { ): Pair<Gift, GiftDelivery> {
val gift = giftRepository.save( val gift = giftRepository.save(
Gift( Gift(
applicationNo = APPLICATION_NO, applicationNo = applicationNo,
senderMemberId = SENDER_MEMBER_ID, senderMemberId = SENDER_MEMBER_ID,
recipientMemberId = RECIPIENT_MEMBER_ID, recipientMemberId = RECIPIENT_MEMBER_ID,
status = status, status = status,