2026-08-19 16:24:02 +08:00
|
|
|
package com.baiyue.lastleg.service;
|
|
|
|
|
|
|
|
|
|
import com.baiyue.lastleg.dto.LastlegOrderRequests;
|
|
|
|
|
import com.baiyue.lastleg.entity.LastlegOrder;
|
|
|
|
|
import com.baiyue.lastleg.entity.LastlegOrderDetail;
|
|
|
|
|
import com.baiyue.lastleg.entity.LastlegOrderStatusHistory;
|
|
|
|
|
import com.baiyue.lastleg.mapper.LastlegOrderDetailMapper;
|
|
|
|
|
import com.baiyue.lastleg.mapper.LastlegOrderMapper;
|
|
|
|
|
import com.baiyue.lastleg.mapper.LastlegOrderStatusHistoryMapper;
|
|
|
|
|
import org.junit.jupiter.api.BeforeEach;
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
import org.junit.jupiter.api.extension.ExtendWith;
|
|
|
|
|
import org.mockito.ArgumentCaptor;
|
|
|
|
|
import org.mockito.Mock;
|
|
|
|
|
import org.mockito.junit.jupiter.MockitoExtension;
|
|
|
|
|
import org.springframework.web.server.ResponseStatusException;
|
|
|
|
|
import org.springframework.test.util.ReflectionTestUtils;
|
|
|
|
|
|
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertThrows;
|
|
|
|
|
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
|
|
|
import static org.mockito.ArgumentMatchers.any;
|
|
|
|
|
import static org.mockito.Mockito.never;
|
|
|
|
|
import static org.mockito.Mockito.verify;
|
|
|
|
|
import static org.mockito.Mockito.when;
|
|
|
|
|
|
|
|
|
|
@ExtendWith(MockitoExtension.class)
|
|
|
|
|
class LastlegOrderServiceTest {
|
|
|
|
|
@Mock LastlegOrderMapper orders;
|
|
|
|
|
@Mock LastlegOrderDetailMapper details;
|
|
|
|
|
@Mock LastlegOrderStatusHistoryMapper histories;
|
|
|
|
|
LastlegOrderService service;
|
|
|
|
|
|
|
|
|
|
@BeforeEach
|
|
|
|
|
void setUp() {
|
|
|
|
|
service = new LastlegOrderService();
|
|
|
|
|
ReflectionTestUtils.setField(service, "orderMapper", orders);
|
|
|
|
|
ReflectionTestUtils.setField(service, "detailMapper", details);
|
|
|
|
|
ReflectionTestUtils.setField(service, "historyMapper", histories);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
2026-08-20 18:02:38 +08:00
|
|
|
void detailDoesNotExposeDropshipCartonsOrInternalEventIds() {
|
2026-08-19 16:24:02 +08:00
|
|
|
LastlegOrder order = order(11L, "100", "PENDING_ASSIGNMENT", null);
|
|
|
|
|
order.setOrderType("ONE_CLICK_DROPSHIP");
|
|
|
|
|
when(orders.selectOne(any())).thenReturn(order);
|
|
|
|
|
when(details.selectList(any())).thenReturn(List.of());
|
|
|
|
|
when(histories.selectList(any())).thenReturn(List.of());
|
|
|
|
|
|
|
|
|
|
var response = service.detail("100", 11L);
|
|
|
|
|
|
2026-08-20 18:02:38 +08:00
|
|
|
assertEquals(11L, response.order().id());
|
2026-08-21 10:43:25 +08:00
|
|
|
assertEquals("100", response.order().customerId());
|
2026-08-22 12:35:32 +08:00
|
|
|
assertEquals("ONE_CLICK_DROPSHIP", response.order().orderType());
|
|
|
|
|
assertEquals("一件代发", response.order().orderTypeName());
|
2026-08-20 18:02:38 +08:00
|
|
|
assertTrue(java.util.Arrays.stream(response.getClass().getRecordComponents())
|
|
|
|
|
.noneMatch(component -> "dropshipPallets".equals(component.getName())));
|
|
|
|
|
assertTrue(java.util.Arrays.stream(com.baiyue.lastleg.dto.LastlegOrderDetailResponse.History.class.getRecordComponents())
|
|
|
|
|
.noneMatch(component -> "eventId".equals(component.getName())));
|
2026-08-19 16:24:02 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void transferUpdatesOrderAndEveryCargoSnapshot() {
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
assertEquals(1, service.transferDestination("100", request));
|
|
|
|
|
|
|
|
|
|
assertEquals("wh-2", order.getTransferWarehouseId());
|
|
|
|
|
assertEquals("LAX-02", order.getTransferWarehouseCode());
|
|
|
|
|
assertEquals("DESTINATION_ASSIGNED", order.getCurrentStatus());
|
|
|
|
|
ArgumentCaptor<LastlegOrderDetail> cargo = ArgumentCaptor.forClass(LastlegOrderDetail.class);
|
|
|
|
|
verify(details).update(cargo.capture(), any());
|
|
|
|
|
assertEquals("LAX-02", cargo.getValue().getDestinationWarehouseCode());
|
|
|
|
|
ArgumentCaptor<LastlegOrderStatusHistory> history = ArgumentCaptor.forClass(LastlegOrderStatusHistory.class);
|
|
|
|
|
verify(histories).insert(history.capture());
|
2026-08-24 11:55:50 +08:00
|
|
|
assertEquals("100", history.getValue().getCustomerId());
|
2026-08-19 16:24:02 +08:00
|
|
|
assertEquals("PENDING_ASSIGNMENT", history.getValue().getFromStatus());
|
|
|
|
|
assertEquals("DESTINATION_ASSIGNED", history.getValue().getToStatus());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void transferRejectsAnOrderAlreadyBoundToInboundPlan() {
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
assertThrows(ResponseStatusException.class, () -> service.transferDestination("100", request));
|
|
|
|
|
verify(orders, never()).updateById(any(LastlegOrder.class));
|
|
|
|
|
verify(details, never()).update(any(), any());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
ResponseStatusException error = assertThrows(ResponseStatusException.class,
|
|
|
|
|
() -> service.transferDestination("100", request));
|
|
|
|
|
assertTrue(error.getStatusCode().is4xxClientError());
|
|
|
|
|
verify(orders, never()).updateById(any(LastlegOrder.class));
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-21 14:42:40 +08:00
|
|
|
@Test
|
|
|
|
|
void pageUsesPaginationAndPlatformFiltersWithoutCustomerScope() {
|
|
|
|
|
var query = new LastlegOrderRequests.Query(3, 25, "LL-", "FIRST_LEG", "IN-", null,
|
|
|
|
|
"", "PENDING_ASSIGNMENT", null, "LAX", null, null, null, null, null);
|
|
|
|
|
var resultPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<LastlegOrder>(3, 25);
|
|
|
|
|
resultPage.setTotal(0);
|
|
|
|
|
when(orders.selectPage(any(), any())).thenReturn(resultPage);
|
|
|
|
|
|
|
|
|
|
service.page(null, query);
|
|
|
|
|
|
|
|
|
|
ArgumentCaptor<com.baomidou.mybatisplus.extension.plugins.pagination.Page<LastlegOrder>> page =
|
|
|
|
|
ArgumentCaptor.forClass(com.baomidou.mybatisplus.extension.plugins.pagination.Page.class);
|
|
|
|
|
verify(orders).selectPage(page.capture(), any());
|
|
|
|
|
assertEquals(3, page.getValue().getCurrent());
|
|
|
|
|
assertEquals(25, page.getValue().getSize());
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-19 16:24:02 +08:00
|
|
|
private static LastlegOrder order(long id, String customerId, String status, String inboundOrderNo) {
|
|
|
|
|
LastlegOrder order = new LastlegOrder();
|
|
|
|
|
order.setId(id);
|
|
|
|
|
order.setCustomerId(customerId);
|
|
|
|
|
order.setCurrentStatus(status);
|
|
|
|
|
order.setInboundOrderNo(inboundOrderNo);
|
|
|
|
|
return order;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|