package com.baiyue.integration.service; import com.baiyue.integration.dto.CarrierScheduleDtos.Observation; import com.baiyue.integration.dto.CarrierScheduleDtos.QueryRequest; import com.baiyue.integration.dto.CarrierScheduleDtos.QueryResult; import com.baiyue.integration.dto.CarrierScheduleDtos.ExceptionObservation; import com.baiyue.integration.provider.CarrierScheduleProviderAdapter; import com.baiyue.integration.provider.CompliantCarrierScheduleProviderAdapter; import org.junit.jupiter.api.Test; import java.time.LocalDateTime; import java.util.List; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; class CarrierScheduleProviderServiceTest { @Test void fallbackNeverPretendsThatWebsiteScrapingSucceeded() { var service = new CarrierScheduleProviderService(List.of(new CompliantCarrierScheduleProviderAdapter())); QueryResult result = service.query(new QueryRequest("COSCO", "CONTAINER_NO", "ZCSU7881970")); assertThat(result.outcome()).isEqualTo("MANUAL_REQUIRED"); assertThat(result.errorCode()).isEqualTo("PROVIDER_API_NOT_CONFIGURED"); assertThat(result.observations()).isEmpty(); assertThat(result.exceptions()).isEmpty(); } @Test void onlyDispatchesNormalizedContainerNumberTracking() { CarrierScheduleProviderAdapter capturing = new CarrierScheduleProviderAdapter() { @Override public boolean supports(String carrierCode) { return true; } @Override public QueryResult query(QueryRequest request) { assertThat(request.trackingType()).isEqualTo("CONTAINER_NO"); assertThat(request.trackingNo()).isEqualTo("ZCSU7881970"); return new QueryResult("TEST", "NO_CHANGE", List.of(), List.of(), null, null, LocalDateTime.now()); } }; var service = new CarrierScheduleProviderService(List.of(capturing)); service.query(new QueryRequest("ZIM", "CONTAINER_NO", "ZCSU7881970")); assertThatThrownBy(() -> service.query(new QueryRequest("ZIM", "CONTAINER_NO", "zcsu7881970"))) .hasMessageContaining("规范化真实集装箱号"); assertThatThrownBy(() -> service.query(new QueryRequest("ZIM", "CONTAINER_NO", "ZCSU7881971"))) .hasMessageContaining("规范化真实集装箱号"); assertThatThrownBy(() -> service.query(new QueryRequest("ZIM", "BILL_OF_LADING", "BL-1"))) .hasMessageContaining("CONTAINER_NO"); } @Test void rejectsProviderSpecificNodesThatWereNotNormalized() { CarrierScheduleProviderAdapter invalid = new CarrierScheduleProviderAdapter() { @Override public boolean supports(String carrierCode) { return true; } @Override public QueryResult query(QueryRequest request) { return new QueryResult("TEST", "SUCCESS", List.of(new Observation("evt", "RAW", "UNKNOWN", LocalDateTime.now(), null, null, null, null, null, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")), List.of(), null, null, LocalDateTime.now()); } }; var service = new CarrierScheduleProviderService(List.of(invalid)); assertThatThrownBy(() -> service.query(new QueryRequest("COSCO", "CONTAINER_NO", "ZCSU7881970"))) .hasMessageContaining("无效标准节点"); } @Test void rejectsProviderHoldsOutsideTheFourFrozenCodes() { CarrierScheduleProviderAdapter invalid = new CarrierScheduleProviderAdapter() { @Override public boolean supports(String carrierCode) { return true; } @Override public QueryResult query(QueryRequest request) { return new QueryResult("TEST", "SUCCESS", List.of(), List.of(new ExceptionObservation( "hold-1", "RAW HOLD", "OTHER_HOLD", true, LocalDateTime.now(), null, null, null, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")), null, null, LocalDateTime.now()); } }; var service = new CarrierScheduleProviderService(List.of(invalid)); assertThatThrownBy(() -> service.query(new QueryRequest("COSCO", "CONTAINER_NO", "ZCSU7881970"))) .hasMessageContaining("无效异常事实"); } }