暂存提交

This commit is contained in:
2026-07-30 18:01:36 +08:00
commit 2f4e159356
368 changed files with 20370 additions and 0 deletions
@@ -0,0 +1,104 @@
package com.baiyue.common.event;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.jupiter.api.Test;
import java.nio.charset.StandardCharsets;
import java.time.Instant;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
class EventEnvelopeTest {
private final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());
@Test
void 标准Uuid事件可以通过校验并完成序列化往返() throws Exception {
EventEnvelope source = validEnvelope(EventIdentifiers.newUuid());
source.requireValid();
String json = objectMapper.writeValueAsString(source);
EventEnvelope restored = objectMapper.readValue(json, EventEnvelope.class);
assertThat(restored).isEqualTo(source);
assertThat(objectMapper.readTree(json).path("eventType").asText())
.isEqualTo(EventTypes.FIRST_LEG_SHIPMENT_DEPARTED);
}
@Test
void 合法Ulid可以作为事件标识() {
EventEnvelope envelope = validEnvelope("01J8Z4QX9K7M2N3P4R5S6T7V8W");
assertThat(EventEnvelopeValidator.validate(envelope)).isEmpty();
}
@Test
void 校验器一次返回全部基础错误() {
EventEnvelope envelope = new EventEnvelope(
"bad-id", "bad_type", 0, null, null, null, " ", "bad-type", " ",
-1, 0L, " ", " ", "bad-cause", null, "bad-hash");
List<String> errors = EventEnvelopeValidator.validate(envelope);
assertThat(errors).hasSizeGreaterThanOrEqualTo(10);
assertThatThrownBy(envelope::requireValid)
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("eventId")
.hasMessageContaining("payloadHash");
}
@Test
void 负载摘要可计算并校验() {
byte[] payload = "{\"orderId\":\"90001\"}".getBytes(StandardCharsets.UTF_8);
String hash = EventPayloadHash.sha256(payload);
assertThat(hash).matches("sha256:[0-9a-f]{64}");
assertThat(EventPayloadHash.matches(payload, hash)).isTrue();
assertThat(EventPayloadHash.matches("{}".getBytes(StandardCharsets.UTF_8), hash)).isFalse();
}
@Test
void 对象字段顺序不同仍产生相同规范摘要() throws Exception {
JsonNode first = objectMapper.readTree("{\"orderId\":\"90001\",\"route\":{\"country\":\"US\",\"city\":\"LA\"}}");
JsonNode second = objectMapper.readTree("{\"route\":{\"city\":\"LA\",\"country\":\"US\"},\"orderId\":\"90001\"}");
assertThat(EventPayloadHash.sha256(EventPayloadCanonicalizer.canonicalize(first)))
.isEqualTo(EventPayloadHash.sha256(EventPayloadCanonicalizer.canonicalize(second)));
}
@Test
void 数组顺序仍作为业务语义保留() throws Exception {
JsonNode first = objectMapper.readTree("{\"steps\":[\"A\",\"B\"]}");
JsonNode second = objectMapper.readTree("{\"steps\":[\"B\",\"A\"]}");
assertThat(EventPayloadHash.sha256(EventPayloadCanonicalizer.canonicalize(first)))
.isNotEqualTo(EventPayloadHash.sha256(EventPayloadCanonicalizer.canonicalize(second)));
}
private EventEnvelope validEnvelope(String eventId) {
JsonNode payload = objectMapper.createObjectNode()
.put("containerNo", "MSCU1234567")
.put("orderId", "90001");
byte[] canonicalPayload = payload.toString().getBytes(StandardCharsets.UTF_8);
return new EventEnvelope(
eventId,
EventTypes.FIRST_LEG_SHIPMENT_DEPARTED,
1,
Instant.parse("2026-07-29T08:30:00Z"),
RegionCode.CN,
RegionCode.OVERSEAS,
"20001",
"FIRST_LEG_SHIPMENT",
"90001",
7,
1L,
"trace-90001",
"handover-90001",
null,
payload,
EventPayloadHash.sha256(canonicalPayload));
}
}