test: prepare measurement review fixtures without approval
This commit is contained in:
@@ -64,6 +64,8 @@ Admin TEST 入口必须通过显式环境文件配置 `ADMIN_TEST_FIXED_CUSTOMER
|
||||
|
||||
固定托盘造数中,`inbound-measurement.mjs` 只复用 `TP-001`、`YW-TP-002` 指定池中的现有托盘;一只可复用,不要求两只同时存在,两只均缺失才阻断,不自动选择池外托盘。仅明确设置内部 `allowAnyExistingPallet` 的通用场景可读取当前仓库已有资源;两者均不创建托盘。
|
||||
|
||||
待审页面验收可用总入口 `--modules inbound-measurement --prepare-measurement-review true`:只允许 TEST 单票及最小依赖,正式创建、测量并提交后停在 `MEASURE_PENDING/PENDING`,不调用审核或生成 WAIT_SPLIT 后续样本。报告 `fullAcceptance=false`、`preparationOnly=true`,业务身份在 `createdResources.measurementReviewUiFixture`;失败保留原数据和报告,不自动重跑或清理。默认完整测量链不受影响。
|
||||
|
||||
OCR模块必须通过`ADMIN_TEST_OCR_IMAGE`显式指定本轮图片,不依赖个人桌面路径;定向运行自动展开客户资质及订单前置。识别失败的空字段允许省略,但识别成功必须有有效重量与单位;人工修正和确认分别增加版本。合成称重测试图只证明上传、识别响应及人工确认协议,不代表现场称重照片或设备验收。费用项目模块按受控编码验证112条正式基线,合法扩展项目保留并单独核对分页和筛选。散板普通状态接口仅验证取消及非法派车拒绝,原单须出现在待匹配需求池;需求池接车到签收另列覆盖缺口,不以手工跳状态冒充履约。
|
||||
|
||||
预约工作查询在本轮业务写入后,仅对服务端明确返回的 A0409“预约批次或运输关联已变化,服务端正在协调完整工作清单”或“已开船工作范围变化,请先完成服务端同步”每 5 秒重读,最多等待 240 秒;超时保留失败,其他错误不重试。这是后台完整扫描的就绪等待,不是页面响应性能验收,也不触发同步写接口。
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import { readFileSync } from 'node:fs'
|
||||
import test from 'node:test'
|
||||
import { parseArguments, validateExecutionOptions } from '../admin-test-env-acceptance.mjs'
|
||||
import { completeDropshipPalletization, verifyMeasurementSubmitReplay,
|
||||
verifyMeasurementApprovalReplay } from './inbound-measurement.mjs'
|
||||
|
||||
@@ -11,6 +12,18 @@ const measurementTests = read('../../firstleg/src/test/java/com/baiyue/firstleg/
|
||||
const cartonTests = read('../../firstleg/src/test/java/com/baiyue/firstleg/service/CartonMeasurementServiceTest.java')
|
||||
const reviewTests = read('../../firstleg/src/test/java/com/baiyue/firstleg/service/MeasurementReviewServiceTest.java')
|
||||
|
||||
test('measurement review preparation is explicit and cannot continue downstream or bulk flows', () => {
|
||||
const args = ['--environment', 'test', '--gateway', 'https://test.invalid', '--username', 'fixture', '--password', 'fixture-only', '--modules', 'inbound-measurement', '--prepare-measurement-review', 'true']
|
||||
const options = parseArguments(args)
|
||||
assert.equal(options.prepareMeasurementReview, true)
|
||||
assert.doesNotThrow(() => validateExecutionOptions(options))
|
||||
assert.throws(() => parseArguments([...args.slice(0, -1), 'false']), /必须明确/)
|
||||
for (const change of [{ waitSplitCount: 2 }, { prepareDropshipManualCount: true }, { requestedModules: ['inbound-measurement', 'phase3-customs'] }]) {
|
||||
assert.throws(() => validateExecutionOptions({ ...options, ...change }), /待审准备/)
|
||||
}
|
||||
assert.equal(parseArguments(args.slice(0, -2)).prepareMeasurementReview, false)
|
||||
})
|
||||
|
||||
test('measurement acceptance scans the stable box code frozen by first print', () => {
|
||||
assert.match(source, /const boxCode = `\$\{inboundCode\}#\$\{originalPackageCount\}-1`/)
|
||||
assert.doesNotMatch(source, /#V\d+#/)
|
||||
|
||||
@@ -1313,6 +1313,21 @@ export async function run(context) {
|
||||
&& Number.isInteger(Number(pendingSummary?.version)),
|
||||
`status=${pendingSummary?.processStatus ?? 'missing'}, version=${pendingSummary?.version ?? 'missing'}`, OPTIONS)
|
||||
|
||||
if (context.options?.prepareMeasurementReview) {
|
||||
const ready = pendingSummary?.processStatus === 'MEASURE_PENDING'
|
||||
&& pendingSummary?.measureReviewStatus === 'PENDING'
|
||||
&& Number.isInteger(Number(pendingSummary?.version))
|
||||
context.createdResources.measurementReviewUiFixture = {
|
||||
marker: context.marker, inboundId, tenantId, inboundCode,
|
||||
measurementId: asId(draft.measurementId), expectedVersion: pendingSummary?.version,
|
||||
status: ready ? 'PREPARED_NOT_VERIFIED' : 'PREPARATION_FAILED', fullAcceptance: false,
|
||||
}
|
||||
context.assert(MODULE, '待审页面样本准备完成,未执行审核', pendingInboundResponse, ready,
|
||||
`inboundCode=${inboundCode}, measurementId=${asId(draft.measurementId)}`, OPTIONS)
|
||||
finishScenario(context, start)
|
||||
return
|
||||
}
|
||||
|
||||
const approvalPath = `/api/platform/v1/inbounds/${inboundId}/measurements/approve?${query(tenantId)}`
|
||||
const approvalPayload = {
|
||||
measurementId: draft.measurementId, expectedVersion: Number(pendingSummary?.version), reason: null,
|
||||
|
||||
Reference in New Issue
Block a user