优化
This commit is contained in:
+64
-18
@@ -1,7 +1,8 @@
|
||||
package com.baiyue.lastleg.service;
|
||||
|
||||
import com.baiyue.lastleg.dto.LastlegOrderRequests;
|
||||
import com.baiyue.lastleg.dto.PendingContainerSummary;
|
||||
import com.baiyue.lastleg.dto.ContainerPlanProgressDetail;
|
||||
import com.baiyue.lastleg.dto.ContainerPlanProgressSummary;
|
||||
import com.baiyue.lastleg.entity.LastlegOrder;
|
||||
import com.baiyue.lastleg.entity.LastlegOrderDetail;
|
||||
import com.baiyue.lastleg.entity.LastlegOrderStatusHistory;
|
||||
@@ -20,7 +21,6 @@ import org.springframework.web.server.ResponseStatusException;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
@@ -30,13 +30,16 @@ import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.Mockito.lenient;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class LastlegOrderServiceTest {
|
||||
// Service tests keep remote master-data validation and persistence independently observable here.
|
||||
@Mock LastlegOrderMapper orders;
|
||||
@Mock LastlegOrderDetailMapper details;
|
||||
@Mock LastlegOrderStatusHistoryMapper histories;
|
||||
@Mock InboundPlanCartonMapper cartons;
|
||||
@Mock FbaWarehouseValidator fbaWarehouses;
|
||||
LastlegOrderService service;
|
||||
|
||||
@BeforeEach
|
||||
@@ -46,6 +49,11 @@ class LastlegOrderServiceTest {
|
||||
ReflectionTestUtils.setField(service, "detailMapper", details);
|
||||
ReflectionTestUtils.setField(service, "historyMapper", histories);
|
||||
ReflectionTestUtils.setField(service, "cartonMapper", cartons);
|
||||
ReflectionTestUtils.setField(service, "fbaWarehouseValidator", fbaWarehouses);
|
||||
lenient().when(fbaWarehouses.required(any(), any(), any())).thenAnswer(invocation ->
|
||||
new FbaWarehouseValidator.VerifiedFbaWarehouse(
|
||||
Long.parseLong(invocation.getArgument(0)), invocation.getArgument(1), invocation.getArgument(2),
|
||||
"US", "CA"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,11 +81,11 @@ class LastlegOrderServiceTest {
|
||||
LastlegOrder order = order(11L, "100", "PENDING_ASSIGNMENT", null);
|
||||
when(orders.selectList(any())).thenReturn(List.of(order));
|
||||
var request = new LastlegOrderRequests.TransferDestination(
|
||||
List.of(11L), "wh-2", "LAX-02", "Los Angeles 02", null);
|
||||
List.of(11L), "193000000000000002", "LAX-02", "Los Angeles 02", null);
|
||||
|
||||
assertEquals(1, service.transferDestination("100", request));
|
||||
|
||||
assertEquals("wh-2", order.getTransferWarehouseId());
|
||||
assertEquals("193000000000000002", order.getTransferWarehouseId());
|
||||
assertEquals("LAX-02", order.getTransferWarehouseCode());
|
||||
assertEquals("DESTINATION_ASSIGNED", order.getCurrentStatus());
|
||||
ArgumentCaptor<LastlegOrderDetail> cargo = ArgumentCaptor.forClass(LastlegOrderDetail.class);
|
||||
@@ -85,7 +93,7 @@ class LastlegOrderServiceTest {
|
||||
assertEquals("LAX-02", cargo.getValue().getDestinationWarehouseCode());
|
||||
ArgumentCaptor<InboundPlanCarton> carton = ArgumentCaptor.forClass(InboundPlanCarton.class);
|
||||
verify(cartons).update(carton.capture(), any());
|
||||
assertEquals("wh-2", carton.getValue().getDestinationWarehouseId());
|
||||
assertEquals("193000000000000002", carton.getValue().getDestinationWarehouseId());
|
||||
assertEquals("LAX-02", carton.getValue().getDestinationWarehouseCode());
|
||||
ArgumentCaptor<LastlegOrderStatusHistory> history = ArgumentCaptor.forClass(LastlegOrderStatusHistory.class);
|
||||
verify(histories).insert(history.capture());
|
||||
@@ -99,7 +107,7 @@ class LastlegOrderServiceTest {
|
||||
LastlegOrder order = order(11L, "100", "DESTINATION_ASSIGNED", "IB-1");
|
||||
when(orders.selectList(any())).thenReturn(List.of(order));
|
||||
var request = new LastlegOrderRequests.TransferDestination(
|
||||
List.of(11L), "wh-2", "LAX-02", "Los Angeles 02", null);
|
||||
List.of(11L), "193000000000000002", "LAX-02", "Los Angeles 02", null);
|
||||
|
||||
assertThrows(ResponseStatusException.class, () -> service.transferDestination("100", request));
|
||||
verify(orders, never()).updateById(any(LastlegOrder.class));
|
||||
@@ -111,7 +119,7 @@ class LastlegOrderServiceTest {
|
||||
void batchRejectsMissingOrCrossCustomerIdsBeforeWriting() {
|
||||
when(orders.selectList(any())).thenReturn(List.of(order(11L, "100", "PENDING_ASSIGNMENT", null)));
|
||||
var request = new LastlegOrderRequests.TransferDestination(
|
||||
List.of(11L, 22L), "wh-2", "LAX-02", "Los Angeles 02", null);
|
||||
List.of(11L, 22L), "193000000000000002", "LAX-02", "Los Angeles 02", null);
|
||||
|
||||
ResponseStatusException error = assertThrows(ResponseStatusException.class,
|
||||
() -> service.transferDestination("100", request));
|
||||
@@ -119,6 +127,22 @@ class LastlegOrderServiceTest {
|
||||
verify(orders, never()).updateById(any(LastlegOrder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void forgedFbaSelectionIsRejectedBeforeLockingOrWritingOrders() {
|
||||
var request = new LastlegOrderRequests.TransferDestination(
|
||||
List.of(11L), "193000000000000002", "FAKE", "伪造仓库", null);
|
||||
when(fbaWarehouses.required("193000000000000002", "FAKE", "伪造仓库"))
|
||||
.thenThrow(new ResponseStatusException(org.springframework.http.HttpStatus.BAD_REQUEST,
|
||||
"所选FBA仓不存在或已停用"));
|
||||
|
||||
ResponseStatusException error = assertThrows(ResponseStatusException.class,
|
||||
() -> service.transferDestination("100", request));
|
||||
|
||||
assertTrue(error.getMessage().contains("所选FBA仓不存在或已停用"));
|
||||
verify(orders, never()).selectList(any());
|
||||
verify(orders, never()).updateById(any(LastlegOrder.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void pageUsesPaginationAndPlatformFiltersWithoutCustomerScope() {
|
||||
var query = new LastlegOrderRequests.Query(3, 25, "LL-", "FIRST_LEG", "IN-", null,
|
||||
@@ -137,14 +161,13 @@ class LastlegOrderServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void pendingContainerPageUsesServerSideAggregatePagination() {
|
||||
var query = new LastlegOrderRequests.PendingContainerQuery(2, 10, "CONT-", null, null);
|
||||
var row = new PendingContainerSummary("BOOKING-1", "CONT-1", 15, 15, 3,
|
||||
150, 0, new BigDecimal("12.5000"), true, null);
|
||||
when(orders.countPendingContainers(query)).thenReturn(11L);
|
||||
when(orders.pagePendingContainers(query, 10, 10)).thenReturn(List.of(row));
|
||||
void containerProgressPageUsesServerSideAggregatePagination() {
|
||||
var query = new LastlegOrderRequests.ContainerProgressQuery(2, 10, "CONT-", null, null);
|
||||
var row = summary(false, 3, "存在3票尚未生成有效入库计划");
|
||||
when(orders.countContainerProgress(query)).thenReturn(11L);
|
||||
when(orders.pageContainerProgress(query, 10, 10)).thenReturn(List.of(row));
|
||||
|
||||
var result = service.pendingContainerPage(query);
|
||||
var result = service.containerProgressPage(query);
|
||||
|
||||
assertEquals(2, result.page());
|
||||
assertEquals(10, result.size());
|
||||
@@ -154,13 +177,36 @@ class LastlegOrderServiceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void pendingContainerPageRejectsReversedDateRangeBeforeQuerying() {
|
||||
var query = new LastlegOrderRequests.PendingContainerQuery(1, 20, null,
|
||||
void containerProgressPageRejectsReversedDateRangeBeforeQuerying() {
|
||||
var query = new LastlegOrderRequests.ContainerProgressQuery(1, 20, null,
|
||||
LocalDateTime.of(2026, 8, 20, 0, 0), LocalDateTime.of(2026, 8, 19, 0, 0));
|
||||
|
||||
assertThrows(ResponseStatusException.class, () -> service.pendingContainerPage(query));
|
||||
assertThrows(ResponseStatusException.class, () -> service.containerProgressPage(query));
|
||||
|
||||
verify(orders, never()).countPendingContainers(any());
|
||||
verify(orders, never()).countContainerProgress(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void containerProgressDetailReturnsEveryOrderWithoutPagination() {
|
||||
var summary = summary(true, 0, null);
|
||||
var items = List.of(
|
||||
new ContainerPlanProgressDetail.Item(1L, "100", "LMO-1", "RK-1", "INBOUND_PLANNED",
|
||||
101L, "LIP-1", "PENDING_ASSIGNMENT", true, LocalDateTime.of(2026, 10, 3, 9, 0)),
|
||||
new ContainerPlanProgressDetail.Item(2L, "200", "LMO-1", "RK-2", "INBOUND_PLANNED",
|
||||
102L, "LIP-2", "PDA_PENDING", true, LocalDateTime.of(2026, 10, 3, 9, 0)));
|
||||
when(orders.findContainerProgress("BOOKING-1")).thenReturn(summary);
|
||||
when(orders.findContainerProgressItems("BOOKING-1")).thenReturn(items);
|
||||
|
||||
var result = service.containerProgressDetail(" BOOKING-1 ");
|
||||
|
||||
assertEquals(summary, result.summary());
|
||||
assertEquals(items, result.orders());
|
||||
verify(orders).findContainerProgressItems("BOOKING-1");
|
||||
}
|
||||
|
||||
private static ContainerPlanProgressSummary summary(boolean ready, long pending, String reason) {
|
||||
return new ContainerPlanProgressSummary("BOOKING-1", "CONT-1", 15, 15, 0,
|
||||
15 - pending, 15 - pending, pending, LocalDateTime.of(2026, 10, 3, 9, 0), ready, reason);
|
||||
}
|
||||
|
||||
private static LastlegOrder order(long id, String customerId, String status, String inboundOrderNo) {
|
||||
|
||||
Reference in New Issue
Block a user