Files
baiyue-firstleg/integration-service/src/test/java/com/baiyue/integration/provider/HedeCarrierScheduleProviderAdapterTest.java
T

106 lines
5.5 KiB
Java

package com.baiyue.integration.provider;
import com.baiyue.integration.dto.CarrierScheduleDtos.QueryRequest;
import com.baiyue.integration.provider.HedeTrackingClient.TrackingResponse;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class HedeCarrierScheduleProviderAdapterTest {
@Test
void appendedLoadingAndChangedEtaPreserveGateEventProjection() throws Exception {
String raw = row("FFAU4879673", "2026-08-05 04:24", "2026-08-22 00:00", "2026-07-30 21:31", "2026-08-01 15:55", "", "", "", "");
String next = row("FFAU4879673", "2026-08-05 04:24", "2026-08-23 00:00", "2026-07-30 21:31", "2026-08-01 15:55", "2026-08-04 19:45", "", "", "");
var adapter = new HedeCarrierScheduleProviderAdapter(mock(HedeTrackingClient.class));
var before = adapter.observations("FFAU4879673", raw);
var after = adapter.observations("FFAU4879673", next);
CarrierResponseAuditAssertions.stableSharedFacts(before, after, raw, next);
assertThat(after).hasSize(before.size() + 1);
}
@Test
void parsesConfirmedMainTableColumnsAndDoesNotTurnEtaIntoAnActualNode() throws Exception {
String html = row("XYLU8251457", "2026-08-20 00:00", "2026-09-09 00:00",
"", "", "", "", "", "");
var rows = HedeCarrierScheduleProviderAdapter.rows(html);
HedeTrackingClient client = mock(HedeTrackingClient.class);
HedeCarrierScheduleProviderAdapter adapter = new HedeCarrierScheduleProviderAdapter(client);
assertThat(rows).singleElement().satisfies(value -> {
assertThat(value.containerNo()).isEqualTo("XYLU8251457");
assertThat(value.vessel()).isEqualTo("POSEN");
assertThat(value.voyage()).isEqualTo("2607W");
assertThat(value.estimatedDeparture()).isEqualTo("2026-08-20 00:00");
assertThat(value.estimatedArrival()).isEqualTo("2026-09-09 00:00");
});
assertThat(adapter.observations("XYLU8251457", html)).extracting(value -> value.standardNode())
.containsExactlyInAnyOrder("DEPARTED_ORIGIN_PORT", "ARRIVED_DESTINATION_PORT");
assertThat(adapter.observations("XYLU8251457", html)).allSatisfy(value -> {
assertThat(value.estimatedAt()).isNotNull();
assertThat(value.actualAt()).isNull();
});
}
@Test
void mapsOnlyActualHedeMilestonesForTheRequestedContainer() {
String html = row("FFAU4879673", "2026-08-05 04:24", "2026-08-22 00:00",
"2026-07-30 21:31", "2026-08-01 15:55", "2026-08-04 19:45", "", "", "");
HedeTrackingClient client = mock(HedeTrackingClient.class);
when(client.configured()).thenReturn(true);
when(client.query(new QueryRequest("HEDE", "CONTAINER_NO", "FFAU4879673")))
.thenReturn(new TrackingResponse(html));
HedeCarrierScheduleProviderAdapter adapter = new HedeCarrierScheduleProviderAdapter(client);
var result = adapter.query(new QueryRequest("HEDE", "CONTAINER_NO", "FFAU4879673"));
assertThat(result.outcome()).isEqualTo("SUCCESS");
assertThat(result.observations()).extracting(value -> value.standardNode())
.containsExactlyInAnyOrder("DEPARTED_ORIGIN_PORT", "ARRIVED_DESTINATION_PORT", "AT_ORIGIN_PORT",
"LOADED_ON_VESSEL");
assertThat(result.observations()).allSatisfy(value -> {
assertThat(value.providerEventId()).hasSize(64);
assertThat(value.rawPayloadHash()).hasSize(64);
assertThat(value.sourceReference()).contains("FFAU4879673").contains("POSEN/2607W");
});
assertThat(result.observations()).extracting(value -> value.observedAt())
.containsOnly(result.observations().get(0).observedAt());
}
@Test
void actualEmptyReturnIsMappedPrecisely() throws Exception {
String html = row("FFAU4879673", "2026-08-05 04:24", "2026-08-22 00:00",
"2026-07-30 21:31", "2026-08-01 15:55", "2026-08-04 19:45", "", "",
"2026-08-28 08:00");
HedeTrackingClient client = mock(HedeTrackingClient.class);
var result = new HedeCarrierScheduleProviderAdapter(client).observations("FFAU4879673", html);
assertThat(result).filteredOn(value -> "EMPTY_RETURNED".equals(value.standardNode()))
.singleElement().satisfies(value -> {
assertThat(value.actualAt()).isNotNull();
assertThat(value.estimatedAt()).isNull();
});
}
@Test
void refusesAmbiguousBillLevelAutomation() {
HedeTrackingClient client = mock(HedeTrackingClient.class);
HedeCarrierScheduleProviderAdapter adapter = new HedeCarrierScheduleProviderAdapter(client);
var result = adapter.query(new QueryRequest("HEDE", "BILL_OF_LADING", "HDE123"));
assertThat(result.outcome()).isEqualTo("PERMANENT_FAILURE");
assertThat(result.errorCode()).isEqualTo("HEDE_CONTAINER_REQUIRED");
}
private static String row(String container, String etd, String eta, String emptyOut, String fullIn,
String loaded, String discharged, String fullOut, String emptyReturned) {
return "<table><tbody><tr class=\"read-tr\">"
+ td("***") + td(container) + td("POSEN") + td("2607W") + td(etd) + td(eta)
+ td(emptyOut) + td(fullIn) + td(loaded) + td(discharged) + td(fullOut) + td(emptyReturned)
+ td("查看") + "</tr></tbody></table>";
}
private static String td(String value) { return "<td>" + value + "</td>"; }
}