Test #464

Merged
klaus merged 8 commits from test into main 2026-11-01 06:23:24 +00:00
4 changed files with 129 additions and 78 deletions
Showing only changes of commit 373b11348b - Show all commits
@@ -108,17 +108,26 @@ interface GiftRepository : JpaRepository<Gift, Long>, GiftLockRepository {
"""
select g
from Gift g
where g.status = kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.DELIVERED
and exists (
select d.id
from GiftDelivery d
where d.giftId = g.id
and d.deliveredAt is not null
and d.deliveredAt <= :cutoff
)
where exists (
select d.id
from GiftDelivery d
where d.giftId = g.id
and (
(
g.status = kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.DELIVERED
and d.deliveredAt is not null
and d.deliveredAt <= :cutoff
)
or (
g.status = kr.co.vividnext.sodalive.v2.gift.domain.GiftStatus.UNDELIVERABLE
and d.undeliverableAt is not null
and d.undeliverableAt <= :cutoff
)
)
)
"""
)
fun findDeliveredGiftsWithDeliveryBeforeOrAt(@Param("cutoff") cutoff: LocalDateTime): List<Gift>
fun findGiftsWithPersonalDataRetentionExpired(@Param("cutoff") cutoff: LocalDateTime): List<Gift>
@Query(
"""
@@ -92,23 +92,23 @@ class GiftScheduler(
@Scheduled(cron = "0 20 * * * *", zone = "Asia/Seoul")
@Transactional
fun runDeliveredGiftPersonalDataErasure() {
val lock = redissonClient.getLock(DELIVERED_GIFT_PERSONAL_DATA_ERASURE_LOCK_KEY)
fun runGiftPersonalDataErasure() {
val lock = redissonClient.getLock(GIFT_PERSONAL_DATA_ERASURE_LOCK_KEY)
if (!lock.tryLock(0, -1, TimeUnit.SECONDS)) {
return
}
try {
eraseDeliveredGiftPersonalData(LocalDateTime.now())
eraseGiftPersonalData(LocalDateTime.now())
} finally {
unlockAfterTransaction(lock)
}
}
@Transactional
fun eraseDeliveredGiftPersonalData(now: LocalDateTime): Int {
fun eraseGiftPersonalData(now: LocalDateTime): Int {
val cutoff = now.minusDays(7)
val expiredGifts = giftRepository.findDeliveredGiftsWithDeliveryBeforeOrAt(cutoff)
val expiredGifts = giftRepository.findGiftsWithPersonalDataRetentionExpired(cutoff)
return expiredGifts.count { gift ->
val delivery = requireNotNull(giftDeliveryRepository.findByGiftId(requireNotNull(gift.id)))
@@ -218,7 +218,7 @@ class GiftScheduler(
const val DEADLINE_REMINDER_HOURS = 24L
const val EXPIRED_TRACKING_REGISTRATION_GIFTS_LOCK_KEY = "lock:gift-expired-tracking-registration-cancellation"
const val EXPIRED_RECIPIENT_ADDRESS_GIFTS_LOCK_KEY = "lock:gift-expired-recipient-address-undeliverable"
const val DELIVERED_GIFT_PERSONAL_DATA_ERASURE_LOCK_KEY = "lock:gift-delivered-personal-data-erasure"
const val GIFT_PERSONAL_DATA_ERASURE_LOCK_KEY = "lock:gift-delivered-personal-data-erasure"
const val DEADLINE_REMINDER_GIFTS_LOCK_KEY = "lock:gift-deadline-reminders"
const val EXPIRED_RECIPIENT_ADDRESS_REASON = "배송지 미입력 기한 초과"
}
@@ -162,7 +162,7 @@ class AdminGiftControllerTest @Autowired constructor(
mapOf(
"runExpiredTrackingRegistrationGiftCancellation" to "0 0 * * * *",
"runExpiredRecipientAddressGiftExpiration" to "0 10 * * * *",
"runDeliveredGiftPersonalDataErasure" to "0 20 * * * *",
"runGiftPersonalDataErasure" to "0 20 * * * *",
"runDeadlineReminderGifts" to "0 40 * * * *"
),
scheduledJobs.associate {
@@ -311,12 +311,13 @@ class AdminGiftControllerTest @Autowired constructor(
.andExpect(jsonPath("$.data.availableActions[1]").value("MARK_UNDELIVERABLE"))
}
@Test
@DisplayName("관리자는 개인정보가 지워진 전달 완료 선물을 기존 빈 문자열과 null 응답으로 조회한다")
fun shouldReturnCompatibleErasedAdminGiftResponses() {
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("관리자는 개인정보가 지워진 종료 선물을 기존 빈 문자열과 null 응답으로 조회한다")
fun shouldReturnCompatibleErasedAdminGiftResponses(giftStatus: GiftStatus) {
val (gift, delivery) = saveAdminGift(
applicationNo = "A-ERASED-CONTROLLER",
status = GiftStatus.DELIVERED,
status = giftStatus,
senderNickname = "erased-admin-fan",
recipientNickname = "erased-admin-creator",
withTracking = false
@@ -331,7 +332,7 @@ class AdminGiftControllerTest @Autowired constructor(
mockMvc.perform(get("/api/v2/admin/gifts/{applicationNo}", gift.applicationNo).with(user("admin").roles("ADMIN")))
.andExpect(status().isOk)
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.data.status").value("DELIVERED"))
.andExpect(jsonPath("$.data.status").value(giftStatus.name))
.andExpect(jsonPath("$.data.senderInfo.nickname").value("erased-admin-fan"))
.andExpect(jsonPath("$.data.senderInfo.name").value(""))
.andExpect(jsonPath("$.data.senderInfo.phoneNumber").value(""))
@@ -359,9 +360,10 @@ class AdminGiftControllerTest @Autowired constructor(
.andExpect(jsonPath("$.data.items[0].availableActions").isEmpty)
}
@Test
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("실제 Spring 개인정보 파기는 JWT HTTP 선물함 계약과 결제·동의·리뷰·이력을 보존한다")
fun shouldEraseDeliveredGiftAndPreserveRealJwtHttpContracts() {
fun shouldEraseGiftAndPreserveRealJwtHttpContracts(status: GiftStatus) {
val now = NOW.plusDays(14)
val recipient = memberRepository.saveAndFlush(
Member(email = "${UUID.randomUUID()}@test.com", password = "password", nickname = "erasure-recipient")
@@ -376,7 +378,7 @@ class AdminGiftControllerTest @Autowired constructor(
val review = requireNotNull(
transaction.execute {
val gift = giftRepository.findById(giftId).orElseThrow()
gift.status = GiftStatus.DELIVERED
gift.status = status
gift.recipientTermsAgreed = true
gift.recipientPrivacyAgreed = true
gift.recipientTermsAgreedAt = NOW
@@ -393,7 +395,9 @@ class AdminGiftControllerTest @Autowired constructor(
delivery.trackingRegisteredAt = NOW.minusDays(2)
delivery.arrivedAtMailboxAt = NOW.minusDays(1)
delivery.inspectionCompletedAt = NOW.plusDays(1)
delivery.deliveredAt = now.minusDays(7)
delivery.deliveredAt = now.minusDays(7).takeIf { status == GiftStatus.DELIVERED }
delivery.undeliverableAt = now.minusDays(7).takeIf { status == GiftStatus.UNDELIVERABLE }
delivery.undeliverableReason = "검수 실패".takeIf { status == GiftStatus.UNDELIVERABLE }
delivery.recipientAddressDeadlineAt = NOW.plusDays(5)
delivery.trackingDeadlineReminderSentAt = NOW.minusDays(3)
delivery.recipientAddressDeadlineReminderSentAt = NOW.plusDays(4)
@@ -437,8 +441,8 @@ class AdminGiftControllerTest @Autowired constructor(
listOf(false, true).forEach { erased ->
if (erased) {
assertFalse(TransactionSynchronizationManager.isActualTransactionActive())
assertEquals(1, scheduler.eraseDeliveredGiftPersonalData(now))
assertEquals(0, scheduler.eraseDeliveredGiftPersonalData(now))
assertEquals(1, scheduler.eraseGiftPersonalData(now))
assertEquals(0, scheduler.eraseGiftPersonalData(now))
assertFalse(TransactionSynchronizationManager.isActualTransactionActive())
}
listOf(detailPath, adminPath, adminListPath, "/api/v2/gifts?type=SENT", "/api/v2/gifts?type=RECEIVED").forEach {
@@ -476,16 +480,27 @@ class AdminGiftControllerTest @Autowired constructor(
originalTimeline = originalTimeline ?: sentData.path("statusTimeline")
assertTrue(requireNotNull(originalTimeline).isArray)
assertEquals(5, requireNotNull(originalTimeline).size())
assertEquals(json.textNode("2026-10-10T12:00:00Z"), requireNotNull(originalTimeline).last().path("occurredAt"))
assertEquals(
if (status == GiftStatus.DELIVERED) json.textNode("2026-10-10T12:00:00Z") else json.nullNode(),
requireNotNull(originalTimeline).last().path("occurredAt")
)
listOf(sentData, receivedData).forEach { data ->
assertEquals(originalTimeline, data.path("statusTimeline"))
assertEquals(
if (status == GiftStatus.UNDELIVERABLE) json.textNode("2026-10-10T12:00:00Z") else json.nullNode(),
data.path("delivery").path("undeliverableAt")
)
assertEquals(
if (status == GiftStatus.UNDELIVERABLE) json.textNode("검수 실패") else json.nullNode(),
data.path("delivery").path("undeliverableReason")
)
assertEquals(json.booleanNode(false), data.path("trackingRequired"))
assertEquals(json.booleanNode(false), data.path("recipientAddressRequired"))
assertEquals(json.nullNode(), data.path("mailbox"))
}
listOf(sentData, receivedData, adminData).forEach { data ->
assertEquals(json.textNode(APPLICATION_NO), data.path("applicationNo"))
assertEquals(json.textNode("DELIVERED"), data.path("status"))
assertEquals(json.textNode(status.name), data.path("status"))
}
listOf("senderInfo" to senderAddress, "recipientInfo" to recipientAddress).forEach { (field, address) ->
val nickname = if (field == "senderInfo") fixture.sender.nickname else recipient.nickname
@@ -499,7 +514,7 @@ class AdminGiftControllerTest @Autowired constructor(
assertEquals(json.numberNode(1), adminList.path("data").path("totalCount"))
val adminItem = adminList.path("data").path("items").single()
assertEquals(json.textNode(APPLICATION_NO), adminItem.path("applicationNo"))
assertEquals(json.textNode("DELIVERED"), adminItem.path("status"))
assertEquals(json.textNode(status.name), adminItem.path("status"))
assertEquals(json.textNode(fixture.sender.nickname), adminItem.path("senderNickname"))
assertEquals(json.textNode(recipient.nickname), adminItem.path("recipientNickname"))
listOf(adminData.path("inboundDeliveryInfo"), adminItem).forEach { data ->
@@ -514,13 +529,13 @@ class AdminGiftControllerTest @Autowired constructor(
assertEquals(json.numberNode(1), list.path("data").path("totalCount"))
val item = list.path("data").path("items").single()
assertEquals(json.textNode(APPLICATION_NO), item.path("applicationNo"))
assertEquals(json.textNode("DELIVERED"), item.path("status"))
assertEquals(json.textNode(status.name), item.path("status"))
assertEquals(json.textNode(direction), item.path("direction"))
assertEquals(json.textNode(nickname), item.path("counterpartNickname"))
assertEquals(json.booleanNode(!erased), item.path("recipientAddressRegistered"))
}
println(
"P15_HTTP erased=$erased status=200 success=true " +
"P17_HTTP giftStatus=$status erased=$erased status=200 success=true " +
"senderStringsEmpty=${sentData.path("senderInfo").all { it.isTextual && it.textValue().isEmpty() }} " +
"recipientAddressNull=${receivedData.path("recipientAddress").isNull} " +
"trackingNull=${sentData.path("giftInfo").path("tracking").isNull} " +
@@ -549,7 +564,8 @@ class AdminGiftControllerTest @Autowired constructor(
.refundGiftCan(requireNotNull(fixture.sender.id), fixture.gift.canUsageId)
Mockito.verifyNoInteractions(giftPushService)
println(
"P15_DB erased=1 repeated=0 persistedNulls=12 giftRows=1 deliveryRows=1 paymentConsentReviewHistoryPreserved=true"
"P17_DB giftStatus=$status erased=1 repeated=0 persistedNulls=12 giftRows=1 deliveryRows=1 " +
"paymentConsentReviewHistoryPreserved=true"
)
}
@@ -22,6 +22,7 @@ import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.EnumSource
import org.junit.jupiter.params.provider.MethodSource
import org.mockito.Mockito
import org.redisson.api.RLock
@@ -608,43 +609,51 @@ class GiftSchedulerTest @Autowired constructor(
Mockito.verifyNoInteractions(giftPushService)
}
@Test
@DisplayName("전달 완료 후 정확히 7일인 선물의 배송 개인정보 12개를 DB에서 지운다")
fun shouldEraseDeliveredGiftWhenDeliveredAtEqualsSevenDayCutoff() {
val (gift, _) = saveGiftForErasure(ERASURE_CUTOFF)
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("상태와 짝인 시각부터 정확히 7일인 선물의 배송 개인정보 12개를 DB에서 지운다")
fun shouldEraseGiftWhenMatchingTimestampEqualsSevenDayCutoff(status: GiftStatus) {
val (gift, _) = saveGiftForErasure(ERASURE_CUTOFF, status)
flushAndClear()
val eligibleGifts = giftRepository.findDeliveredGiftsWithDeliveryBeforeOrAt(ERASURE_CUTOFF)
assertEquals(1, scheduler.eraseGiftPersonalData(ERASURE_NOW))
val eligibleGifts = giftRepository.findGiftsWithPersonalDataRetentionExpired(ERASURE_CUTOFF)
assertEquals(listOf(gift.id), eligibleGifts.map { it.id })
assertEquals(1, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW))
flushAndClear()
assertEquals(List(12) { null }, personalData(reloadDelivery(gift)))
}
@Test
@DisplayName("전달 완료 후 7일보다 1초 덜 지난 선물의 개인정보는 보존한다")
fun shouldIgnoreDeliveredGiftOneSecondNewerThanSevenDayCutoff() {
val (gift, delivery) = saveGiftForErasure(ERASURE_CUTOFF.plusSeconds(1))
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("짝인 시각부터 7일보다 1초 덜 지났으면 다른 시각이 오래돼도 개인정보를 보존한다")
fun shouldIgnoreGiftOneSecondNewerThanSevenDayCutoffDespiteOldOtherTimestamp(status: GiftStatus) {
val (gift, delivery) = saveGiftForErasure(ERASURE_CUTOFF.plusSeconds(1), status)
if (status == GiftStatus.DELIVERED) {
delivery.undeliverableAt = ERASURE_CUTOFF.minusDays(30)
} else {
delivery.deliveredAt = ERASURE_CUTOFF.minusDays(30)
}
val originalPersonalData = personalData(delivery)
flushAndClear()
assertEquals(0, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW))
assertEquals(0, scheduler.eraseGiftPersonalData(ERASURE_NOW))
flushAndClear()
assertEquals(originalPersonalData, personalData(reloadDelivery(gift)))
}
@Test
@DisplayName("도입 시점보다 오래전에 생성되고 전달 완료된 과거 누적 선물도 지운다")
fun shouldEraseOlderHistoricalDeliveredGifts() {
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("도입 시점보다 오래전에 생성되고 종료된 과거 누적 선물도 지운다")
fun shouldEraseOlderHistoricalGifts(status: GiftStatus) {
val historicalAt = LocalDateTime.of(2020, 1, 1, 12, 0)
val (gift, delivery) = saveGiftForErasure(historicalAt.plusDays(10))
val (gift, delivery) = saveGiftForErasure(historicalAt.plusDays(10), status)
gift.createdAt = historicalAt
delivery.createdAt = historicalAt
flushAndClear()
assertEquals(1, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW))
assertEquals(1, scheduler.eraseGiftPersonalData(ERASURE_NOW))
flushAndClear()
assertEquals(List(12) { null }, personalData(reloadDelivery(gift)))
@@ -653,17 +662,29 @@ class GiftSchedulerTest @Autowired constructor(
}
@Test
@DisplayName("완료 시각이 없거나 전달 완료가 아닌 모든 상태는 개인정보를 보존한다")
fun shouldIgnoreNullDeliveredAtAndNonDeliveredGifts() {
val gifts = listOf(saveGiftForErasure(null)) + GiftStatus.values()
.filter { it != GiftStatus.DELIVERED }
@DisplayName("짝인 시각이 없거나 지원하지 않는 상태는 다른 시각이 오래돼도 개인정보를 보존한다")
fun shouldIgnoreNullMatchingTimestampsAndUnsupportedStatuses() {
val supportedStatuses = setOf(GiftStatus.DELIVERED, GiftStatus.UNDELIVERABLE)
val gifts = supportedStatuses.map { status ->
saveGiftForErasure(null, status, "NULL-$status").also { (_, delivery) ->
if (status == GiftStatus.DELIVERED) {
delivery.undeliverableAt = ERASURE_CUTOFF.minusDays(30)
} else {
delivery.deliveredAt = ERASURE_CUTOFF.minusDays(30)
}
}
} + GiftStatus.values()
.filter { it !in supportedStatuses }
.mapIndexed { index, status ->
saveGiftForErasure(ERASURE_CUTOFF.minusDays(30), status, "IGNORE-$index")
saveGiftForErasure(null, status, "IGNORE-$index").also { (_, delivery) ->
delivery.deliveredAt = ERASURE_CUTOFF.minusDays(30)
delivery.undeliverableAt = ERASURE_CUTOFF.minusDays(30)
}
}
val originals = gifts.map { (_, delivery) -> personalData(delivery) }
flushAndClear()
assertEquals(0, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW))
assertEquals(0, scheduler.eraseGiftPersonalData(ERASURE_NOW))
flushAndClear()
gifts.forEachIndexed { index, (gift, _) ->
@@ -672,56 +693,60 @@ class GiftSchedulerTest @Autowired constructor(
}
}
@Test
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("12개 개인정보 중 어느 하나만 남아 있어도 나머지 값을 DB에서 지운다")
fun shouldEraseRemainingFieldsFromPartiallyClearedGift() {
fun shouldEraseRemainingFieldsFromPartiallyClearedGift(status: GiftStatus) {
val gifts = PERSONAL_DATA_FIELDS.mapIndexed { index, remainingField ->
saveGiftForErasure(ERASURE_CUTOFF, applicationNo = "PARTIAL-$index").also { (_, delivery) ->
saveGiftForErasure(ERASURE_CUTOFF, status, "PARTIAL-$index").also { (_, delivery) ->
PERSONAL_DATA_FIELDS.filter { it != remainingField }.forEach { it.set(delivery, null) }
}
}
flushAndClear()
assertEquals(12, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW))
assertEquals(12, scheduler.eraseGiftPersonalData(ERASURE_NOW))
flushAndClear()
gifts.forEach { (gift, _) -> assertEquals(List(12) { null }, personalData(reloadDelivery(gift))) }
}
@Test
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("이미 개인정보가 모두 null인 선물은 첫 실행부터 변경하지 않는다")
fun shouldReturnZeroWhenAllPersonalDataIsAlreadyNull() {
val (gift, delivery) = saveGiftForErasure(ERASURE_CUTOFF)
fun shouldReturnZeroWhenAllPersonalDataIsAlreadyNull(status: GiftStatus) {
val (gift, delivery) = saveGiftForErasure(ERASURE_CUTOFF, status)
PERSONAL_DATA_FIELDS.forEach { it.set(delivery, null) }
flushAndClear()
val updatedAt = reloadDelivery(gift).updatedAt
assertEquals(0, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW))
assertEquals(0, scheduler.eraseGiftPersonalData(ERASURE_NOW))
flushAndClear()
assertEquals(List(12) { null }, personalData(reloadDelivery(gift)))
assertEquals(updatedAt, reloadDelivery(gift).updatedAt)
}
@Test
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("개인정보 정리를 재실행하면 추가 변경 없이 0건을 반환한다")
fun shouldReturnZeroWhenErasureRunsAgain() {
val (gift, _) = saveGiftForErasure(ERASURE_CUTOFF)
fun shouldReturnZeroWhenErasureRunsAgain(status: GiftStatus) {
val (gift, _) = saveGiftForErasure(ERASURE_CUTOFF, status)
flushAndClear()
assertEquals(1, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW))
assertEquals(1, scheduler.eraseGiftPersonalData(ERASURE_NOW))
flushAndClear()
val updatedAt = reloadDelivery(gift).updatedAt
assertEquals(0, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW.plusDays(1)))
assertEquals(0, scheduler.eraseGiftPersonalData(ERASURE_NOW.plusDays(1)))
flushAndClear()
assertEquals(List(12) { null }, personalData(reloadDelivery(gift)))
assertEquals(updatedAt, reloadDelivery(gift).updatedAt)
}
@Test
@ParameterizedTest
@EnumSource(value = GiftStatus::class, names = ["DELIVERED", "UNDELIVERABLE"])
@DisplayName("개인정보 정리는 선물·회원·결제·동의·리뷰와 업무 시각을 DB에 보존하고 환불·푸시하지 않는다")
fun shouldPreserveGiftMemberPaymentConsentReviewAndBusinessTimestamps() {
fun shouldPreserveGiftMemberPaymentConsentReviewAndBusinessTimestamps(status: GiftStatus) {
val sender = entityManager.persist(
Member(password = "test-password", nickname = "sender", profileImage = "sender-profile.png")
.apply { pgChargeCan = 120 }
@@ -733,7 +758,7 @@ class GiftSchedulerTest @Autowired constructor(
UseCan(canUsage = CanUsage.GIFT, can = 60, rewardCan = 20).apply { member = sender }
)
val (gift, delivery) = saveGift(
GiftStatus.DELIVERED,
status,
APPLIED_AT.plusDays(3),
senderMemberId = requireNotNull(sender.id),
recipientMemberId = requireNotNull(recipient.id),
@@ -752,7 +777,7 @@ class GiftSchedulerTest @Autowired constructor(
delivery.inspectionCompletedAt = APPLIED_AT.plusDays(4)
delivery.deliveredAt = ERASURE_CUTOFF
delivery.canceledAt = APPLIED_AT.plusHours(1)
delivery.undeliverableAt = APPLIED_AT.plusHours(2)
delivery.undeliverableAt = if (status == GiftStatus.UNDELIVERABLE) ERASURE_CUTOFF else APPLIED_AT.plusHours(2)
delivery.undeliverableReason = "보존할 업무 사유"
val review = entityManager.persist(
GiftReview(requireNotNull(gift.id), requireNotNull(sender.id), 5, "[\"안전\"]", "감사합니다")
@@ -764,7 +789,7 @@ class GiftSchedulerTest @Autowired constructor(
val originalReview = entityManager.find(GiftReview::class.java, review.id)
flushAndClear()
assertEquals(1, scheduler.eraseDeliveredGiftPersonalData(ERASURE_NOW))
assertEquals(1, scheduler.eraseGiftPersonalData(ERASURE_NOW))
flushAndClear()
val reloadedGift = entityManager.find(Gift::class.java, gift.id)
@@ -849,13 +874,14 @@ class GiftSchedulerTest @Autowired constructor(
private fun personalData(delivery: GiftDelivery): List<String?> = PERSONAL_DATA_FIELDS.map { it.get(delivery) }
private fun saveGiftForErasure(
deliveredAt: LocalDateTime?,
retentionStartedAt: LocalDateTime?,
status: GiftStatus = GiftStatus.DELIVERED,
applicationNo: String = APPLICATION_NO
): Pair<Gift, GiftDelivery> = saveGift(status, APPLIED_AT.plusDays(3), applicationNo = applicationNo)
.also { (_, delivery) ->
fillDeliveryPersonalData(delivery)
delivery.deliveredAt = deliveredAt
delivery.deliveredAt = retentionStartedAt.takeIf { status == GiftStatus.DELIVERED }
delivery.undeliverableAt = retentionStartedAt.takeIf { status == GiftStatus.UNDELIVERABLE }
}
private fun fillDeliveryPersonalData(delivery: GiftDelivery) {
@@ -928,11 +954,11 @@ class GiftSchedulerTest @Autowired constructor(
GiftScheduler::runExpiredRecipientAddressGiftExpiration
),
ScheduledEntryPoint(
"runDeliveredGiftPersonalDataErasure",
"eraseDeliveredGiftPersonalData",
"runGiftPersonalDataErasure",
"eraseGiftPersonalData",
"0 20 * * * *",
"lock:gift-delivered-personal-data-erasure",
GiftScheduler::runDeliveredGiftPersonalDataErasure
GiftScheduler::runGiftPersonalDataErasure
),
ScheduledEntryPoint(
"runDeadlineReminderGifts",