This commit is contained in:
2026-08-21 14:42:40 +08:00
parent 5fd00d3151
commit e534784052
20 changed files with 274 additions and 34 deletions
@@ -17,9 +17,11 @@ class SmartDispatchOpenApiContractTest {
assertTrue(yaml.contains("/api/platform/v1/last-leg/dispatches/candidates:"));
assertTrue(yaml.contains("/api/platform/v1/last-leg/dispatches/pre-arrange:"));
assertTrue(yaml.contains("platform:overseas-warehouse:inbound-order:list"));
assertTrue(yaml.contains("platform:overseas-warehouse:inbound-order:edit"));
assertTrue(yaml.contains("platform:overseas-warehouse:inbound-order:smart-dispatch"));
assertTrue(yaml.contains("SmartDispatchPreArrange"));
assertTrue(yaml.contains("SmartDispatchCandidate"));
assertTrue(yaml.contains("name: planIds"));
assertTrue(yaml.contains("required: true"));
String dispatchContract = yaml.substring(0,
yaml.indexOf("/api/platform/v1/last-leg/overseas-procurements:"));
assertFalse(dispatchContract.contains("name: customerId"));
@@ -31,20 +31,20 @@ class SmartDispatchControllerTest {
}
@Test
void candidatesResolveSingleCustomerScopeWithoutRequestParameter() {
when(service.resolveSingleCustomerScope()).thenReturn("100");
when(service.candidates("100", "LMO-1", "ONT8", "PLAN")).thenReturn(List.of());
void candidatesResolveCustomerScopeFromSelectedPlans() {
when(service.resolveCustomerScopeForPlans(List.of(1L, 2L))).thenReturn("100");
when(service.candidates("100", List.of(1L, 2L), "LMO-1", "ONT8", "PLAN")).thenReturn(List.of());
controller.candidates(platform(), "LMO-1", "ONT8", "PLAN");
controller.candidates(platform(), List.of(1L, 2L), "LMO-1", "ONT8", "PLAN");
verify(service).candidates("100", "LMO-1", "ONT8", "PLAN");
verify(service).candidates("100", List.of(1L, 2L), "LMO-1", "ONT8", "PLAN");
}
@Test
void preArrangeResolvesSingleCustomerAndAuthenticatedOperator() {
DispatchRequests.PreArrange request = new DispatchRequests.PreArrange(
List.of(10L, 11L), "ONT8 -> LAX9", "APT-1", "SUCCESS", "PENDING");
when(service.resolveSingleCustomerScope()).thenReturn("100");
when(service.resolveCustomerScopeForPallets(List.of(10L, 11L))).thenReturn("100");
controller.preArrange(platform(), request);
@@ -52,20 +52,20 @@ class SmartDispatchControllerTest {
}
@Test
void endpointsReuseInboundOrderListAndEditAuthorities() throws Exception {
void endpointsUseInboundOrderListAndDedicatedSmartDispatchAuthorities() throws Exception {
PreAuthorize candidates = SmartDispatchController.class
.getMethod("candidates", AuthenticatedUser.class, String.class, String.class, String.class)
.getMethod("candidates", AuthenticatedUser.class, List.class, String.class, String.class, String.class)
.getAnnotation(PreAuthorize.class);
PreAuthorize preArrange = SmartDispatchController.class
.getMethod("preArrange", AuthenticatedUser.class, DispatchRequests.PreArrange.class)
.getAnnotation(PreAuthorize.class);
assertThat(candidates.value()).contains(OverseasPermissions.INBOUND_ORDER_LIST);
assertThat(preArrange.value()).contains(OverseasPermissions.INBOUND_ORDER_EDIT);
assertThat(preArrange.value()).contains(OverseasPermissions.INBOUND_ORDER_SMART_DISPATCH);
}
private static AuthenticatedUser platform() {
return new AuthenticatedUser(7L, 0L, 0L, 8L, "operator", "PLATFORM", "WEB",
Set.of(OverseasPermissions.INBOUND_ORDER_LIST, OverseasPermissions.INBOUND_ORDER_EDIT));
Set.of(OverseasPermissions.INBOUND_ORDER_LIST, OverseasPermissions.INBOUND_ORDER_SMART_DISPATCH));
}
}
@@ -82,8 +82,28 @@ class DispatchServiceTest {
@Test
void invalidCandidateStageIsRejected() {
assertThrows(ResponseStatusException.class, () -> service.candidates("100", null, null, "INVALID"));
verify(candidates, never()).available(any(), any(), any(), any());
assertThrows(ResponseStatusException.class,
() -> service.candidates("100", List.of(1L), null, null, "INVALID"));
verify(candidates, never()).available(any(), any(), any(), any(), any());
}
@Test
void resolvesCustomerFromSelectedPlansAndPalletsInMultiCustomerDeployment() {
when(candidates.findCustomerScopesByPlanIds(List.of(1L, 2L))).thenReturn(List.of("100"));
when(candidates.findCustomerScopesByPlanPalletIds(List.of(10L, 11L))).thenReturn(List.of("100"));
assertEquals("100", service.resolveCustomerScopeForPlans(List.of(2L, 1L, 1L)));
assertEquals("100", service.resolveCustomerScopeForPallets(List.of(11L, 10L)));
}
@Test
void rejectsSelectedPlansThatSpanCustomers() {
when(candidates.findCustomerScopesByPlanIds(List.of(1L, 2L))).thenReturn(List.of("100", "200"));
ResponseStatusException exception = assertThrows(ResponseStatusException.class,
() -> service.resolveCustomerScopeForPlans(List.of(1L, 2L)));
assertEquals(409, exception.getStatusCode().value());
}
@Test
@@ -99,8 +119,8 @@ class DispatchServiceTest {
@Test
void emptyCustomerScopeProducesEmptyCandidatesAndRejectsPreArrange() {
assertEquals(List.of(), service.candidates(null, null, null, null));
verify(candidates, never()).available(any(), any(), any(), any());
assertEquals(List.of(), service.candidates(null, null, null, null, null));
verify(candidates, never()).available(any(), any(), any(), any(), any());
ResponseStatusException exception = assertThrows(ResponseStatusException.class,
() -> service.preArrange(null, "7",