优化
This commit is contained in:
+3
@@ -21,5 +21,8 @@ class OverseasProcurementInventoryBoundaryTest {
|
||||
assertFalse(source.contains("stockIn("));
|
||||
assertFalse(source.contains("setAvailablePackages"));
|
||||
assertFalse(source.contains("availablePackages"));
|
||||
assertFalse(source.contains("addOutbound"));
|
||||
assertFalse(source.contains("OverseasProcurementOutbound"));
|
||||
assertFalse(source.contains("outboundQuantity"));
|
||||
}
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package com.baiyue.lastleg.procurement;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class OverseasProcurementOpenApiContractTest {
|
||||
@Test
|
||||
void procurementContractDocumentsCandidatesClearSemanticsAndExcludesOutbound() throws Exception {
|
||||
String yaml;
|
||||
try (var input = getClass().getResourceAsStream("/openapi/overseas-business-v1.yaml")) {
|
||||
yaml = new String(input.readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
assertTrue(yaml.contains("/customer-options:"));
|
||||
assertTrue(yaml.contains("/warehouse-options:"));
|
||||
assertTrue(yaml.contains("显式 null 或空串表示清空"));
|
||||
assertTrue(yaml.contains("platform:overseas-business:purchase:list"));
|
||||
assertTrue(yaml.contains("platform:overseas-business:purchase:edit"));
|
||||
assertFalse(yaml.contains("/outbounds"));
|
||||
assertFalse(yaml.contains("采购出库单"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void contractContainsPlatformTruckWritesAndIndependentLooseboardDomain() throws Exception {
|
||||
String yaml;
|
||||
try (var input = getClass().getResourceAsStream("/openapi/overseas-business-v1.yaml")) {
|
||||
yaml = new String(input.readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
assertTrue(yaml.contains("platform:overseas-business:truck:create"));
|
||||
assertTrue(yaml.contains("platform:overseas-business:truck:edit"));
|
||||
assertTrue(yaml.contains("/api/platform/v1/last-leg/local-looseboard-orders:"));
|
||||
assertTrue(yaml.contains("platform:overseas-business:looseboard:list"));
|
||||
assertTrue(yaml.contains("platform:overseas-business:looseboard:create"));
|
||||
assertTrue(yaml.contains("platform:overseas-business:looseboard:edit"));
|
||||
assertTrue(yaml.contains("platform:overseas-business:looseboard:status"));
|
||||
assertFalse(yaml.contains("/api/platform/v1/last-leg/outbound"));
|
||||
assertFalse(yaml.contains("/api/platform/v1/last-leg/delivery"));
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -8,14 +8,16 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
class OverseasProcurementSchemaContractTest {
|
||||
@Test
|
||||
void baselineContainsOrderOutboundAndReviewHistoryTables() throws Exception {
|
||||
void baselineContainsOrderAndOperationHistoryButNoProcurementOutbound() throws Exception {
|
||||
String sql;
|
||||
try (var input = getClass().getResourceAsStream("/db/lastleg.sql")) {
|
||||
sql = new String(input.readAllBytes(), StandardCharsets.UTF_8);
|
||||
}
|
||||
assertTrue(sql.contains("CREATE TABLE IF NOT EXISTS ll_overseas_procurement_order"));
|
||||
assertTrue(sql.contains("CREATE TABLE IF NOT EXISTS ll_overseas_procurement_outbound"));
|
||||
assertTrue(sql.contains("CREATE TABLE IF NOT EXISTS ll_overseas_procurement_status_history"));
|
||||
assertTrue(sql.contains("UNIQUE KEY uk_ll_overseas_procurement_outbound_no(customer_id,order_id,outbound_no)"));
|
||||
assertTrue(sql.contains("operation_type VARCHAR(32) NOT NULL"));
|
||||
assertTrue(sql.contains("change_detail JSON NULL"));
|
||||
org.junit.jupiter.api.Assertions.assertFalse(sql.contains("CREATE TABLE IF NOT EXISTS ll_overseas_procurement_outbound"));
|
||||
org.junit.jupiter.api.Assertions.assertFalse(sql.contains("outbound_quantity BIGINT"));
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -62,6 +62,15 @@ class OverseasProcurementControllerTest {
|
||||
verify(service).review("100", "HC1", "7", request);
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformUpdatePassesAuditedOperator() {
|
||||
var request = new OverseasProcurementRequests.Update(0L, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null);
|
||||
platform.update(user(0L, "PLATFORM", Set.of(OverseasProcurementService.MANAGE_PERMISSION)),
|
||||
"100", "HC1", request);
|
||||
verify(service).update("100", "HC1", "7", request);
|
||||
}
|
||||
|
||||
private AuthenticatedUser user(long tenantId, String appCode, Set<String> permissions) {
|
||||
return new AuthenticatedUser(7L, tenantId, tenantId, 8L, "operator", appCode, "WEB", permissions);
|
||||
}
|
||||
|
||||
+69
-14
@@ -3,8 +3,9 @@ package com.baiyue.lastleg.procurement.service;
|
||||
import com.baiyue.lastleg.procurement.dto.OverseasProcurementRequests;
|
||||
import com.baiyue.lastleg.procurement.entity.OverseasProcurementOrder;
|
||||
import com.baiyue.lastleg.procurement.mapper.OverseasProcurementOrderMapper;
|
||||
import com.baiyue.lastleg.procurement.mapper.OverseasProcurementOutboundMapper;
|
||||
import com.baiyue.lastleg.procurement.mapper.OverseasProcurementStatusHistoryMapper;
|
||||
import com.baiyue.lastleg.masterdata.quote.service.PartnerWarehouseDirectory;
|
||||
import com.baiyue.lastleg.masterdata.quote.dto.OverseasQuoteResponses;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -23,21 +24,23 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class OverseasProcurementServiceTest {
|
||||
@Mock OverseasProcurementOrderMapper orders;
|
||||
@Mock OverseasProcurementOutboundMapper outbounds;
|
||||
@Mock OverseasProcurementStatusHistoryMapper histories;
|
||||
@Mock PartnerWarehouseDirectory warehouseDirectory;
|
||||
private OverseasProcurementService service;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
service = new OverseasProcurementService();
|
||||
ReflectionTestUtils.setField(service, "orders", orders);
|
||||
ReflectionTestUtils.setField(service, "outbounds", outbounds);
|
||||
ReflectionTestUtils.setField(service, "histories", histories);
|
||||
ReflectionTestUtils.setField(service, "warehouseDirectory", warehouseDirectory);
|
||||
ReflectionTestUtils.setField(service, "objectMapper", new ObjectMapper());
|
||||
}
|
||||
|
||||
@@ -49,7 +52,6 @@ class OverseasProcurementServiceTest {
|
||||
return 1;
|
||||
});
|
||||
when(orders.findNo(anyString(), anyString())).thenAnswer(ignored -> saved.get());
|
||||
when(outbounds.listOrder(anyString(), any())).thenReturn(List.of());
|
||||
when(histories.listOrder(anyString(), any())).thenReturn(List.of());
|
||||
|
||||
var detail = service.create("100", "7", new OverseasProcurementRequests.Create(
|
||||
@@ -69,21 +71,75 @@ class OverseasProcurementServiceTest {
|
||||
100L, null, null, null, null, null, null, null, null);
|
||||
|
||||
ResponseStatusException error = assertThrows(ResponseStatusException.class,
|
||||
() -> service.update("100", "HC1", request));
|
||||
() -> service.update("100", "HC1", "7", request));
|
||||
assertEquals(409, error.getStatusCode().value());
|
||||
}
|
||||
|
||||
@Test
|
||||
void outboundCannotExceedDerivedInventory() {
|
||||
OverseasProcurementOrder order = order(OverseasProcurementService.APPROVED, 100, 80);
|
||||
void explicitNullClearsOptionalFieldsAndWritesOperationHistory() {
|
||||
OverseasProcurementOrder order = order(OverseasProcurementService.APPROVED, 100, 0);
|
||||
order.setProductUrl("https://example.test/old");
|
||||
when(orders.lockNo("100", "HC1")).thenReturn(order);
|
||||
when(orders.addOutbound(order.getId(), "100", 30)).thenReturn(0);
|
||||
var request = new OverseasProcurementRequests.AddOutbound(30L, "OUT-1", null, null,
|
||||
LocalDateTime.now(), null);
|
||||
when(orders.findNo("100", "HC1")).thenReturn(order);
|
||||
when(histories.listOrder("100", 1L)).thenReturn(List.of());
|
||||
var request = new OverseasProcurementRequests.Update(0L, null, null,
|
||||
new ObjectMapper().nullNode(), new ObjectMapper().nullNode(), null,
|
||||
null, null, null, null, null, null, null, null);
|
||||
|
||||
ResponseStatusException error = assertThrows(ResponseStatusException.class,
|
||||
() -> service.addOutbound("100", "HC1", "7", request));
|
||||
assertEquals(409, error.getStatusCode().value());
|
||||
service.update("100", "HC1", "7", request);
|
||||
|
||||
assertEquals(null, order.getProductUrl());
|
||||
verify(histories).insert(org.mockito.ArgumentMatchers.<com.baiyue.lastleg.procurement.entity.OverseasProcurementStatusHistory>argThat(value ->
|
||||
"UPDATE".equals(value.getOperationType()) && value.getChangeDetail().contains("productUrl")));
|
||||
}
|
||||
|
||||
@Test
|
||||
void omittedOptionalFieldKeepsExistingValue() {
|
||||
OverseasProcurementOrder order = order(OverseasProcurementService.APPROVED, 100, 0);
|
||||
order.setProductUrl("https://example.test/keep");
|
||||
when(orders.lockNo("100", "HC1")).thenReturn(order);
|
||||
when(orders.findNo("100", "HC1")).thenReturn(order);
|
||||
when(histories.listOrder("100", 1L)).thenReturn(List.of());
|
||||
var request = new OverseasProcurementRequests.Update(0L, null, null, null, null,
|
||||
null, null, null, null, null, null, null, null, null);
|
||||
|
||||
service.update("100", "HC1", "7", request);
|
||||
|
||||
assertEquals("https://example.test/keep", order.getProductUrl());
|
||||
verify(orders, never()).updateById(org.mockito.ArgumentMatchers.<OverseasProcurementOrder>any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void warehouseSelectionFreezesCanonicalCandidateName() {
|
||||
OverseasProcurementOrder order = order(OverseasProcurementService.APPROVED, 100, 0);
|
||||
when(orders.lockNo("100", "HC1")).thenReturn(order);
|
||||
when(orders.findNo("100", "HC1")).thenReturn(order);
|
||||
when(histories.listOrder("100", 1L)).thenReturn(List.of());
|
||||
when(warehouseDirectory.required(10L)).thenReturn(
|
||||
new OverseasQuoteResponses.PartnerWarehouseOption("10", "LAX-01", "洛杉矶采购仓", "US"));
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
var request = new OverseasProcurementRequests.Update(0L, null, null, null, null,
|
||||
null, mapper.getNodeFactory().textNode("10"), mapper.getNodeFactory().textNode("伪造名称"),
|
||||
null, null, null, null, null, null);
|
||||
|
||||
service.update("100", "HC1", "7", request);
|
||||
|
||||
assertEquals("10", order.getPurchaseWarehouseId());
|
||||
assertEquals("洛杉矶采购仓", order.getPurchaseWarehouseName());
|
||||
}
|
||||
|
||||
@Test
|
||||
void customerOptionsAreDeduplicatedSnapshotsFromProcurementOrders() {
|
||||
OverseasProcurementOrder option = new OverseasProcurementOrder();
|
||||
option.setCustomerId("100");
|
||||
option.setCustomerName("Acme");
|
||||
when(orders.customerOptions("ac", 20)).thenReturn(List.of(option));
|
||||
|
||||
var values = service.customerOptions(" ac ", 20);
|
||||
|
||||
assertEquals(1, values.size());
|
||||
assertEquals("100", values.get(0).customerId());
|
||||
assertEquals("Acme", values.get(0).customerName());
|
||||
}
|
||||
|
||||
private OverseasProcurementOrder order(String status, long inbound, long outbound) {
|
||||
@@ -93,7 +149,6 @@ class OverseasProcurementServiceTest {
|
||||
order.setOrderNo("HC1");
|
||||
order.setStatus(status);
|
||||
order.setInboundQuantity(inbound);
|
||||
order.setOutboundQuantity(outbound);
|
||||
order.setPurchaseQuantity(500L);
|
||||
order.setVersion(0L);
|
||||
order.setCreatedAt(LocalDateTime.now());
|
||||
|
||||
Reference in New Issue
Block a user