暂存提交
This commit is contained in:
+97
@@ -0,0 +1,97 @@
|
||||
package com.baiyue.eventbridge.service;
|
||||
|
||||
import com.baiyue.common.event.EventEnvelope;
|
||||
import com.baiyue.common.event.EventPayloadCanonicalizer;
|
||||
import com.baiyue.common.event.EventPayloadHash;
|
||||
import com.baiyue.common.event.RegionCode;
|
||||
import com.baiyue.eventbridge.domain.BridgeInbox;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.dao.DuplicateKeyException;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doThrow;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
class EventInboxServiceTest {
|
||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
||||
private final InboxStore store = mock(InboxStore.class);
|
||||
private final EventInboxService service = new EventInboxService(store, objectMapper, "OVERSEAS");
|
||||
|
||||
@Test
|
||||
void 首次事件落库并返回已接收() {
|
||||
EventEnvelope envelope = envelope("sha256:placeholder");
|
||||
envelope = withHash(envelope);
|
||||
|
||||
assertThat(service.receive(envelope).result()).isEqualTo("已接收");
|
||||
verify(store).insert(any(BridgeInbox.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void 相同事件和摘要重复接收不再次写入() {
|
||||
EventEnvelope envelope = withHash(envelope("sha256:placeholder"));
|
||||
BridgeInbox existing = existing(envelope.payloadHash());
|
||||
when(store.findByEventId(envelope.eventId())).thenReturn(existing);
|
||||
|
||||
assertThat(service.receive(envelope).result()).isEqualTo("重复");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 相同事件但摘要不同时拒绝覆盖() {
|
||||
EventEnvelope envelope = withHash(envelope("sha256:placeholder"));
|
||||
when(store.findByEventId(envelope.eventId())).thenReturn(existing("sha256:" + "0".repeat(64)));
|
||||
|
||||
assertThatThrownBy(() -> service.receive(envelope))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("拒绝覆盖");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 并发插入冲突后按既有记录判定为重复() {
|
||||
EventEnvelope envelope = withHash(envelope("sha256:placeholder"));
|
||||
when(store.findByEventId(envelope.eventId())).thenReturn(null, existing(envelope.payloadHash()));
|
||||
doThrow(new DuplicateKeyException("并发重复")).when(store).insert(any());
|
||||
|
||||
assertThat(service.receive(envelope).result()).isEqualTo("重复");
|
||||
}
|
||||
|
||||
@Test
|
||||
void 目标区域与当前部署区域不一致时拒绝接收() {
|
||||
EventInboxService cnService = new EventInboxService(store, objectMapper, "CN");
|
||||
EventEnvelope envelope = withHash(envelope("sha256:placeholder"));
|
||||
|
||||
assertThatThrownBy(() -> cnService.receive(envelope))
|
||||
.isInstanceOf(IllegalArgumentException.class)
|
||||
.hasMessageContaining("目标区域");
|
||||
}
|
||||
|
||||
private EventEnvelope envelope(String hash) {
|
||||
return new EventEnvelope("550e8400-e29b-41d4-a716-446655440000", "OrderApproved", 1,
|
||||
Instant.parse("2026-07-29T08:30:00Z"), RegionCode.CN, RegionCode.OVERSEAS,
|
||||
"20001", "ORDER", "90001", 1, null, "trace-1", "flow-1", null,
|
||||
objectMapper.createObjectNode().put("orderId", "90001"), hash);
|
||||
}
|
||||
|
||||
private EventEnvelope withHash(EventEnvelope source) {
|
||||
String hash = EventPayloadHash.sha256(EventPayloadCanonicalizer.canonicalize(source.payload()));
|
||||
return new EventEnvelope(source.eventId(), source.eventType(), source.eventVersion(), source.occurredAt(),
|
||||
source.sourceRegion(), source.targetRegion(), source.tenantId(), source.aggregateType(),
|
||||
source.aggregateId(), source.aggregateVersion(), source.handoverVersion(), source.traceId(),
|
||||
source.correlationId(), source.causationId(), source.payload(), hash);
|
||||
}
|
||||
|
||||
private BridgeInbox existing(String hash) {
|
||||
BridgeInbox inbox = new BridgeInbox();
|
||||
inbox.setEventId("550e8400-e29b-41d4-a716-446655440000");
|
||||
inbox.setPayloadHash(hash);
|
||||
inbox.setReceivedAt(LocalDateTime.of(2026, 7, 29, 18, 0));
|
||||
return inbox;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user