119 lines
6.5 KiB
Java
119 lines
6.5 KiB
Java
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.ReceivingContainerController;
|
|
import com.baiyue.lastleg.inventory.command.controller.InventoryCommandController;
|
|
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 org.springframework.web.bind.annotation.DeleteMapping;
|
|
|
|
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;
|
|
|
|
class Phase4BrowserApiBoundaryTest {
|
|
@Test
|
|
void onlyStableContainerReceivingUsesThePdaInboundAccessDomain() throws Exception {
|
|
assertTrue(basePath(ReceivingContainerController.class).startsWith("/api/pda/v1/"));
|
|
assertFalse(basePath(ReceivingContainerController.class).contains("/api/platform/"));
|
|
Path controllers = Path.of("src/main/java/com/baiyue/lastleg/inboundplan/pda/controller");
|
|
String source = Files.walk(controllers).filter(path -> path.toString().endsWith(".java"))
|
|
.map(path -> {
|
|
try { return Files.readString(path); }
|
|
catch (Exception exception) { throw new IllegalStateException(exception); }
|
|
}).collect(Collectors.joining("\n"));
|
|
assertFalse(source.contains("/api/pda/v1/last-leg/inbound-plans/{planNo}"));
|
|
assertFalse(source.contains("@RequestParam(required = false) String customerId"));
|
|
}
|
|
|
|
@Test
|
|
void excludedOutboundControllersAreDisabledUnlessExplicitlyEnabledLater() {
|
|
for (Class<?> type : new Class<?>[] {
|
|
DispatchController.class, DeliveryTransferController.class, DispatchPdaController.class
|
|
}) {
|
|
ConditionalOnProperty condition = type.getAnnotation(ConditionalOnProperty.class);
|
|
assertTrue(condition != null, type.getSimpleName());
|
|
assertTrue(Arrays.asList(condition.name()).contains("lastleg.future-outbound-api.enabled"));
|
|
assertFalse(condition.matchIfMissing());
|
|
}
|
|
}
|
|
|
|
@Test
|
|
void dispatchQueryIsIndependentlyEnabledWithoutExposingOutboundCommands() {
|
|
ConditionalOnProperty condition = DispatchQueryController.class.getAnnotation(ConditionalOnProperty.class);
|
|
assertTrue(condition != null);
|
|
assertTrue(Arrays.asList(condition.name()).contains("lastleg.dispatch-query-api.enabled"));
|
|
assertFalse(condition.matchIfMissing());
|
|
assertTrue(Arrays.stream(DispatchQueryController.class.getDeclaredMethods())
|
|
.filter(method -> method.isAnnotationPresent(GetMapping.class)).count() == 2);
|
|
assertFalse(Arrays.stream(DispatchQueryController.class.getDeclaredMethods())
|
|
.flatMap(method -> Arrays.stream(method.getAnnotations()))
|
|
.anyMatch(annotation -> Set.of("PostMapping", "PutMapping", "DeleteMapping")
|
|
.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 smartDispatchOnlyExposesCandidatePreArrangeAndDraftLifecycleEndpoints() {
|
|
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() == 2);
|
|
assertTrue(Arrays.stream(SmartDispatchController.class.getDeclaredMethods())
|
|
.filter(method -> method.isAnnotationPresent(PostMapping.class)).count() == 6);
|
|
assertTrue(Arrays.stream(SmartDispatchController.class.getDeclaredMethods())
|
|
.filter(method -> method.isAnnotationPresent(DeleteMapping.class)).count() == 1);
|
|
assertTrue(Arrays.stream(SmartDispatchController.class.getDeclaredMethods())
|
|
.filter(method -> method.isAnnotationPresent(DeleteMapping.class))
|
|
.allMatch(method -> Arrays.asList(method.getAnnotation(DeleteMapping.class).value())
|
|
.contains("/drafts/{draftToken}/containers/{containerId}")));
|
|
assertFalse(Arrays.stream(SmartDispatchController.class.getDeclaredMethods())
|
|
.flatMap(method -> Arrays.stream(method.getAnnotations()))
|
|
.anyMatch(annotation -> Set.of("PutMapping", "PatchMapping")
|
|
.contains(annotation.annotationType().getSimpleName())));
|
|
}
|
|
|
|
@Test
|
|
void platformInventoryCommandsDoNotMapOutboundAllocationPickingOrShipping() {
|
|
Set<String> paths = Arrays.stream(InventoryCommandController.class.getDeclaredMethods())
|
|
.flatMap(method -> Arrays.stream(method.getAnnotations()))
|
|
.filter(annotation -> annotation.annotationType().getName().startsWith("org.springframework.web.bind.annotation"))
|
|
.flatMap(annotation -> {
|
|
try {
|
|
return Arrays.stream((String[]) annotation.annotationType().getMethod("value").invoke(annotation));
|
|
} catch (ReflectiveOperationException ignored) {
|
|
return java.util.stream.Stream.empty();
|
|
}
|
|
}).collect(Collectors.toSet());
|
|
assertFalse(paths.contains("/allocate"));
|
|
assertFalse(paths.contains("/unallocate"));
|
|
assertFalse(paths.contains("/pick"));
|
|
assertFalse(paths.contains("/ship"));
|
|
}
|
|
|
|
private static String basePath(Class<?> type) {
|
|
return type.getAnnotation(RequestMapping.class).value()[0];
|
|
}
|
|
}
|