优化
This commit is contained in:
+40
@@ -164,6 +164,46 @@ class HttpWarehouseResourceGatewayTest {
|
||||
server.verify();
|
||||
}
|
||||
|
||||
/** 实际SHIP后报废的原托扫码仍拒绝;保留提供者业务码/原因,不伪装为服务故障或按ID重试。 */
|
||||
@Test
|
||||
void inspectPreservesScrappedPalletBusinessConflictWithoutFallback() {
|
||||
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/D1747-1-001"))
|
||||
.andRespond(withSuccess("""
|
||||
{"code":"A0409","message":"托盘已报废","data":null}
|
||||
""", MediaType.APPLICATION_JSON));
|
||||
assertThatThrownBy(() -> gateway.inspectPallet("D1747-1-001"))
|
||||
.isInstanceOfSatisfying(ResponseStatusException.class, error -> {
|
||||
assertThat(error.getStatusCode()).isEqualTo(HttpStatus.CONFLICT);
|
||||
assertThat(error.getReason()).isEqualTo("托盘已报废");
|
||||
});
|
||||
server.verify();
|
||||
}
|
||||
|
||||
/** 按ID读取使用同一响应边界,错误码即使带data也不能被当作合法实托。 */
|
||||
@Test
|
||||
void idLookupRejectsBusinessConflictEvenWithPayload() {
|
||||
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/id/31"))
|
||||
.andRespond(withSuccess("""
|
||||
{"code":"A0409","message":"托盘状态冲突","data":{"palletId":31,"palletCode":"PAL-1",
|
||||
"warehouseId":88,"locationId":40,"status":"IDLE","version":1}}
|
||||
""", MediaType.APPLICATION_JSON));
|
||||
assertThatThrownBy(() -> gateway.resolvePallet(31L))
|
||||
.isInstanceOfSatisfying(ResponseStatusException.class, error ->
|
||||
assertThat(error.getStatusCode()).isEqualTo(HttpStatus.CONFLICT));
|
||||
server.verify();
|
||||
}
|
||||
|
||||
/** 同一个状态冲突无论通过HTTP状态还是业务信封传输,都不能降为400或503。 */
|
||||
@Test
|
||||
void inspectPreservesHttpConflict() {
|
||||
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/PAL-CONFLICT"))
|
||||
.andRespond(withStatus(HttpStatus.CONFLICT));
|
||||
assertThatThrownBy(() -> gateway.inspectPallet("PAL-CONFLICT"))
|
||||
.isInstanceOfSatisfying(ResponseStatusException.class, error ->
|
||||
assertThat(error.getStatusCode()).isEqualTo(HttpStatus.CONFLICT));
|
||||
server.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveReservedFallsBackToConfirmedPhysicalBindingForEarlierPlanDisplayCode() {
|
||||
server.expect(requestTo("http://warehouse/internal/v1/warehouse-pallets/resolve/IP-ACY2-20260909-166786-P001"))
|
||||
|
||||
+4
-4
@@ -359,7 +359,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
|
||||
new ContainerInboundPlanPreviewResponse.Group("ONE_CLICK_DROPSHIP", "31", "US-LAX-01", "Los Angeles",
|
||||
1, 1, 1, 1, 0, 0, 1, 0, List.of(overseas))), null);
|
||||
when(plans.previewContainer(BOOKING_ID)).thenReturn(preview);
|
||||
when(numbers.next(eq("INBOUND_PLAN"), any(String.class), any(Long.class)))
|
||||
when(numbers.next(eq("INBOUND_PLAN")))
|
||||
.thenReturn("IP-FBA", "IP-OVERSEAS");
|
||||
when(plans.sourcePalletNos("100", 11L, "ONE_CLICK_DROPSHIP")).thenReturn(List.of("MSCU6639870-ABE3-001"));
|
||||
when(plans.sourcePalletNos("200", 12L, "ONE_CLICK_DROPSHIP")).thenReturn(List.of("MSCU6639870-US-LAX-01-001"));
|
||||
@@ -392,7 +392,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
|
||||
List.of(new ContainerInboundPlanPreviewResponse.Group("FIRST_LEG", "31", "US-LAX-01", "Los Angeles",
|
||||
1, 1, 2, 0, 2, 0, 2, 0, List.of(overseas))), null);
|
||||
when(plans.previewContainer(BOOKING_ID)).thenReturn(preview);
|
||||
when(numbers.next(eq("INBOUND_PLAN"), any(String.class), any(Long.class))).thenReturn("IP-OVERSEAS");
|
||||
when(numbers.next(eq("INBOUND_PLAN"))).thenReturn("IP-OVERSEAS");
|
||||
when(plans.sourcePalletNos("200", 12L, "FIRST_LEG")).thenReturn(List.of());
|
||||
|
||||
ContainerPlanConversionCommand command = ReflectionTestUtils.invokeMethod(coordinator, "prepareCommand",
|
||||
@@ -424,7 +424,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
|
||||
List.of(new ContainerInboundPlanPreviewResponse.Group("FBA", null, "ACY2", "Amazon ACY2",
|
||||
1, 1, 3, 2, 1, 0, 3, 0, List.of(order))), null);
|
||||
when(plans.previewContainer(BOOKING_ID)).thenReturn(preview);
|
||||
when(numbers.next(eq("INBOUND_PLAN"), any(String.class), any(Long.class))).thenReturn("IP-ACY2");
|
||||
when(numbers.next(eq("INBOUND_PLAN"))).thenReturn("IP-ACY2");
|
||||
when(plans.sourcePalletNos("100", 11L, "FIRST_LEG")).thenReturn(List.of(
|
||||
"D0004-101-001", "D0004-101-002"));
|
||||
|
||||
@@ -475,7 +475,7 @@ class ContainerInboundPlanConversionCoordinatorTest {
|
||||
|
||||
assertEquals(21L, preparation.items().get(0).planId());
|
||||
assertEquals("IP-MANUAL", preparation.items().get(0).planNo());
|
||||
verify(numbers, never()).next(any(String.class), any(String.class), any(Long.class));
|
||||
verify(numbers, never()).next(any(String.class));
|
||||
}
|
||||
|
||||
private ContainerInboundPlanPreviewResponse.Order previewOrder(String customerId, String orderId,
|
||||
|
||||
+1
@@ -262,6 +262,7 @@ class FbaAppointmentPersistenceTest {
|
||||
@Bean com.baiyue.lastleg.mapper.LastlegOrderMapper orders(){var mock=mock(com.baiyue.lastleg.mapper.LastlegOrderMapper.class);var row=new com.baiyue.lastleg.entity.LastlegOrder();row.setId(100L);row.setCustomerId("C");row.setInboundCode("WT-REAL");when(mock.selectById(100L)).thenReturn(row);return mock;}
|
||||
@Bean AppointmentExternalSourceGateway bookings(){var mock=mock(AppointmentExternalSourceGateway.class);when(mock.resolve(anyList())).thenReturn(List.of(new AppointmentExternalSourceGateway.Source("C","B-1","TR-1","RECEIVED","100","FBA:ONT8",100L,10,2L)));return mock;}
|
||||
@Bean AppointmentSourceLinker linker(com.baiyue.lastleg.mapper.LastlegOrderMapper orders,InboundFbaAppointmentItemMapper items,AppointmentExternalSourceGateway bookings){return new InboundAppointmentSourceLinker(orders,items,bookings);}
|
||||
@Bean com.baiyue.lastleg.service.LastlegDocumentNumberGenerator documentNumbers() { return com.baiyue.lastleg.service.TestDocumentNumbers.documents(); }
|
||||
@Bean InboundFbaAppointmentService service(){return new InboundFbaAppointmentService();}
|
||||
@Bean com.baiyue.lastleg.appointmentwork.AppointmentWorkMapper workMapper(SqlSessionTemplate session){return session.getMapper(com.baiyue.lastleg.appointmentwork.AppointmentWorkMapper.class);}
|
||||
/** 使用生产持久层,继续验证需求失效与预约写入的同事务行为。 */
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ class InboundFbaAppointmentServiceTest {
|
||||
headers=mock(InboundFbaAppointmentMapper.class);items=mock(InboundFbaAppointmentItemMapper.class);query=mock(InboundFbaAppointmentQueryMapper.class);
|
||||
commands=mock(FbaAppointmentCommandMapper.class);sources=mock(AppointmentSourceService.class);flags=mock(AppointmentBatchPreviewMapper.class);
|
||||
service=new InboundFbaAppointmentService();
|
||||
org.springframework.test.util.ReflectionTestUtils.setField(service, "documentNumbers", com.baiyue.lastleg.service.TestDocumentNumbers.documents());
|
||||
ReflectionTestUtils.setField(service,"receiving",mock(com.baiyue.lastleg.inboundplan.receiving.FbaReceivingStore.class));
|
||||
ReflectionTestUtils.setField(service,"receivingWork",mock(com.baiyue.lastleg.inboundplan.receiving.FbaAppointmentWorkPort.class));
|
||||
ReflectionTestUtils.setField(service,"workChanges",mock(com.baiyue.lastleg.inboundplan.work.AppointmentWorkAppointmentChanges.class));
|
||||
@@ -95,7 +96,7 @@ class InboundFbaAppointmentServiceTest {
|
||||
}
|
||||
|
||||
@Test void savesCrossCustomerArrangementBeforeAnyInboundPlanOrExternalNumberExists() {
|
||||
var result=create("create");assertTrue(result.appointmentNo().startsWith("AP-"));assertNull(result.confirmationNo());assertNull(result.appointmentAt());
|
||||
var result=create("create");assertTrue(result.appointmentNo().matches("YY[0-9]{12}"));assertNull(result.confirmationNo());assertNull(result.appointmentAt());
|
||||
assertEquals(LocalDate.of(2026,10,15),result.plannedDate());assertEquals(2,result.selectedCount());assertEquals("PENDING",result.appointmentStatus());
|
||||
assertEquals(List.of("A","B"),result.items().stream().map(FbaAppointmentResponse.Item::customerId).toList());verify(query,never()).selectedLines(anyList());
|
||||
}
|
||||
|
||||
+1
-1
@@ -75,7 +75,7 @@ class InboundPlanServiceTest {
|
||||
ReflectionTestUtils.setField(service, "commandMapper", commandMapper);
|
||||
ReflectionTestUtils.setField(service, "sourcePalletMapper", sourcePalletMapper);
|
||||
ReflectionTestUtils.setField(service, "objectMapper", JsonMapper.builder().findAndAddModules().build());
|
||||
ReflectionTestUtils.setField(service, "orderNoGenerator", new com.baiyue.lastleg.service.LastlegOrderNoGenerator());
|
||||
ReflectionTestUtils.setField(service, "orderNoGenerator", com.baiyue.lastleg.service.TestDocumentNumbers.orders());
|
||||
org.mockito.Mockito.lenient().when(lineMapper.selectList(any())).thenReturn(List.of());
|
||||
org.mockito.Mockito.lenient().when(palletMapper.selectList(any())).thenReturn(List.of());
|
||||
org.mockito.Mockito.lenient().when(allocationMapper.selectList(any())).thenReturn(List.of());
|
||||
|
||||
Reference in New Issue
Block a user