110 lines
5.9 KiB
Java
110 lines
5.9 KiB
Java
package com.baiyue.lastleg.pda;
|
|||
|
|
|
||
|
|
import com.baiyue.common.security.AuthenticatedUser;
|
||
|
|
import com.baiyue.lastleg.delivery.controller.OutboundPdaController;
|
||
|
|
import com.baiyue.lastleg.delivery.dto.DeliveryRequests;
|
||
|
|
import com.baiyue.lastleg.delivery.dto.DeliveryResponses;
|
||
|
|
import com.baiyue.lastleg.delivery.service.DeliveryTransferService;
|
||
|
|
import com.baiyue.lastleg.dispatch.pda.controller.DispatchPdaController;
|
||
|
|
import com.baiyue.lastleg.dispatch.pda.dto.DispatchPdaRequests;
|
||
|
|
import com.baiyue.lastleg.dispatch.pda.service.DispatchPdaWorkflowService;
|
||
|
|
import org.junit.jupiter.api.Test;
|
||
|
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||
|
|
import org.springframework.test.util.ReflectionTestUtils;
|
||
|
|
import org.springframework.web.bind.annotation.RequestParam;
|
||
|
|
import org.springframework.web.server.ResponseStatusException;
|
||
|
|
|
||
|
|
import java.lang.reflect.Method;
|
||
|
|
import java.nio.charset.StandardCharsets;
|
||
|
|
import java.nio.file.Files;
|
||
|
|
import java.nio.file.Path;
|
||
|
|
import java.util.Arrays;
|
||
|
|
import java.util.Set;
|
||
|
|
|
||
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||
|
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||
|
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||
|
|
import static org.mockito.Mockito.mock;
|
||
|
|
import static org.mockito.Mockito.verify;
|
||
|
|
|
||
|
|
class PdaOutboundDispatchContractTest {
|
||
|
|
private static final String SECURITY =
|
||
|
|
"hasAuthority('lastleg:pda:operate') and hasAuthority('ROLE_OVERSEAS_WAREHOUSE_PDA_OPERATOR')";
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void controllersRequirePdaRoleAndNeverAcceptCustomerOrWarehouseScope() {
|
||
|
|
assertEquals(SECURITY, DispatchPdaController.class.getAnnotation(PreAuthorize.class).value());
|
||
|
|
assertEquals(SECURITY, OutboundPdaController.class.getAnnotation(PreAuthorize.class).value());
|
||
|
|
for (Class<?> controller : Set.of(DispatchPdaController.class, OutboundPdaController.class)) {
|
||
|
|
for (Method method : controller.getDeclaredMethods()) {
|
||
|
|
assertTrue(Arrays.stream(method.getParameters()).noneMatch(parameter -> {
|
||
|
|
RequestParam query = parameter.getAnnotation(RequestParam.class);
|
||
|
|
return query != null && Set.of("customerId", "warehouseId")
|
||
|
|
.contains(query.name().isBlank() ? query.value() : query.name());
|
||
|
|
}));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
assertTrue(Arrays.stream(DispatchPdaRequests.Pick.class.getRecordComponents())
|
||
|
|
.noneMatch(component -> "warehouseId".equals(component.getName()) || "customerId".equals(component.getName())));
|
||
|
|
assertTrue(Arrays.stream(DeliveryRequests.PdaPick.class.getRecordComponents())
|
||
|
|
.noneMatch(component -> "warehouseId".equals(component.getName()) || "customerId".equals(component.getName())));
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void controllersPassOnlyTokenBoundWarehouseToServices() {
|
||
|
|
DispatchPdaWorkflowService dispatchService = mock(DispatchPdaWorkflowService.class);
|
||
|
|
DeliveryTransferService outboundService = mock(DeliveryTransferService.class);
|
||
|
|
DispatchPdaController dispatch = new DispatchPdaController();
|
||
|
|
OutboundPdaController outbound = new OutboundPdaController();
|
||
|
|
ReflectionTestUtils.setField(dispatch, "service", dispatchService);
|
||
|
|
ReflectionTestUtils.setField(outbound, "service", outboundService);
|
||
|
|
AuthenticatedUser user = pda(Set.of("lastleg:pda:operate", "ROLE_OVERSEAS_WAREHOUSE_PDA_OPERATOR"), 900L);
|
||
|
|
|
||
|
|
dispatch.list(user, null);
|
||
|
|
outbound.list(user, null);
|
||
|
|
|
||
|
|
verify(dispatchService).list("900", null);
|
||
|
|
verify(outboundService).pdaTasks("900", null);
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void missingRolePermissionOrWarehouseBindingIsRejected() {
|
||
|
|
DispatchPdaController controller = new DispatchPdaController();
|
||
|
|
assertThrows(ResponseStatusException.class,
|
||
|
|
() -> controller.list(pda(Set.of("lastleg:pda:operate"), 900L), null));
|
||
|
|
assertThrows(ResponseStatusException.class,
|
||
|
|
() -> controller.list(pda(Set.of("ROLE_OVERSEAS_WAREHOUSE_PDA_OPERATOR"), 900L), null));
|
||
|
|
assertThrows(ResponseStatusException.class,
|
||
|
|
() -> controller.list(pda(Set.of("lastleg:pda:operate", "ROLE_OVERSEAS_WAREHOUSE_PDA_OPERATOR"), null), null));
|
||
|
|
}
|
||
|
|
|
||
|
|
@Test
|
||
|
|
void pdaOpenApiContainsOnlyFrozenDispatchAndOutboundWorkflow() throws Exception {
|
||
|
|
String yaml = Files.readString(Path.of("src/main/resources/openapi/overseas-pda-operations-v1.yaml"),
|
||
|
|
StandardCharsets.UTF_8);
|
||
|
|
assertTrue(yaml.contains("/api/pda/v1/last-leg/dispatches:"));
|
||
|
|
assertTrue(yaml.contains("/api/pda/v1/last-leg/dispatches/{dispatchNo}/depart:"));
|
||
|
|
assertTrue(yaml.contains("/api/pda/v1/last-leg/outbound-tasks/{taskNo}/complete:"));
|
||
|
|
assertFalse(yaml.contains("name: customerId"));
|
||
|
|
assertFalse(yaml.contains("name: warehouseId"));
|
||
|
|
assertFalse(yaml.contains("/api/pda/v1/last-leg/delivery"));
|
||
|
|
assertTrue(yaml.contains("inventoryPositionId:"));
|
||
|
|
assertTrue(yaml.contains("cartonMark:"));
|
||
|
|
assertTrue(yaml.contains("availablePackages:"));
|
||
|
|
assertTrue(yaml.contains("pickedPackages:"));
|
||
|
|
assertEquals(Set.of("inventoryPositionId", "palletNo", "cartonMark", "skuCode", "inboundCode",
|
||
|
|
"availablePackages", "pickedPackages"),
|
||
|
|
Arrays.stream(DeliveryResponses.PdaPickPosition.class.getRecordComponents())
|
||
|
|
.map(component -> component.getName()).collect(java.util.stream.Collectors.toSet()));
|
||
|
|
assertEquals(Set.of("idempotencyKey"),
|
||
|
|
Arrays.stream(DeliveryRequests.PdaComplete.class.getRecordComponents())
|
||
|
|
.map(component -> component.getName()).collect(java.util.stream.Collectors.toSet()));
|
||
|
|
}
|
||
|
|
|
||
|
|
private static AuthenticatedUser pda(Set<String> permissions, Long warehouseId) {
|
||
|
|
return new AuthenticatedUser(7L, 0L, 0L, 8L, "picker", "PLATFORM", "PDA", permissions,
|
||
|
|
false, null, null, false, warehouseId);
|
||
|
|
}
|
||
|
|
}
|