优化
This commit is contained in:
+9
-1
@@ -6,7 +6,7 @@
|
||||
|---|---|---|---|
|
||||
| 平台后台全模块 HTTP 验收 | `scripts/admin-test-env-acceptance.mjs` | 会创建、更新或最终停用测试数据 | `--modules` 默认列表中的平台客户、仓储、订单、入库、分柜、装柜、船期、拖车、报关、财务、通知、统计等模块 |
|
||||
| 客户工作台完整 HTTP 链路验收 | `scripts/client-test-env-acceptance.mjs` | 会创建测试企业、订单、入库、权限和站内消息数据 | 注册/审核、客户隔离、订单、入库计费、文件、财务、客户侧权限,以及我的消息未读/已读/全部已读链路 |
|
||||
| Client 二期兼容 HTTP 验收 | `scripts/client-phase2-test-env-acceptance.mjs` | 会写入测试环境业务数据 | 二期客户入库、测量、费用和权限兼容场景;不是替代 Client 全量入口 |
|
||||
| Client 二期专项 HTTP 验收 | `scripts/client-phase2-test-env-acceptance.mjs` | 会写入测试环境业务数据 | 二期客户入库、测量、费用和权限专项场景;不是替代 Client 全量入口 |
|
||||
|
||||
执行前必须确认目标环境、账号和数据清理/停用策略,并获得当前对话的测试环境验收授权。`admin-test-env-modules/*contract.test.mjs` 只验证模块脚本结构,不能代替 HTTP 验收。
|
||||
|
||||
@@ -23,6 +23,14 @@
|
||||
| PDA 本地页面和状态测试 | `../apps/pda-uniapp/tests/*.test.mjs` |
|
||||
| 本地数据库 SQL 静态/受控验收 | `scripts/local-db-full-acceptance.ps1` |
|
||||
|
||||
Admin/Client HTTP 脚本的离线合同只验证脚本结构、参数和模块边界,不访问测试环境:
|
||||
|
||||
| 合同范围 | 入口 |
|
||||
|---|---|
|
||||
| Admin 订单、箱码、三期装柜/PDA、订舱、拖车、通知 | `scripts/admin-test-env-modules/*contract.test.mjs`;模块映射见 `scripts/admin-test-env-modules/README.md` |
|
||||
| Client 消息中心调用 | `scripts/client-notifications-contract.test.mjs` |
|
||||
| 验收入口与模块注册 | `scripts/full-regression-entry-contract.test.mjs`、`scripts/controller-pipeline-contract.test.mjs` |
|
||||
|
||||
## 后端全量回归
|
||||
|
||||
## 入口
|
||||
|
||||
@@ -45,7 +45,8 @@ export async function run(context) {
|
||||
| 商户资质与下单身份 | `merchant-qualification-fixture.mjs` | `merchant-qualification-fixture-contract.test.mjs` |
|
||||
| 订单创建、可计价主数据与审核异步收敛 | `orders.mjs` | `orders-pricing-fixture-contract.test.mjs`、`orders-approval-convergence-contract.test.mjs` |
|
||||
| 入库测量、首次打印冻结箱码与墨家扫码 | `inbound-measurement.mjs` | `inbound-measurement-box-code-contract.test.mjs` |
|
||||
| 三期柜次、装柜、PDA 与证据/出仓门禁 | `phase3-container-loading.mjs`、`phase3-loading.mjs`、`phase3-pda-convergence.mjs`、`phase3-evidence-gate.mjs`、`phase3-loading-finalize.mjs`、`phase3-outbound-dispatch.mjs` | `phase3-producer-chain-contract.test.mjs`、`manual-state-loading-pda-contract.test.mjs` |
|
||||
| 三期柜次概览、装柜、PDA 与证据/出仓门禁 | `phase3-container-loading.mjs`、`phase3-container-overview.mjs`、`phase3-loading.mjs`、`phase3-pda-convergence.mjs`、`phase3-evidence-gate.mjs`、`phase3-loading-finalize.mjs`、`phase3-outbound-dispatch.mjs` | `phase3-container-regression-contract.test.mjs`、`phase3-producer-chain-contract.test.mjs`、`manual-state-loading-pda-contract.test.mjs` |
|
||||
| 分柜与父子入库单数量守恒 | `phase3-order-splitting.mjs` | `phase3-order-splitting-contract.test.mjs` |
|
||||
| 订舱共享主数据前置与订舱验收 | `ocean-booking-fixture.mjs`、`ocean-bookings.mjs`、`phase3-port-schedules.mjs`、`phase3-carrier-schedule-queries.mjs` | `ocean-booking-fixture-contract.test.mjs`、`phase3-carrier-schedule-queries.test.mjs` |
|
||||
| 拖车预约 | `truck-appointments.mjs` | `truck-appointments-contract.test.mjs` |
|
||||
| 消息中心管理 | `notifications.mjs` | `notifications-contract.test.mjs` |
|
||||
|
||||
@@ -6,9 +6,7 @@ function id(value) { return value == null ? '' : String(value) }
|
||||
|
||||
export function controlledPhotoDownload(downloadPath, response) {
|
||||
const controlledPath = typeof downloadPath === 'string'
|
||||
&& downloadPath.startsWith('/api/')
|
||||
&& !downloadPath.startsWith('//')
|
||||
&& !downloadPath.includes('://')
|
||||
&& /^\/api\/platform\/v1\/containers\/[1-9]\d*\/pda\/photos\/[1-9]\d*\/download$/.test(downloadPath)
|
||||
const contentType = String(response?.contentType || '').toLowerCase()
|
||||
return controlledPath
|
||||
&& response?.http === 200
|
||||
|
||||
@@ -17,6 +17,7 @@ const truckAttachmentDialog = read(`${adminRoot}trucking/components/TruckAttachm
|
||||
const truckList = read(`${adminRoot}trucking/pages/TruckAppointmentsView.vue`)
|
||||
const truckForm = read(`${adminRoot}trucking/components/TruckAppointmentForm.vue`)
|
||||
const containerList = read(`${adminRoot}container-loading/pages/ContainersView.vue`)
|
||||
const containerOverviewPanel = read(`${adminRoot}container-loading/components/ContainerOverviewPanel.vue`)
|
||||
const containerLoadingAcceptance = read('phase3-container-loading.mjs')
|
||||
const truckAcceptance = read('truck-appointments.mjs')
|
||||
const matrix = read('../../../docs/三期/货柜管理全链验收矩阵-2026-08-13.md')
|
||||
@@ -41,23 +42,27 @@ test('overview regression requires workflowStatus and distinguishes 100 percent
|
||||
test('every overview photo uses its server-provided controlled downloadPath', () => {
|
||||
assert.match(overviewOpenApi, /\/api\/platform\/v1\/containers\/\{id\}\/pda\/photos\/\{fileId\}\/download/)
|
||||
assert.match(overviewAcceptance, /context\.requestBinary\('GET', downloadPath\)/)
|
||||
assert.equal(controlledPhotoDownload('/api/platform/v1/files/1', {
|
||||
assert.equal(controlledPhotoDownload('/api/platform/v1/containers/7/pda/photos/23/download', {
|
||||
http: 200, bytes: new Uint8Array([1]), contentType: 'image/png',
|
||||
}), true)
|
||||
for (const [path, response] of [
|
||||
['https://example.test/file', { http: 200, bytes: new Uint8Array([1]), contentType: 'image/png' }],
|
||||
['/api/platform/v1/files/1', { http: 200, bytes: new Uint8Array([1]), contentType: 'application/json' }],
|
||||
['/api/platform/v1/files/1', { http: 404, bytes: new Uint8Array(), contentType: 'image/png' }],
|
||||
['/api/platform/v1/files/loading-evidence/21/22/23', { http: 200, bytes: new Uint8Array([1]), contentType: 'image/png' }],
|
||||
['/api/platform/v1/containers/7/pda/photos/23/download', { http: 200, bytes: new Uint8Array([1]), contentType: 'application/json' }],
|
||||
['/api/platform/v1/containers/7/pda/photos/23/download', { http: 404, bytes: new Uint8Array(), contentType: 'image/png' }],
|
||||
]) assert.equal(controlledPhotoDownload(path, response), false)
|
||||
})
|
||||
|
||||
test('truck attachment API is frozen while Admin add-reference entry remains blocked', () => {
|
||||
test('truck attachment API and Admin upload-reference-delete flow are frozen', () => {
|
||||
assert.match(truckApi, /referenceTruckAppointmentAttachment/)
|
||||
assert.match(truckApi, /uploadTruckAppointmentAttachment/)
|
||||
assert.match(truckApi, /deleteTruckAppointmentAttachment/)
|
||||
assert.doesNotMatch(truckAttachmentDialog, /referenceTruckAppointmentAttachment/)
|
||||
assert.match(truckAttachmentDialog, /uploadTruckAppointmentAttachment/)
|
||||
assert.match(truckAttachmentDialog, /上传并关联/)
|
||||
assert.match(truckAttachmentDialog, /confirmButtonText: '确认', cancelButtonText: '取消'/)
|
||||
assert.match(truckAcceptance, /删除后回查拖车预约附件列表/)
|
||||
assert.match(truckAcceptance, /!remainingAttachments\.some/)
|
||||
assert.match(matrix, /拖车附件新增入口缺失[\s\S]*BLOCKED_CONTRACT/)
|
||||
assert.match(matrix, /拖车附件闭环[\s\S]*`LANDED`/)
|
||||
})
|
||||
|
||||
test('existing container number replacement keeps container plan and PDA identities stable', () => {
|
||||
@@ -78,6 +83,10 @@ test('customer public display uses tenantName without a legalName fallback', ()
|
||||
assert.match(matrix, /客户公开名称一致性[\s\S]*已统一 `tenantName`[\s\S]*`LANDED`/)
|
||||
})
|
||||
|
||||
test('Chinese status dialogs and 390px layout remain explicit Admin contract blockers', () => {
|
||||
assert.match(matrix, /中文状态、弹框与 390px 布局[\s\S]*BLOCKED_CONTRACT/)
|
||||
test('Chinese status dialogs and 390px layout are landed', () => {
|
||||
assert.match(releaseView, /确认放舱/)
|
||||
assert.match(containerOverviewPanel, /AWAITING_REVIEW: '待人工复核'/)
|
||||
assert.match(containerOverviewPanel, /PHOTO_STEP_EMPTY_CONTAINER: '空柜照片'/)
|
||||
assert.match(matrix, /中文状态、弹框与 390px 布局[\s\S]*`LANDED`/)
|
||||
assert.doesNotMatch(matrix, /拖车附件新增入口缺失|中文状态、弹框与 390px 布局[^\n]*BLOCKED_CONTRACT/)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user