优化
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import test from 'node:test'
|
||||
|
||||
const source = readFileSync(new URL('./phase3-evidence-gate.mjs', import.meta.url), 'utf8')
|
||||
|
||||
test('evidence gate requires stable PDA identity and server LOADING before any evidence request', () => {
|
||||
for (const field of ['taskId', 'inboundId', 'loadingPlanId', 'containerBookingId', 'warehouseId']) {
|
||||
assert.match(source, new RegExp(`${field}`), `${field} must be part of the preflight identity`)
|
||||
}
|
||||
assert.match(source, /pda-loading\/tasks\?loadingPlanId=/)
|
||||
assert.match(source, /task\?\.id\) === taskId/)
|
||||
assert.match(source, /task\?\.loadingPlanId\) === loadingPlanId/)
|
||||
assert.match(source, /task\?\.containerBookingId\) === containerBookingId/)
|
||||
assert.match(source, /taskItem\?\.inboundId\) === inboundId/)
|
||||
assert.match(source, /processStatus === 'LOADING'/)
|
||||
assert.match(source, /if \(!serverLoading\)[\s\S]*return/)
|
||||
assert.match(source, /AWAITING_REVIEW 不作为证据开放条件/)
|
||||
const gate = source.slice(source.indexOf('const taskResponse'), source.indexOf('const path ='))
|
||||
assert.doesNotMatch(gate, /loading\/evidence/)
|
||||
assert.match(source, /const path = `\/api\/platform\/inbounds\/\$\{inboundId\}\/loading\/evidence/)
|
||||
})
|
||||
@@ -13,6 +13,7 @@ class SupplierSqlContractTest {
|
||||
assertThat(stream).isNotNull();
|
||||
String sql = new String(stream.readAllBytes(), StandardCharsets.UTF_8);
|
||||
assertThat(sql).contains("CREATE TABLE IF NOT EXISTS wh_supplier", "tenant_id BIGINT UNSIGNED NOT NULL DEFAULT 0",
|
||||
"chk_wh_supplier_tenant CHECK (tenant_id = 0)",
|
||||
"category='BOOKING' AND scope IN ('DOMESTIC','INTERNATIONAL')", "license_file_id VARCHAR(128)",
|
||||
"MONTHLY_30','MONTHLY_45','MONTHLY_60','MONTHLY_90','PER_TRANSACTION','IMMEDIATE",
|
||||
"created_by BIGINT UNSIGNED", "updated_by BIGINT UNSIGNED",
|
||||
|
||||
@@ -2,6 +2,8 @@ package com.baiyue.warehouse.service;
|
||||
|
||||
import com.baiyue.common.core.exception.BizException;
|
||||
import com.baiyue.warehouse.dto.SupplierDtos.SaveRequest;
|
||||
import com.baiyue.warehouse.dto.SupplierDtos.PageQuery;
|
||||
import com.baiyue.warehouse.dto.SupplierDtos.StatusRequest;
|
||||
import com.baiyue.warehouse.entity.SupplierEntity;
|
||||
import com.baiyue.warehouse.repository.SupplierRepository;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -13,6 +15,7 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -30,20 +33,40 @@ class SupplierServiceTest {
|
||||
|
||||
@Test void createsPlatformPublicBookingSupplier() {
|
||||
when(repository.existsName(0L, "测试供应商", null)).thenReturn(false);
|
||||
service.create(booking);
|
||||
service.create(101L, booking);
|
||||
verify(repository).insert(any(SupplierEntity.class));
|
||||
}
|
||||
|
||||
@Test void rejectsScopeForNonBookingSupplier() {
|
||||
SaveRequest customs = new SaveRequest("报关供应商", "CUSTOMS", "DOMESTIC", "宁波", "法人", "联系人",
|
||||
"13800000000", null, null, null, null, "ACTIVE", "PER_TRANSACTION", null);
|
||||
assertThatThrownBy(() -> service.create(customs)).isInstanceOf(BizException.class)
|
||||
assertThatThrownBy(() -> service.create(101L, customs)).isInstanceOf(BizException.class)
|
||||
.hasMessageContaining("仅适用于订舱供应商");
|
||||
}
|
||||
|
||||
@Test void requiresScopeForBookingSupplier() {
|
||||
SaveRequest missingScope = new SaveRequest("订舱供应商", "BOOKING", null, "宁波", "法人", "联系人",
|
||||
"13800000000", null, null, null, null, "ACTIVE", "PER_TRANSACTION", null);
|
||||
assertThatThrownBy(() -> service.create(missingScope)).isInstanceOf(BizException.class);
|
||||
assertThatThrownBy(() -> service.create(101L, missingScope)).isInstanceOf(BizException.class);
|
||||
}
|
||||
|
||||
@Test void rejectsScopeFilterWithoutBookingCategory() {
|
||||
assertThatThrownBy(() -> service.page(new PageQuery(1, 20, "CUSTOMS", "DOMESTIC", null, null, null)))
|
||||
.isInstanceOf(BizException.class).hasMessageContaining("scope仅适用于订舱供应商");
|
||||
}
|
||||
|
||||
@Test void repeatedStatusChangeIsIdempotent() {
|
||||
SupplierEntity entity = new SupplierEntity(); entity.setId(101L); entity.setTenantId(0L); entity.setStatus("ACTIVE");
|
||||
when(repository.find(0L, 101L)).thenReturn(entity);
|
||||
service.changeStatus(101L, new StatusRequest("ACTIVE"));
|
||||
verify(repository, never()).save(any());
|
||||
}
|
||||
|
||||
@Test void validatesInternalSupplierSnapshot() {
|
||||
SupplierEntity entity = new SupplierEntity(); entity.setId(101L); entity.setTenantId(0L); entity.setName("测试供应商");
|
||||
entity.setCategory("BOOKING"); entity.setScope("DOMESTIC"); entity.setStatus("ACTIVE");
|
||||
when(repository.find(0L, 101L)).thenReturn(entity);
|
||||
var snapshot = service.internalSnapshot(101L, true, "BOOKING", "DOMESTIC");
|
||||
org.assertj.core.api.Assertions.assertThat(snapshot.supplierId()).isEqualTo(101L);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user