Merge branch 'test' of http://8.163.30.128:10082/java-project/baiyue-firstleg into test
This commit is contained in:
+1
@@ -35,6 +35,7 @@ class ContainerControllerContractTest {
|
||||
.contains("/api/platform/v1/containers/{id}/transport:")
|
||||
.contains("platform:firstleg:container:list")
|
||||
.contains("EDITING")
|
||||
.contains("WAIT_LOADING")
|
||||
.contains("LOADING")
|
||||
.contains("COMPLETED")
|
||||
.doesNotContain("tenantId")
|
||||
|
||||
+3
@@ -24,7 +24,10 @@ class ContainerBookingMapperContractTest {
|
||||
assertThat(select)
|
||||
.contains("fl_loading_plan")
|
||||
.contains("p.id AS plan_id")
|
||||
.contains("CASE WHEN p.id IS NULL THEN 'WAIT_LOADING'")
|
||||
.contains("plan_status")
|
||||
.contains("p.plan_status != 'COMPLETED'")
|
||||
.doesNotContain("<>")
|
||||
.doesNotContain("tenant_id")
|
||||
.doesNotContain("account_id");
|
||||
}
|
||||
|
||||
+3
-1
@@ -34,7 +34,9 @@ class LoadingListQueryMapperContractTest {
|
||||
.contains("FROM fl_loading_plan p")
|
||||
.contains("JOIN fl_container_booking b")
|
||||
.contains("LEFT JOIN fl_loading_plan_item i")
|
||||
.contains("p.plan_status = 'LOADING'")
|
||||
.contains("p.preload_pushed_at IS NOT NULL")
|
||||
.contains("p.plan_status IN ('EDITING', 'LOADING')")
|
||||
.contains("active_item.deleted = 0")
|
||||
.contains("b.warehouse_id = #{query.warehouseId}")
|
||||
.doesNotContain("query.accountId")
|
||||
.doesNotContain("PRELOAD_PUSHED");
|
||||
|
||||
@@ -110,6 +110,8 @@ class SmartLoadingSqlContractTest {
|
||||
.contains("CHECK (plan_status IN ('EDITING', 'LOADING', 'COMPLETED'))")
|
||||
.contains("OLD.plan_status = 'EDITING' AND NEW.plan_status IN ('EDITING', 'LOADING')")
|
||||
.contains("NEW.plan_status IN ('LOADING', 'COMPLETED')")
|
||||
.contains("OLD.plan_status = 'LOADING' AND NEW.plan_status = 'EDITING'")
|
||||
.contains("旧版本在推送预装时即写入 LOADING")
|
||||
.contains("SET MESSAGE_TEXT = '装柜状态只允许单向推进'")
|
||||
.contains("IF OLD.plan_status = 'EDITING' AND NEW.plan_status = 'LOADING' THEN")
|
||||
.contains("ELSEIF OLD.plan_status = 'LOADING' AND NEW.plan_status = 'COMPLETED' THEN")
|
||||
|
||||
@@ -56,7 +56,7 @@ class ContainerServiceTest {
|
||||
assertThat(saved.getWarehouseName()).isEqualTo("上海中转仓");
|
||||
assertThat(saved.getDeparturePortCode()).isEqualTo("CNSHA");
|
||||
assertThat(saved.getCapacityCbm()).isEqualByComparingTo("68.0000");
|
||||
assertThat(saved.getPlanStatus()).isEqualTo("EDITING");
|
||||
assertThat(saved.getPlanStatus()).isEqualTo("WAIT_LOADING");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,6 +73,20 @@ class ContainerServiceTest {
|
||||
verify(repository).updateDraft(current, 2, 9L, "admin");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("待装柜阶段允许完整编辑")
|
||||
void updatesAllFieldsWhileWaitingForLoading() {
|
||||
ContainerBookingEntity current = booking("WAIT_LOADING", 2);
|
||||
when(repository.find(11L)).thenReturn(current);
|
||||
when(repository.updateDraft(any(), org.mockito.ArgumentMatchers.eq(2),
|
||||
org.mockito.ArgumentMatchers.eq(9L), org.mockito.ArgumentMatchers.eq("admin"))).thenReturn(1);
|
||||
|
||||
service.updateDraft(11L, 9L, "admin", new FullUpdateRequest(2, request("柜 NEW")));
|
||||
|
||||
assertThat(current.getCabinetNo()).isEqualTo("柜 NEW");
|
||||
verify(repository).updateDraft(current, 2, 9L, "admin");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("进入预装柜中后拒绝完整编辑")
|
||||
void rejectsFullUpdateAfterPreloadPush() {
|
||||
|
||||
@@ -50,13 +50,12 @@ class LoadingListServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRejectEditingStatusFromPreloadList() {
|
||||
void shouldAcceptEditingStatusFromPreloadList() {
|
||||
PreloadQuery query = new PreloadQuery(null, "EDITING", 100L, null, null, 1, 20);
|
||||
|
||||
assertThatThrownBy(() -> service.preloadPage(query))
|
||||
.isInstanceOf(BizException.class)
|
||||
.extracting(error -> ((BizException) error).getResultCode())
|
||||
.isEqualTo(ResultCode.BAD_REQUEST);
|
||||
service.preloadPage(query);
|
||||
|
||||
verify(repository).preloadPage(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -7,12 +7,14 @@ import com.baiyue.firstleg.dto.LoadingPickDtos.ReviewRequest;
|
||||
import com.baiyue.firstleg.dto.LoadingPickDtos.SkipRequest;
|
||||
import com.baiyue.firstleg.dto.LoadingPickDtos.BatchRequest;
|
||||
import com.baiyue.firstleg.dto.LoadingPickDtos.BatchItemRequest;
|
||||
import com.baiyue.firstleg.dto.LoadingPickDtos.ClaimRequest;
|
||||
import com.baiyue.firstleg.entity.LoadingPickAssignmentEntity;
|
||||
import com.baiyue.firstleg.entity.LoadingPickHistoryEntity;
|
||||
import com.baiyue.firstleg.entity.LoadingPickItemEntity;
|
||||
import com.baiyue.firstleg.entity.LoadingPickOperationEntity;
|
||||
import com.baiyue.firstleg.entity.LoadingPickTaskEntity;
|
||||
import com.baiyue.firstleg.repository.LoadingPickRepository;
|
||||
import com.baiyue.firstleg.repository.SmartLoadingRepository;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.InOrder;
|
||||
@@ -24,6 +26,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -36,6 +39,8 @@ class LoadingPickServiceTest {
|
||||
@MockBean
|
||||
private LoadingPickRepository repository;
|
||||
@MockBean
|
||||
private SmartLoadingRepository smartLoadingRepository;
|
||||
@MockBean
|
||||
private LoadingListService loadingListService;
|
||||
@MockBean
|
||||
private PdaPickSettlementService settlementService;
|
||||
@@ -75,6 +80,52 @@ class LoadingPickServiceTest {
|
||||
verify(repository).insert(any(LoadingPickHistoryEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void keepsPickAsStartLoadingFallbackForOlderClients() {
|
||||
LoadingPickTaskEntity task = task();
|
||||
LoadingPickItemEntity item = item();
|
||||
preparePick(task, item, "pick-start-loading");
|
||||
when(smartLoadingRepository.startPicking(10L, 9L, "operator")).thenReturn(1);
|
||||
|
||||
service.pick(20L, 30L, new PickRequest(101L, 2, List.of(), 0, "pick-start-loading"),
|
||||
9L, "operator");
|
||||
|
||||
verify(smartLoadingRepository).startPicking(10L, 9L, "operator");
|
||||
verify(smartLoadingRepository).insert(any(com.baiyue.firstleg.entity.LoadingPlanHistoryEntity.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void claimStartsLoadingAndSameOperatorReentryDoesNotDuplicateStartHistory() {
|
||||
LoadingPickTaskEntity task = task();
|
||||
LoadingPickAssignmentEntity assignment = assignment();
|
||||
AtomicReference<LoadingPickOperationEntity> operation = new AtomicReference<>();
|
||||
when(repository.operation("claim-1")).thenAnswer(invocation -> operation.get());
|
||||
when(repository.operation("claim-2")).thenReturn(null);
|
||||
when(repository.task(20L)).thenReturn(task);
|
||||
when(repository.taskForUpdate(20L)).thenReturn(task);
|
||||
when(repository.assignment(20L)).thenReturn(null, assignment);
|
||||
when(repository.createAssignment(20L, 9L, "operator", 9L, "operator", "CLAIMED")).thenReturn(1);
|
||||
when(smartLoadingRepository.startPicking(10L, 9L, "operator")).thenReturn(1, 0);
|
||||
doAnswer(invocation -> {
|
||||
LoadingPickOperationEntity value = invocation.getArgument(0);
|
||||
if ("claim-1".equals(value.getOperationId())) operation.set(value);
|
||||
return null;
|
||||
}).when(repository).insert(any(LoadingPickOperationEntity.class));
|
||||
|
||||
service.claim(20L, new ClaimRequest(0, "claim-1"), 9L, "operator");
|
||||
service.claim(20L, new ClaimRequest(0, "claim-1"), 9L, "operator");
|
||||
service.claim(20L, new ClaimRequest(0, "claim-2"), 9L, "operator");
|
||||
|
||||
verify(smartLoadingRepository, times(2)).startPicking(10L, 9L, "operator");
|
||||
verify(smartLoadingRepository, times(1)).insert(argThat(
|
||||
(com.baiyue.firstleg.entity.LoadingPlanHistoryEntity history) ->
|
||||
"START_LOADING".equals(history.getActionType())
|
||||
&& "EDITING".equals(history.getFromStatus())
|
||||
&& "LOADING".equals(history.getToStatus())
|
||||
&& "PDA-START-20".equals(history.getOperationId())));
|
||||
verify(repository, times(1)).createAssignment(20L, 9L, "operator", 9L, "operator", "CLAIMED");
|
||||
}
|
||||
|
||||
@Test
|
||||
void touchesTaskBeforeCompletingLastPartialItem() {
|
||||
LoadingPickTaskEntity task = task();
|
||||
|
||||
@@ -202,6 +202,28 @@ class SmartLoadingServiceTest {
|
||||
assertThat(captor.getValue().getProductQuantity()).isEqualTo(67);
|
||||
}
|
||||
|
||||
@Test
|
||||
void recyclesLegacyLoadingPlanBeforeAddingFirstItem() {
|
||||
LoadingPlanEntity stale = plan("LOADING", 5);
|
||||
LoadingPlanEntity after = plan("EDITING", 7);
|
||||
when(repository.plan(1)).thenReturn(stale, after);
|
||||
when(repository.booking(99)).thenReturn(booking());
|
||||
when(repository.recycleUnpicked(1, 5, 7, "u")).thenReturn(1);
|
||||
when(repository.touch(1, 6, 7, "u")).thenReturn(1);
|
||||
when(repository.items(1)).thenReturn(List.of());
|
||||
when(repository.candidate(100, 10, 20)).thenReturn(candidate(10));
|
||||
when(repository.activeItem(1L, 9L, 20L)).thenReturn(null);
|
||||
when(cargoClient.detail(anyString(), anyLong(), anyLong(), anyLong())).thenReturn(ApiResponse.success(
|
||||
new OrderCargoClient.CargoBinding(20L, 30L, 1, "货物", 1,
|
||||
BigDecimal.ONE, BigDecimal.ONE, null, null, null, null, null, null)));
|
||||
|
||||
Plan result = service.assign(1, new AssignRequest(10L, 20L, 1, 5, "assign-recycle"), 7, "u");
|
||||
|
||||
assertThat(result.status()).isEqualTo("EDITING");
|
||||
verify(repository).recycleUnpicked(1, 5, 7, "u");
|
||||
verify(repository).touch(1, 6, 7, "u");
|
||||
}
|
||||
|
||||
@Test
|
||||
void replaysBeforeVersionCheck() {
|
||||
AssignRequest request = new AssignRequest(10L, 20L, 2, 0, "assign-replay");
|
||||
@@ -335,7 +357,7 @@ class SmartLoadingServiceTest {
|
||||
@Test
|
||||
void pushesIdempotently() {
|
||||
LoadingPlanEntity editing = plan("EDITING", 3);
|
||||
LoadingPlanEntity pushed = plan("LOADING", 4);
|
||||
LoadingPlanEntity pushed = plan("EDITING", 4);
|
||||
pushed.setPushIdempotencyKey("key");
|
||||
when(repository.plan(1)).thenReturn(editing, pushed);
|
||||
when(repository.items(1)).thenReturn(List.of(item(8, 9, 20, 1)));
|
||||
@@ -344,7 +366,7 @@ class SmartLoadingServiceTest {
|
||||
|
||||
Plan result = service.pushPreload(1, "key", new PushRequest(3), 7, "u");
|
||||
|
||||
assertThat(result.status()).isEqualTo("LOADING");
|
||||
assertThat(result.status()).isEqualTo("EDITING");
|
||||
verify(repository).push(1, "key", 3, 7, "u");
|
||||
}
|
||||
|
||||
@@ -373,7 +395,7 @@ class SmartLoadingServiceTest {
|
||||
@Test
|
||||
void pushesWithoutContainerNumberWhenCapacityIsWithinLimit() {
|
||||
LoadingPlanEntity editing = plan("EDITING", 1);
|
||||
LoadingPlanEntity pushed = plan("LOADING", 2);
|
||||
LoadingPlanEntity pushed = plan("EDITING", 2);
|
||||
ContainerBookingEntity booking = booking();
|
||||
booking.setContainerNo(null);
|
||||
when(repository.plan(1)).thenReturn(editing, pushed);
|
||||
@@ -383,7 +405,7 @@ class SmartLoadingServiceTest {
|
||||
|
||||
Plan result = service.pushPreload(1, "no-container-key", new PushRequest(1), 7, "u");
|
||||
|
||||
assertThat(result.status()).isEqualTo("LOADING");
|
||||
assertThat(result.status()).isEqualTo("EDITING");
|
||||
verify(repository).push(1, "no-container-key", 1, 7, "u");
|
||||
verify(loadingPickService, never()).begin(anyLong(), any(), anyLong(), anyString(), anyList());
|
||||
}
|
||||
|
||||
@@ -8,9 +8,11 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
class SmartLoadingStatusTest {
|
||||
@Test
|
||||
void statusCanOnlyAdvanceOneWay() {
|
||||
assertThat(SmartLoadingStatus.WAIT_LOADING.canAdvanceTo(SmartLoadingStatus.EDITING)).isTrue();
|
||||
assertThat(SmartLoadingStatus.EDITING.canAdvanceTo(SmartLoadingStatus.LOADING)).isTrue();
|
||||
assertThat(SmartLoadingStatus.LOADING.canAdvanceTo(SmartLoadingStatus.COMPLETED)).isTrue();
|
||||
assertThat(SmartLoadingStatus.COMPLETED.canAdvanceTo(SmartLoadingStatus.LOADING)).isFalse();
|
||||
assertThat(SmartLoadingStatus.WAIT_LOADING.mutable()).isTrue();
|
||||
assertThat(SmartLoadingStatus.EDITING.mutable()).isTrue();
|
||||
assertThat(SmartLoadingStatus.LOADING.mutable()).isTrue();
|
||||
assertThat(SmartLoadingStatus.LOADING.allowsTransportUpdate()).isTrue();
|
||||
|
||||
@@ -21,6 +21,7 @@ import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
@@ -72,4 +73,36 @@ class SplitPreloadServiceTest {
|
||||
verify(loadingModelBridge).requireStarted(10, 20);
|
||||
verify(repository).beginLoading(10, 20, 7, 4);
|
||||
}
|
||||
|
||||
@Test
|
||||
void startsPreloadConfirmationAfterLoadingBeginsWithLinkedContainerGate() {
|
||||
when(repository.claimOperation(anyLong(), anyLong(), anyLong(), anyString(), anyString())).thenReturn(true);
|
||||
when(repository.findInbound(10, 20)).thenReturn(new InboundSnapshot(20L, 10L, "LOADING", 5));
|
||||
PreloadPlanEntity plan = new PreloadPlanEntity();
|
||||
plan.setTenantId(10L); plan.setInboundId(20L); plan.setStatus("PENDING"); plan.setVersion(3);
|
||||
plan.setItemsJson("[]");
|
||||
when(repository.findPlan(10, 20)).thenReturn(plan);
|
||||
org.mockito.Mockito.doNothing().when(loadingModelBridge).requireStarted(10, 20);
|
||||
when(repository.changePlanStatus(10, 20, "PENDING", "CONFIRMING", 7, "admin", 3)).thenReturn(1);
|
||||
|
||||
SplitActionResponse result = service.startConfirming(10, 20, 7, "admin", "k4",
|
||||
new ConfirmPreloadRequest(3));
|
||||
|
||||
assertThat(result.mainStatus()).isEqualTo("LOADING");
|
||||
verify(loadingModelBridge).requireStarted(10, 20);
|
||||
verify(repository).changePlanStatus(10, 20, "PENDING", "CONFIRMING", 7, "admin", 3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void rejectsLoadingPreloadConfirmationWhenLinkedContainersHaveNotStarted() {
|
||||
when(repository.claimOperation(anyLong(), anyLong(), anyLong(), anyString(), anyString())).thenReturn(true);
|
||||
when(repository.findInbound(10, 20)).thenReturn(new InboundSnapshot(20L, 10L, "LOADING", 5));
|
||||
org.mockito.Mockito.doThrow(new IllegalStateException("not started"))
|
||||
.when(loadingModelBridge).requireStarted(10, 20);
|
||||
|
||||
assertThatThrownBy(() -> service.startConfirming(10, 20, 7, "admin", "k5",
|
||||
new ConfirmPreloadRequest(3)))
|
||||
.isInstanceOf(IllegalStateException.class)
|
||||
.hasMessage("not started");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user