diff --git a/firstleg/src/test/java/com/baiyue/firstleg/terminaldrayage/service/ContainerWorkbenchServiceTest.java b/firstleg/src/test/java/com/baiyue/firstleg/terminaldrayage/service/ContainerWorkbenchServiceTest.java index 0216d1caf..8fcbb1d3e 100644 --- a/firstleg/src/test/java/com/baiyue/firstleg/terminaldrayage/service/ContainerWorkbenchServiceTest.java +++ b/firstleg/src/test/java/com/baiyue/firstleg/terminaldrayage/service/ContainerWorkbenchServiceTest.java @@ -84,6 +84,65 @@ class ContainerWorkbenchServiceTest { verifyNoInteractions(carrierSchedules); } + @Test + void realOverseasListAndDetailProjectBothEmptyReturnActions() throws Exception { + verifyRealEmptyReturnProjection(true, true); + } + + @Test + void realOverseasListAndDetailRemoveBothActionsWithoutPermission() throws Exception { + verifyRealEmptyReturnProjection(false, true); + } + + @Test + void unloadedListWithoutDrayageAggregateDoesNotOfferUnexecutableReturn() throws Exception { + verifyRealEmptyReturnProjection(true, false); + } + + private void verifyRealEmptyReturnProjection(boolean hasPermission, boolean hasAggregate) throws Exception { + var mapper = mock(com.baiyue.firstleg.terminaldrayage.mapper.TerminalDrayageMapper.class); + var json = new com.fasterxml.jackson.databind.ObjectMapper().findAndRegisterModules(); + var realDrayages = new TerminalDrayageService(mapper, + mock(com.baiyue.firstleg.service.WarehouseSupplierSnapshotService.class), carrierSchedules, json); + ReflectionTestUtils.setField(service, "terminalDrayages", realDrayages); + ContainerBookingEntity container = container(); + container.setUnloadingCompletedAt(LocalDateTime.of(2026, 9, 5, 8, 0)); + var context = new com.baiyue.firstleg.terminaldrayage.mapper.TerminalDrayageMapper.Context( + 11L, "MSCU1234567", 21L, "ACTIVE", container.getUnloadingCompletedAt()); + var row = new com.baiyue.firstleg.terminaldrayage.entity.TerminalDrayageEntity(); + row.setId(51L); + row.setContainerBookingId(11L); + row.setVersion(3); + row.setActualPickupAt(LocalDateTime.of(2026, 9, 4, 9, 0)); + when(repository.page(eq("OVERSEAS"), any())).thenReturn(new PageResult<>(List.of(container), 1, 20, 1, 1)); + when(repository.find(11L)).thenReturn(container); + when(repository.departed(11L)).thenReturn(true); + when(mapper.contexts(List.of(11L))).thenReturn(List.of(context)); + when(mapper.context(11L)).thenReturn(context); + when(mapper.findAll(List.of(11L))).thenReturn(hasAggregate ? List.of(row) : List.of()); + when(mapper.find(11L)).thenReturn(hasAggregate ? row : null); + when(carrierSchedules.containerActualFacts(List.of(11L))).thenReturn(List.of(facts("PICKED_UP"))); + Set permissions = hasPermission + ? Set.of("platform:firstleg:terminal-drayage:list", "platform:firstleg:terminal-drayage:empty-return:confirm") + : Set.of("platform:firstleg:terminal-drayage:list"); + + var page = service.overseasPage(query(WorkbenchScope.ACTIVE), permissions); + var listed = page.records().get(0); + var detail = service.overseasDetail(11L, permissions); + List expected = hasPermission && hasAggregate ? List.of("RECORD_EMPTY_RETURN") : List.of(); + assertThat(listed.workbenchStage()).isEqualTo("UNLOADED"); + assertThat(listed.terminalDrayage().status()).isEqualTo("UNLOADED"); + assertThat(listed.allowedActions()).isEqualTo(expected); + assertThat(listed.terminalDrayage().allowedActions()).isEqualTo(expected); + assertThat(detail.allowedActions()).isEqualTo(listed.allowedActions()); + assertThat(detail.terminalDrayage().allowedActions()).isEqualTo(listed.terminalDrayage().allowedActions()); + var serialized = json.readTree(json.writeValueAsString(com.baiyue.common.core.api.ApiResponse.success(page))); + assertThat(serialized.at("/data/records/0/allowedActions")).isEqualTo(json.valueToTree(expected)); + assertThat(serialized.at("/data/records/0/terminalDrayage/allowedActions")).isEqualTo(json.valueToTree(expected)); + verify(mapper).findAll(List.of(11L)); + verify(mapper).contexts(List.of(11L)); + } + @Test void domesticHistoryDetailKeepsTheDepartedContainerAndItsUniqueLoadingPlan() { ContainerBookingEntity container = container();