test(firstleg): decouple PDA completion from truck

This commit is contained in:
2026-09-01 16:33:57 +08:00
parent eb385fe906
commit 9098d8dfdf
4 changed files with 67 additions and 3 deletions
@@ -40,6 +40,8 @@ import com.baiyue.firstleg.oceanbooking.entity.OceanBookingEntity;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.InOrder;
import org.mockito.ArgumentCaptor;
import org.springframework.boot.test.mock.mockito.MockBean;
@@ -785,6 +787,7 @@ class LoadingPickServiceTest {
@Test
void failedSameOperationIdCanResumeWithoutCreatingAnotherCommand() {
assertNoTruckCoupling();
LoadingPickTaskEntity failed = task();
failed.setTaskStatus("COMPLETION_FAILED");
LoadingPickTaskEntity completing = task();
@@ -871,6 +874,35 @@ class LoadingPickServiceTest {
verify(completionCommands).complete(900L, "worker-1");
}
@ParameterizedTest(name = "truck state {0} never participates in PDA completion")
@ValueSource(strings = {"NO_APPOINTMENT", "DRAFT", "IN_PROGRESS", "COMPLETED"})
void completionWorkerIsIndependentOfEveryTruckAppointmentState(String truckState) {
assertNoTruckCoupling();
LoadingPickTaskEntity completing = task();
completing.setTaskStatus("COMPLETING");
when(repository.task(20L)).thenReturn(completing);
when(repository.inboundOwners(20L)).thenReturn(List.of(
new LoadingPickItemMapper.InboundOwner(101L, 50L)));
when(repository.allPlanItemsPicked(10L)).thenReturn(true);
when(repository.review(20L)).thenReturn(null);
when(repository.approve(20L, 9L, "operator", "checked")).thenReturn(1);
when(repository.completeAccepted(20L, 9L, "operator")).thenReturn(1);
long commandId = 920L + Math.abs(truckState.hashCode() % 20);
when(completionCommands.complete(commandId, "worker-truck-independent")).thenReturn(true);
service.processCompletion(completionCommand(commandId,
"async-truck-independent-" + truckState.toLowerCase()), "worker-truck-independent");
verify(cabinetEvidenceService).requireComplete(99L);
verify(settlementService).settleOwner(20L, 50L, 9L, "operator");
verify(loadingDeliveryService).completeAfterPdaSettlement(101L, 50L, 9L, "operator",
"PDA-async-truck-independent-" + truckState.toLowerCase() + "-50", "checked");
verify(loadingListService).finishFromPda(10L, 20L, 9L, "operator");
verify(loadingListService).publishCompletedEvent(10L);
verify(repository).completeAccepted(20L, 9L, "operator");
verify(completionCommands).complete(commandId, "worker-truck-independent");
}
@Test
void workerUsesCabinetEvidenceOnceWithReversedTwoCustomerOwnerOrder() {
LoadingPickTaskEntity completing = task();
@@ -911,6 +943,7 @@ class LoadingPickServiceTest {
@Test
void secondCustomerOwnerReadyFailureLeavesEveryOwnerUnsettledAndUncompleted() {
assertNoTruckCoupling();
LoadingPickTaskEntity completing = task();
completing.setTaskStatus("COMPLETING");
when(repository.task(20L)).thenReturn(completing);
@@ -939,6 +972,7 @@ class LoadingPickServiceTest {
@Test
void workerRestartResumesFromOwnerCheckpointsWithoutRepeatingSettlements() {
assertNoTruckCoupling();
LoadingPickTaskEntity completing = task();
completing.setTaskStatus("COMPLETING");
when(repository.task(20L)).thenReturn(completing);
@@ -1180,6 +1214,14 @@ class LoadingPickServiceTest {
verify(repository, never()).touchTask(any(Long.class), any(Integer.class));
}
private static void assertNoTruckCoupling() {
assertThat(LoadingPickService.class.getDeclaredFields())
.noneMatch(field -> field.getType().equals(TruckAppointmentService.class));
assertThat(LoadingPickService.class.getDeclaredMethods())
.noneMatch(method -> method.getName().equals("completeTruckAfterCommit")
|| method.getName().equals("completeLoadingFromPda"));
}
private void preparePick(LoadingPickTaskEntity task, LoadingPickItemEntity item, String operationId) {
when(repository.history(operationId)).thenReturn(null);
when(repository.task(20L)).thenReturn(task);