fix: bind overseas receiving to shared warehouse
This commit is contained in:
+6
@@ -70,6 +70,8 @@ class ReceivingContainerContractTest {
|
||||
assertTrue(schema.contains("unique key uk_ll_receiving_sku_pallet (customer_id,line_id,pallet_id,sku_code)"));
|
||||
String receivingSession = tableBlock(schema, "ll_receiving_container_session");
|
||||
assertTrue(receivingSession.contains("sign_photos json"));
|
||||
assertTrue(receivingSession.contains("overseas_warehouse_id bigint not null"));
|
||||
assertTrue(receivingSession.contains("overseas_warehouse_name varchar(255) not null"));
|
||||
assertFalse(receivingSession.contains("photo_file_ids json"));
|
||||
assertTrue(unified.contains("create table if not exists ll_receiving_sku_receipt"));
|
||||
assertTrue(unified.contains("column_name='sign_photos'"));
|
||||
@@ -83,6 +85,8 @@ class ReceivingContainerContractTest {
|
||||
assertTrue(unified.contains("concat('container:',upper(trim(container_no)))"));
|
||||
assertTrue(unified.contains("assert_receiving_operation_global_key_migratable"));
|
||||
assertTrue(unified.contains("group_concat(column_name order by seq_in_index)= 'operator_key,idempotency_key'"));
|
||||
assertTrue(unified.contains("assert_pending_orders_do_not_use_source_warehouse"));
|
||||
assertTrue(unified.contains("assert_active_receiving_session_has_warehouse"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -105,6 +109,8 @@ class ReceivingContainerContractTest {
|
||||
assertTrue(receivingPaths.contains("仅 PLATFORM WAREHOUSE_PICKER 可用"));
|
||||
assertFalse(receivingPaths.contains("客户与操作账号均从 PDA Token 获取"));
|
||||
assertTrue(yaml.contains("enum: [LICENSE_PLATE, CONTAINER_SEAL, DOOR_OPEN]"));
|
||||
assertTrue(yaml.contains("overseasWarehouseId: { type: string"));
|
||||
assertTrue(yaml.contains("overseasWarehouseName: { type: string"));
|
||||
assertFalse(receivingPaths.contains("photoFileIds"));
|
||||
}
|
||||
|
||||
|
||||
+11
-3
@@ -31,12 +31,12 @@ class ReceivingContainerControllerTest {
|
||||
|
||||
@Test
|
||||
void candidatesDerivesOperatorFromPlatformWarehousePickerIdentity() {
|
||||
when(service.candidates("42")).thenReturn(List.of(new ReceivingContainerResponses.Candidate(
|
||||
when(service.candidates("42", 900L)).thenReturn(List.of(new ReceivingContainerResponses.Candidate(
|
||||
"CONT-1", "WAIT_SIGN", 2, 2, List.of("ONT8"), 4, 20, 0, false)));
|
||||
|
||||
controller.candidates(picker());
|
||||
|
||||
verify(service).candidates("42");
|
||||
verify(service).candidates("42", 900L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -54,8 +54,16 @@ class ReceivingContainerControllerTest {
|
||||
.hasMessageContaining("403");
|
||||
}
|
||||
|
||||
@Test
|
||||
void pickerAuthorityWithoutWarehouseBindingIsForbidden() {
|
||||
AuthenticatedUser unbound = new AuthenticatedUser(42L, 0L, 0L, 8L, "receiver", "PLATFORM", "PDA",
|
||||
Set.of(ReceivingContainerController.OPERATE_PERMISSION));
|
||||
assertThatThrownBy(() -> controller.candidates(unbound)).isInstanceOf(ResponseStatusException.class)
|
||||
.hasMessageContaining("403");
|
||||
}
|
||||
|
||||
private static AuthenticatedUser picker() {
|
||||
return new AuthenticatedUser(42L, 0L, 0L, 8L, "receiver", "PLATFORM", "PDA",
|
||||
Set.of(ReceivingContainerController.OPERATE_PERMISSION));
|
||||
Set.of(ReceivingContainerController.OPERATE_PERMISSION), false, null, null, false, 900L);
|
||||
}
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.baiyue.lastleg.inboundplan.pda.gateway;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.mock.web.MockMultipartFile;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
import org.springframework.test.web.client.MockRestServiceServer;
|
||||
import org.springframework.web.client.RestClient;
|
||||
import org.springframework.web.server.ResponseStatusException;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
|
||||
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
|
||||
|
||||
class HttpUnloadPhotoFileGatewayTest {
|
||||
private HttpUnloadPhotoFileGateway gateway;
|
||||
private MockRestServiceServer server;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
RestClient.Builder builder = RestClient.builder();
|
||||
server = MockRestServiceServer.bindTo(builder).build();
|
||||
gateway = new HttpUnloadPhotoFileGateway();
|
||||
ReflectionTestUtils.setField(gateway, "restClientBuilder", builder);
|
||||
ReflectionTestUtils.setField(gateway, "baseUrl", "http://file-service");
|
||||
ReflectionTestUtils.setField(gateway, "internalToken", "internal-token");
|
||||
gateway.initializeClient();
|
||||
}
|
||||
|
||||
@Test
|
||||
void forgedImageBusinessFailureMapsToBadRequestInsteadOfInternalError() {
|
||||
server.expect(requestTo("http://file-service/internal/file/v1/business-files/100/OVERSEAS_UNLOAD_PHOTO/8"))
|
||||
.andRespond(withSuccess("{\"code\":\"A0400\",\"message\":\"上传内容不是有效图片\",\"data\":null}",
|
||||
MediaType.APPLICATION_JSON));
|
||||
|
||||
assertThatThrownBy(() -> gateway.upload("100", 8L, 7L,
|
||||
new MockMultipartFile("file", "forged.png", "image/png", "<script>".getBytes())))
|
||||
.isInstanceOfSatisfying(ResponseStatusException.class,
|
||||
error -> assertThat(error.getStatusCode().value()).isEqualTo(400));
|
||||
server.verify();
|
||||
}
|
||||
|
||||
@Test
|
||||
void mismatchedPhotoMetadataMapsToBadRequest() {
|
||||
server.expect(requestTo("http://file-service/internal/file/v1/business-files/100/OVERSEAS_UNLOAD_PHOTO/8/9"))
|
||||
.andRespond(withSuccess("{\"code\":\"200\",\"data\":{\"fileId\":9,\"tenantId\":101,\"businessType\":\"OVERSEAS_UNLOAD_PHOTO\",\"businessId\":\"8\"}}",
|
||||
MediaType.APPLICATION_JSON));
|
||||
|
||||
assertThatThrownBy(() -> gateway.validate("100", 8L, 9L))
|
||||
.isInstanceOfSatisfying(ResponseStatusException.class,
|
||||
error -> assertThat(error.getStatusCode().value()).isEqualTo(400));
|
||||
server.verify();
|
||||
}
|
||||
}
|
||||
+32
-7
@@ -88,7 +88,14 @@ class ReceivingContainerServiceBehaviorTest {
|
||||
when(lines.selectList(any())).thenReturn(List.of());
|
||||
when(sessions.insert(any(ReceivingContainerSession.class))).thenReturn(1);
|
||||
when(operations.insert(any(ReceivingContainerOperation.class))).thenReturn(1);
|
||||
service.prepare("7", "receiver", "CONT-A", new ReceivingContainerRequests.Action("same-key"));
|
||||
when(warehouse.requireActiveSharedWarehouse(100L)).thenReturn(warehouseReference());
|
||||
when(plans.claimReceivingWarehouse("100", 2L, 100L)).thenReturn(1);
|
||||
InboundPlan claimed = plan("CONT-A"); claimed.setOverseasWarehouseId(100L);
|
||||
when(plans.selectById(2L)).thenReturn(claimed);
|
||||
var response = service.prepare("7", "receiver", 100L, "CONT-A",
|
||||
new ReceivingContainerRequests.Action("same-key"));
|
||||
assertThat(response.overseasWarehouseId()).isEqualTo(100L);
|
||||
assertThat(response.overseasWarehouseName()).isEqualTo("Shared LAX");
|
||||
ArgumentCaptor<ReceivingContainerSession> selected = ArgumentCaptor.forClass(ReceivingContainerSession.class);
|
||||
verify(sessions).insert(selected.capture());
|
||||
assertThat(selected.getValue().getCustomerId()).isEqualTo("100");
|
||||
@@ -98,7 +105,7 @@ class ReceivingContainerServiceBehaviorTest {
|
||||
verify(operations).insert(saved.capture());
|
||||
when(operations.find("7", "same-key")).thenReturn(saved.getValue());
|
||||
|
||||
assertThatThrownBy(() -> service.prepare("7", "receiver", "CONT-B",
|
||||
assertThatThrownBy(() -> service.prepare("7", "receiver", 100L, "CONT-B",
|
||||
new ReceivingContainerRequests.Action("same-key"))).isInstanceOf(ResponseStatusException.class)
|
||||
.hasMessageContaining("409");
|
||||
}
|
||||
@@ -110,20 +117,33 @@ class ReceivingContainerServiceBehaviorTest {
|
||||
when(plans.selectList(any())).thenReturn(List.of(first, second), List.of(first), List.of(second));
|
||||
when(lines.selectList(any())).thenReturn(List.of());
|
||||
|
||||
assertThat(service.candidates("7")).extracting("containerNo").containsExactly("CONT-A", "CONT-B");
|
||||
assertThat(service.candidates("7", 100L)).extracting("containerNo").containsExactly("CONT-A", "CONT-B");
|
||||
|
||||
InboundPlan ambiguous = plan("CONT-A"); ambiguous.setId(4L); ambiguous.setCustomerId("200");
|
||||
org.mockito.Mockito.reset(plans, sessions);
|
||||
when(plans.selectList(any())).thenReturn(List.of(first, ambiguous));
|
||||
assertThatThrownBy(() -> service.candidates("7")).isInstanceOf(ResponseStatusException.class)
|
||||
assertThatThrownBy(() -> service.candidates("7", 100L)).isInstanceOf(ResponseStatusException.class)
|
||||
.hasMessageContaining("exactly one customer");
|
||||
}
|
||||
|
||||
@Test
|
||||
void candidatesIncludeUnassignedAndSameWarehouseButHideOtherWarehouse() {
|
||||
InboundPlan unassigned = plan("CONT-A");
|
||||
InboundPlan same = plan("CONT-B"); same.setId(3L); same.setOverseasWarehouseId(100L);
|
||||
InboundPlan other = plan("CONT-C"); other.setId(4L); other.setOverseasWarehouseId(200L);
|
||||
when(plans.selectList(any())).thenReturn(List.of(unassigned, same, other),
|
||||
List.of(unassigned), List.of(same));
|
||||
when(lines.selectList(any())).thenReturn(List.of());
|
||||
|
||||
assertThat(service.candidates("7", 100L)).extracting("containerNo")
|
||||
.containsExactly("CONT-A", "CONT-B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void waitSignSelectionAlreadyLocksAccountFromViewingAnotherContainer() {
|
||||
when(plans.selectList(any())).thenReturn(List.of(plan("CONT-B")));
|
||||
when(sessions.findActiveByOperator("OPERATOR:7")).thenReturn(session("CONT-A", "WAIT_SIGN"));
|
||||
assertThatThrownBy(() -> service.detail("7", "CONT-B"))
|
||||
assertThatThrownBy(() -> service.detail("7", 100L, "CONT-B"))
|
||||
.isInstanceOf(ResponseStatusException.class).hasMessageContaining("409");
|
||||
}
|
||||
|
||||
@@ -131,13 +151,13 @@ class ReceivingContainerServiceBehaviorTest {
|
||||
void prepareEnforcesBothActiveAccountAndActiveContainerUniqueness() {
|
||||
when(plans.selectList(any())).thenReturn(List.of(plan("CONT-B")));
|
||||
when(sessions.lockActiveByOperator("OPERATOR:7")).thenReturn(session("CONT-A", "WAIT_SIGN"));
|
||||
assertThatThrownBy(() -> service.prepare("7", "receiver", "CONT-B",
|
||||
assertThatThrownBy(() -> service.prepare("7", "receiver", 100L, "CONT-B",
|
||||
new ReceivingContainerRequests.Action("account-lock"))).isInstanceOf(ResponseStatusException.class);
|
||||
verify(sessions, never()).insert(any(ReceivingContainerSession.class));
|
||||
|
||||
org.mockito.Mockito.reset(sessions, operations);
|
||||
when(sessions.lockActiveByContainer("CONTAINER:CONT-B")).thenReturn(session("CONT-B", "WAIT_SIGN"));
|
||||
assertThatThrownBy(() -> service.prepare("7", "receiver", "CONT-B",
|
||||
assertThatThrownBy(() -> service.prepare("7", "receiver", 100L, "CONT-B",
|
||||
new ReceivingContainerRequests.Action("container-lock"))).isInstanceOf(ResponseStatusException.class);
|
||||
verify(sessions, never()).insert(any(ReceivingContainerSession.class));
|
||||
}
|
||||
@@ -356,6 +376,7 @@ class ReceivingContainerServiceBehaviorTest {
|
||||
private static ReceivingContainerSession session(String containerNo, String status) {
|
||||
ReceivingContainerSession value = new ReceivingContainerSession();
|
||||
value.setId(8L); value.setCustomerId("100"); value.setContainerNo(containerNo); value.setOperatorKey("7");
|
||||
value.setOverseasWarehouseId(100L); value.setOverseasWarehouseName("Shared LAX");
|
||||
value.setStatus(status); value.setVersion(0);
|
||||
return value;
|
||||
}
|
||||
@@ -378,6 +399,10 @@ class ReceivingContainerServiceBehaviorTest {
|
||||
"AVAILABLE", fbaCode, 0);
|
||||
}
|
||||
|
||||
private static WarehouseResourceGateway.WarehouseReference warehouseReference() {
|
||||
return new WarehouseResourceGateway.WarehouseReference(100L, "SHARED-LAX", "Shared LAX", "ACTIVE");
|
||||
}
|
||||
|
||||
private String hash(Object value) {
|
||||
try {
|
||||
String json = new ObjectMapper().findAndRegisterModules().copy()
|
||||
|
||||
+13
@@ -4,8 +4,11 @@ import com.baiyue.lastleg.inventory.entity.InventoryBalance;
|
||||
import com.baiyue.lastleg.inventory.entity.InventoryLedger;
|
||||
import com.baiyue.lastleg.inventory.entity.InventoryOperation;
|
||||
import com.baiyue.lastleg.inventory.entity.InventoryPosition;
|
||||
import com.baiyue.lastleg.inventory.query.dto.InventoryQueryRequests;
|
||||
import com.baiyue.lastleg.inventory.query.mapper.InventoryQueryMapper;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import org.apache.ibatis.annotations.Select;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -69,6 +72,16 @@ class InventorySchemaContractTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void positionQuerySqlReferencesOnlyFieldsExposedByThePositionQueryDto() throws NoSuchMethodException {
|
||||
Select select = InventoryQueryMapper.class.getMethod("positions", String.class, long.class,
|
||||
InventoryQueryRequests.PositionQuery.class).getAnnotation(Select.class);
|
||||
String sql = String.join(" ", select.value());
|
||||
assertFalse(sql.contains("q.skuCode"));
|
||||
assertFalse(sql.contains("q.warehouseLocationCode"));
|
||||
assertFalse(sql.contains("sku_code"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void incrementalMigrationIsAdditiveAndRerunnable() throws IOException {
|
||||
String migration = Files.readString(Path.of("..", "scripts", "db", "incremental.sql"), StandardCharsets.UTF_8)
|
||||
|
||||
+10
-4
@@ -22,19 +22,25 @@ class InventoryQueryControllerTest {
|
||||
|
||||
@Test
|
||||
void platformBalancePageQueriesAllCustomers() {
|
||||
controller.balances(user(0L, "PLATFORM"), query);
|
||||
controller.balances(user(0L, "PLATFORM"), null, query);
|
||||
verify(service).balances(eq(null), eq(query));
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformBalancePageUsesExplicitCustomerScope() {
|
||||
controller.balances(user(0L, "PLATFORM"), " 10001 ", query);
|
||||
verify(service).balances(eq("10001"), eq(query));
|
||||
}
|
||||
|
||||
@Test
|
||||
void merchantCannotUsePlatformInventoryController() {
|
||||
assertThrows(ResponseStatusException.class,
|
||||
() -> controller.summary(user(100L, "MERCHANT"), query));
|
||||
() -> controller.summary(user(100L, "MERCHANT"), null, query));
|
||||
}
|
||||
|
||||
@Test
|
||||
void platformSummaryQueriesAllCustomers() {
|
||||
controller.summary(user(0L, "PLATFORM"), query);
|
||||
controller.summary(user(0L, "PLATFORM"), null, query);
|
||||
verify(service).dashboard(eq(null), eq(query));
|
||||
}
|
||||
|
||||
@@ -43,7 +49,7 @@ class InventoryQueryControllerTest {
|
||||
InventoryQueryRequests.PositionQuery positionQuery =
|
||||
new InventoryQueryRequests.PositionQuery(null, null, null);
|
||||
assertThrows(ResponseStatusException.class,
|
||||
() -> controller.positions(null, 1L, positionQuery));
|
||||
() -> controller.positions(null, 1L, null, positionQuery));
|
||||
}
|
||||
|
||||
private static AuthenticatedUser user(long customerId, String appCode) {
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ import com.baiyue.common.event.*; import com.baiyue.lastleg.entity.*; import com
|
||||
class LoadingCompletedConsumerTest {
|
||||
@Mock LastlegEventInboxMapper inbox; @Mock LastlegOrderMapper orders; @Mock LastlegInboundOrderMapper inboundOrders; @Mock LastlegOrderDetailMapper details; @Mock LastlegOrderStatusHistoryMapper histories; @Mock InboundPlanCartonMapper cartons; @Mock DropshipOrderService dropshipOrders; @Mock InboundPlanService inboundPlans; @Mock InventoryCommandService inventory; ObjectMapper json=new ObjectMapper().findAndRegisterModules(); LoadingCompletedConsumer service;
|
||||
@BeforeEach void setup(){ service=new LoadingCompletedConsumer(); ReflectionTestUtils.setField(service,"inboxMapper",inbox); ReflectionTestUtils.setField(service,"orderMapper",orders); ReflectionTestUtils.setField(service,"inboundOrderMapper",inboundOrders); ReflectionTestUtils.setField(service,"detailMapper",details); ReflectionTestUtils.setField(service,"historyMapper",histories); ReflectionTestUtils.setField(service,"cartonMapper",cartons); ReflectionTestUtils.setField(service,"dropshipOrders",dropshipOrders); ReflectionTestUtils.setField(service,"inboundPlans",inboundPlans); ReflectionTestUtils.setField(service,"inventory",inventory); ReflectionTestUtils.setField(service,"objectMapper",json); ReflectionTestUtils.setField(service,"orderNoGenerator",new LastlegOrderNoGenerator()); lenient().doAnswer(i->{ LastlegOrder o=i.getArgument(0); o.setId(Math.abs(o.getSourceInboundId().hashCode())+1L); return 1; }).when(orders).insert(any(LastlegOrder.class)); lenient().when(inboundPlans.convert(anyString(),anyLong())).thenReturn(new InboundPlanResponse(1L,"LIP-1","100",1L,"MSCU1","PENDING_ASSIGNMENT",1,1,BigDecimal.ONE,List.of(),List.of(),List.of())); }
|
||||
@Test void createsOneOrderAndOneInboundPlanPerInbound(){ EventEnvelope event=event(); assertEquals(2,service.consume(event)); verify(orders,times(2)).insert(any(LastlegOrder.class)); verify(inboundPlans,times(2)).convert(eq("100"),anyLong()); verify(inventory,times(2)).registerInTransit(eq("100"),eq("SYSTEM"),any(InventoryCommandRequests.InTransit.class)); verify(details,times(2)).insert(any(LastlegOrderDetail.class)); verify(histories,times(2)).insert(any(LastlegOrderStatusHistory.class)); ArgumentCaptor<LastlegOrder> c=ArgumentCaptor.forClass(LastlegOrder.class); verify(orders,times(2)).insert(c.capture()); assertEquals(Set.of("in-1","in-2"),c.getAllValues().stream().map(LastlegOrder::getSourceInboundId).collect(java.util.stream.Collectors.toSet())); assertTrue(c.getAllValues().stream().allMatch(o->"PENDING_ASSIGNMENT".equals(o.getCurrentStatus()))); assertTrue(c.getAllValues().stream().allMatch(o->o.getId()!=null)); assertTrue(c.getAllValues().stream().allMatch(o->"MSCU1".equals(o.getContainerNo()))); assertTrue(c.getAllValues().stream().allMatch(o->"FBA".equals(o.getDestinationType()))); ArgumentCaptor<LastlegInboundOrder> snapshots=ArgumentCaptor.forClass(LastlegInboundOrder.class); verify(inboundOrders,times(2)).insert(snapshots.capture()); assertTrue(snapshots.getAllValues().stream().allMatch(o->"100".equals(o.getCustomerId())&&"FBA".equals(o.getDestinationType()))); assertEquals(1,c.getAllValues().stream().map(LastlegOrder::getOrderNo).distinct().count()); assertEquals(new LastlegOrderNoGenerator().forContainerNo("MSCU1"),c.getAllValues().get(0).getOrderNo()); }
|
||||
@Test void createsOneOrderAndOneInboundPlanPerInbound(){ EventEnvelope event=event(); assertEquals(2,service.consume(event)); verify(orders,times(2)).insert(any(LastlegOrder.class)); verify(inboundPlans,times(2)).convert(eq("100"),anyLong()); verify(inventory,times(2)).registerInTransit(eq("100"),eq("SYSTEM"),any(InventoryCommandRequests.InTransit.class)); verify(details,times(2)).insert(any(LastlegOrderDetail.class)); verify(histories,times(2)).insert(any(LastlegOrderStatusHistory.class)); ArgumentCaptor<LastlegOrder> c=ArgumentCaptor.forClass(LastlegOrder.class); verify(orders,times(2)).insert(c.capture()); assertEquals(Set.of("in-1","in-2"),c.getAllValues().stream().map(LastlegOrder::getSourceInboundId).collect(java.util.stream.Collectors.toSet())); assertTrue(c.getAllValues().stream().allMatch(o->"PENDING_ASSIGNMENT".equals(o.getCurrentStatus()))); assertTrue(c.getAllValues().stream().allMatch(o->o.getId()!=null)); assertTrue(c.getAllValues().stream().allMatch(o->"MSCU1".equals(o.getContainerNo()))); assertTrue(c.getAllValues().stream().allMatch(o->"FBA".equals(o.getDestinationType()))); assertTrue(c.getAllValues().stream().allMatch(o->"ow-1".equals(o.getSourceWarehouseId())&&o.getOverseasWarehouseId()==null)); ArgumentCaptor<LastlegInboundOrder> snapshots=ArgumentCaptor.forClass(LastlegInboundOrder.class); verify(inboundOrders,times(2)).insert(snapshots.capture()); assertTrue(snapshots.getAllValues().stream().allMatch(o->"100".equals(o.getCustomerId())&&"FBA".equals(o.getDestinationType()))); assertEquals(1,c.getAllValues().stream().map(LastlegOrder::getOrderNo).distinct().count()); assertEquals(new LastlegOrderNoGenerator().forContainerNo("MSCU1"),c.getAllValues().get(0).getOrderNo()); }
|
||||
@Test void repeatedEventReturnsExistingEffect(){ EventEnvelope event=event(); LastlegEventInbox row=new LastlegEventInbox(); row.setPayloadHash(event.payloadHash()); when(inbox.selectById(event.eventId())).thenReturn(row); when(orders.countContainer("100","MSCU1")).thenReturn(2L); assertEquals(2,service.consume(event)); verify(orders).countContainer("100","MSCU1"); verify(orders,never()).insert(any(LastlegOrder.class)); verify(details,never()).insert(any(LastlegOrderDetail.class)); }
|
||||
@Test void sameEventWithDifferentHashIsRejected(){ EventEnvelope event=event(); LastlegEventInbox row=new LastlegEventInbox(); row.setPayloadHash("sha256:"+"0".repeat(64)); when(inbox.selectById(event.eventId())).thenReturn(row); assertThrows(IllegalArgumentException.class,()->service.consume(event)); }
|
||||
@Test void inboundSnapshotUsesCustomerIdAndHasNoPhantomTenantColumn() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user