package com.baiyue.lastleg.financefee; import com.baiyue.lastleg.financefee.config.OverseasFeeResponseJsonConfiguration; import com.baiyue.lastleg.financefee.entity.OverseasFeeSource; import com.baiyue.lastleg.financefee.service.OverseasFeeDeliveryService.RetryRecord; import com.fasterxml.jackson.databind.ObjectMapper; import org.junit.jupiter.api.Test; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import java.time.LocalDateTime; import java.time.OffsetDateTime; import static org.assertj.core.api.Assertions.*; /** 费用与出库时间必须表达同一时刻,业务录入的本地支付时间不能被误转 UTC。 */ class OverseasFeeResponseTimeTest { @Test void feeSystemTimesAndRetryExposeUtcWithoutChangingStoredValues() throws Exception { ObjectMapper json = Jackson2ObjectMapperBuilder.json().modulesToInstall( new OverseasFeeResponseJsonConfiguration().overseasFeeResponseTimeModule()).build(); var utc = LocalDateTime.of(2026, 10, 23, 10, 30); var fee = new OverseasFeeSource(); fee.setCreatedAt(utc); fee.setReviewedAt(utc); fee.setUpdatedAt(utc); fee.setPaidAt(utc); var document = json.readTree(json.writeValueAsString(fee)); for (var field : new String[]{"createdAt", "reviewedAt", "updatedAt"}) { assertThat(document.get(field).asText()).isEqualTo("2026-10-23T10:30:00Z"); assertThat(OffsetDateTime.parse(document.get(field).asText()).toInstant()) .isEqualTo(OffsetDateTime.parse("2026-10-23T18:30:00+08:00").toInstant()); } assertThat(fee.getCreatedAt()).isEqualTo(utc); assertThat(document.get("paidAt").asText()).doesNotEndWith("Z"); var retry = json.readTree(json.writeValueAsString(new RetryRecord("key", utc, "审核员", "重试", "SUCCESS", null))); assertThat(retry.get("requestedAt").asText()).isEqualTo("2026-10-23T10:30:00Z"); fee.setReviewedAt(null); assertThat(json.readTree(json.writeValueAsString(fee)).get("reviewedAt").isNull()).isTrue(); } }