提交
This commit is contained in:
+28
@@ -3,6 +3,7 @@ package com.baiyue.lastleg.controller;
|
||||
import com.baiyue.lastleg.delivery.controller.DeliveryTransferController;
|
||||
import com.baiyue.lastleg.dispatch.controller.DispatchController;
|
||||
import com.baiyue.lastleg.dispatch.controller.DispatchQueryController;
|
||||
import com.baiyue.lastleg.dispatch.controller.SmartDispatchController;
|
||||
import com.baiyue.lastleg.dispatch.pda.controller.DispatchPdaController;
|
||||
import com.baiyue.lastleg.inboundplan.pda.controller.InboundPalletAssignmentController;
|
||||
import com.baiyue.lastleg.inboundplan.pda.controller.InboundPdaController;
|
||||
@@ -11,10 +12,13 @@ import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
@@ -53,6 +57,30 @@ class Phase4BrowserApiBoundaryTest {
|
||||
.contains(annotation.annotationType().getSimpleName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void dispatchQueryIsEnabledByDefaultWithoutEnablingOutboundCommands() throws Exception {
|
||||
String yaml = Files.readString(Path.of("src/main/resources/application.yml"));
|
||||
assertTrue(yaml.contains("enabled: ${LASTLEG_DISPATCH_QUERY_API_ENABLED:true}"));
|
||||
assertTrue(yaml.contains("enabled: ${LASTLEG_SMART_DISPATCH_API_ENABLED:true}"));
|
||||
assertFalse(yaml.contains("future-outbound-api:"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void smartDispatchIsIndependentlyEnabledWithOnlyCandidateAndPreArrangeEndpoints() {
|
||||
ConditionalOnProperty condition = SmartDispatchController.class.getAnnotation(ConditionalOnProperty.class);
|
||||
assertTrue(condition != null);
|
||||
assertTrue(Arrays.asList(condition.name()).contains("lastleg.smart-dispatch-api.enabled"));
|
||||
assertFalse(condition.matchIfMissing());
|
||||
assertTrue(Arrays.stream(SmartDispatchController.class.getDeclaredMethods())
|
||||
.filter(method -> method.isAnnotationPresent(GetMapping.class)).count() == 1);
|
||||
assertTrue(Arrays.stream(SmartDispatchController.class.getDeclaredMethods())
|
||||
.filter(method -> method.isAnnotationPresent(PostMapping.class)).count() == 1);
|
||||
assertFalse(Arrays.stream(SmartDispatchController.class.getDeclaredMethods())
|
||||
.flatMap(method -> Arrays.stream(method.getAnnotations()))
|
||||
.anyMatch(annotation -> Set.of("PutMapping", "DeleteMapping", "PatchMapping")
|
||||
.contains(annotation.annotationType().getSimpleName())));
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformInventoryCommandsDoNotMapOutboundAllocationPickingOrShipping() {
|
||||
Set<String> paths = Arrays.stream(InventoryCommandController.class.getDeclaredMethods())
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.baiyue.lastleg.dispatch;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class SmartDispatchOpenApiContractTest {
|
||||
@Test
|
||||
void contractDocumentsOnlyCandidateAndPreArrangeSmartDispatchWrites() throws Exception {
|
||||
String yaml;
|
||||
try (var input = getClass().getResourceAsStream("/openapi/overseas-business-v1.yaml")) {
|
||||
yaml = new String(input.readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
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("SmartDispatchPreArrange"));
|
||||
assertTrue(yaml.contains("SmartDispatchCandidate"));
|
||||
String dispatchContract = yaml.substring(0,
|
||||
yaml.indexOf("/api/platform/v1/last-leg/overseas-procurements:"));
|
||||
assertFalse(dispatchContract.contains("name: customerId"));
|
||||
assertFalse(yaml.contains("/api/platform/v1/last-leg/dispatches/{dispatchNo}/depart:"));
|
||||
}
|
||||
}
|
||||
+19
-3
@@ -4,12 +4,14 @@ import com.baiyue.common.core.api.PageResult;
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.lastleg.dispatch.dto.DispatchRequests;
|
||||
import com.baiyue.lastleg.dispatch.service.DispatchService;
|
||||
import com.baiyue.lastleg.security.OverseasPermissions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import java.util.List;
|
||||
@@ -32,13 +34,14 @@ class DispatchQueryControllerTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformPageQueriesAllCustomersWithoutCustomerId() {
|
||||
void platformPageUsesServerResolvedSingleCustomerWithoutCustomerId() {
|
||||
DispatchRequests.Query query = new DispatchRequests.Query(1, 20, null, null, null, null);
|
||||
when(service.page(null, query)).thenReturn(new PageResult<>(List.of(), 1, 20, 0, 0));
|
||||
when(service.resolveSingleCustomerScope()).thenReturn("100");
|
||||
when(service.page("100", query)).thenReturn(new PageResult<>(List.of(), 1, 20, 0, 0));
|
||||
|
||||
var response = controller.page(platform(), query);
|
||||
|
||||
verify(service).page(null, query);
|
||||
verify(service).page("100", query);
|
||||
assertThat(response.code()).isEqualTo("200");
|
||||
assertThat(response.data().records()).isEmpty();
|
||||
assertThatThrownBy(() -> controller.page(null, query))
|
||||
@@ -47,6 +50,19 @@ class DispatchQueryControllerTest {
|
||||
((ResponseStatusException) error).getStatusCode().value()).isEqualTo(401));
|
||||
}
|
||||
|
||||
@Test
|
||||
void listAndDetailReuseInboundOrderListAuthority() throws Exception {
|
||||
PreAuthorize page = DispatchQueryController.class
|
||||
.getMethod("page", AuthenticatedUser.class, DispatchRequests.Query.class)
|
||||
.getAnnotation(PreAuthorize.class);
|
||||
PreAuthorize detail = DispatchQueryController.class
|
||||
.getMethod("detail", AuthenticatedUser.class, String.class)
|
||||
.getAnnotation(PreAuthorize.class);
|
||||
|
||||
assertThat(page.value()).contains(OverseasPermissions.INBOUND_ORDER_LIST);
|
||||
assertThat(detail.value()).contains(OverseasPermissions.INBOUND_ORDER_LIST);
|
||||
}
|
||||
|
||||
private static AuthenticatedUser platform() {
|
||||
return new AuthenticatedUser(7L, 0L, 0L, 8L, "operator", "PLATFORM", "WEB", Set.of());
|
||||
}
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
package com.baiyue.lastleg.dispatch.controller;
|
||||
|
||||
import com.baiyue.common.security.AuthenticatedUser;
|
||||
import com.baiyue.lastleg.dispatch.dto.DispatchRequests;
|
||||
import com.baiyue.lastleg.dispatch.service.DispatchService;
|
||||
import com.baiyue.lastleg.security.OverseasPermissions;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class SmartDispatchControllerTest {
|
||||
@Mock DispatchService service;
|
||||
private SmartDispatchController controller;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
controller = new SmartDispatchController();
|
||||
ReflectionTestUtils.setField(controller, "service", service);
|
||||
}
|
||||
|
||||
@Test
|
||||
void candidatesResolveSingleCustomerScopeWithoutRequestParameter() {
|
||||
when(service.resolveSingleCustomerScope()).thenReturn("100");
|
||||
when(service.candidates("100", "LMO-1", "ONT8", "PLAN")).thenReturn(List.of());
|
||||
|
||||
controller.candidates(platform(), "LMO-1", "ONT8", "PLAN");
|
||||
|
||||
verify(service).candidates("100", "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");
|
||||
|
||||
controller.preArrange(platform(), request);
|
||||
|
||||
verify(service).preArrange("100", "7", request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void endpointsReuseInboundOrderListAndEditAuthorities() throws Exception {
|
||||
PreAuthorize candidates = SmartDispatchController.class
|
||||
.getMethod("candidates", AuthenticatedUser.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);
|
||||
}
|
||||
|
||||
private static AuthenticatedUser platform() {
|
||||
return new AuthenticatedUser(7L, 0L, 0L, 8L, "operator", "PLATFORM", "WEB",
|
||||
Set.of(OverseasPermissions.INBOUND_ORDER_LIST, OverseasPermissions.INBOUND_ORDER_EDIT));
|
||||
}
|
||||
}
|
||||
+25
-3
@@ -86,6 +86,28 @@ class DispatchServiceTest {
|
||||
verify(candidates, never()).available(any(), any(), any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolvesOnlyCustomerScopeAndRejectsMultipleCustomers() {
|
||||
when(candidates.findCustomerScopes()).thenReturn(List.of("100"));
|
||||
assertEquals("100", service.resolveSingleCustomerScope());
|
||||
|
||||
when(candidates.findCustomerScopes()).thenReturn(List.of("100", "200"));
|
||||
ResponseStatusException exception = assertThrows(ResponseStatusException.class,
|
||||
() -> service.resolveSingleCustomerScope());
|
||||
assertEquals(409, exception.getStatusCode().value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void emptyCustomerScopeProducesEmptyCandidatesAndRejectsPreArrange() {
|
||||
assertEquals(List.of(), service.candidates(null, null, null, null));
|
||||
verify(candidates, never()).available(any(), any(), any(), any());
|
||||
|
||||
ResponseStatusException exception = assertThrows(ResponseStatusException.class,
|
||||
() -> service.preArrange(null, "7",
|
||||
new DispatchRequests.PreArrange(List.of(10L), null, null, null, null)));
|
||||
assertEquals(409, exception.getStatusCode().value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void editCannotBypassPdaManagedDispatchStatus() {
|
||||
DispatchOrder dispatch = new DispatchOrder();
|
||||
@@ -105,14 +127,14 @@ class DispatchServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformDetailFindsDispatchGloballyAndLoadsItemsWithRecordCustomer() {
|
||||
void detailUsesResolvedCustomerScopeAndLoadsItems() {
|
||||
DispatchOrder dispatch = new DispatchOrder();
|
||||
dispatch.setId(1L);
|
||||
dispatch.setCustomerId("200");
|
||||
dispatch.setDispatchNo("PC1");
|
||||
when(orders.findAnyByDispatchNo("PC1")).thenReturn(dispatch);
|
||||
when(orders.findByDispatchNo("200", "PC1")).thenReturn(dispatch);
|
||||
|
||||
service.detail(null, "PC1");
|
||||
service.detail("200", "PC1");
|
||||
|
||||
verify(items).findByDispatchOrder("200", 1L);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user