优化
This commit is contained in:
@@ -65,14 +65,14 @@ function viewHarness({ createPage = false, detailPage = false, api = {}, storage
|
||||
const route = vue.reactive({ params: { orderNo: detailPage ? 'PO-1' : '' } })
|
||||
const auth = vue.reactive({ token: 'identity-A', user: { tenantName: 'Company' }, profile: { tenantName: 'Company' }, hasPermission: () => true })
|
||||
const pushes = [], dispose = []
|
||||
const defaults = { listProcurements: async () => ({ records: [], total: 0 }), getProcurement: async orderNo => ({ order: { orderNo } }), createProcurement: async () => ({ order: { orderNo: 'PO-CREATED' } }) }
|
||||
const defaults = { getProcurementWorkflow: async orderNo => ({ orderNo, version: 1, status: 'WAIT_CUSTOMER_CONFIRM', receipts: [], outbounds: [] }), confirmProcurement: async () => ({ orderNo: 'PO-1', version: 2, status: 'CONFIRMED' }), listProcurements: async () => ({ records: [], total: 0 }), getProcurement: async orderNo => ({ order: { orderNo } }), createProcurement: async () => ({ order: { orderNo: 'PO-CREATED' } }) }
|
||||
const { descriptor } = parse(readFileSync(new URL('./views/ProcurementView.vue', import.meta.url), 'utf8'))
|
||||
const source = compileScript(descriptor, { id: 'procurement-test' }).content
|
||||
const context = { exports: {}, Error, crypto, sessionStorage: { getItem: key => storage.get(key) || null, setItem: (key, value) => storage.set(key, value), removeItem: key => storage.delete(key) },
|
||||
require(name) {
|
||||
if (name === 'vue') return { ...vue, onBeforeUnmount: callback => dispose.push(callback), watch: (...args) => { const stop = vue.watch(...args); dispose.push(stop); return stop } }
|
||||
if (name === 'vue-router') return { useRoute: () => route, useRouter: () => ({ push: async target => pushes.push(target) }) }
|
||||
if (name === 'element-plus') return { ElMessage: { success: () => {} } }
|
||||
if (name === 'element-plus') return { ElMessage: { success: () => {} }, ElMessageBox: { confirm: async () => {} } }
|
||||
if (name === '@/api/types') return { ApiError }
|
||||
if (name === '@/api/session') return { accessTokenIdentity: token => token }
|
||||
if (name === '@/modules/auth/public') return { useAuthStore: () => auth }
|
||||
@@ -160,12 +160,60 @@ test('domestic purchase creates an export order and displays the actual origin a
|
||||
const payload = presentation.buildProcurementCreate({ ...draft(), procurementDirection: 'DOMESTIC_TO_OVERSEAS', receivingAddress: 'US, CA, Los Angeles, test destination' }, 'Authenticated Company', 'export-key')
|
||||
assert.equal(payload.procurementDirection, 'DOMESTIC_TO_OVERSEAS')
|
||||
assert.equal(payload.receivingAddress, 'US, CA, Los Angeles, test destination')
|
||||
assert.equal(presentation.statusLabel('WAIT_OVERSEAS_RECEIPT', payload.procurementDirection), '待国内到仓')
|
||||
assert.equal(presentation.statusLabel('DOMESTIC_RECEIVING', payload.procurementDirection), '海外收货中')
|
||||
assert.equal(presentation.statusLabel('WAIT_CHARGES', payload.procurementDirection), '待海外核费')
|
||||
assert.equal(presentation.statusLabel('WAIT_OVERSEAS_RECEIPT'), '待海外到仓')
|
||||
assert.equal(presentation.statusLabel('RECEIVING', payload.procurementDirection), '收货中')
|
||||
assert.equal(presentation.statusLabel('DELIVERING', payload.procurementDirection), '派送中')
|
||||
assert.equal(presentation.statusLabel('WAIT_CUSTOMER_CONFIRM', payload.procurementDirection), '待客户确认')
|
||||
assert.equal(presentation.statusLabel('COMPLETED'), '签收完成')
|
||||
assert.throws(() => presentation.buildProcurementCreate({ ...draft(), procurementDirection: 'INVALID' }, 'Company', 'key'), /采购方向/)
|
||||
const source = readFileSync(new URL('./views/ProcurementView.vue', import.meta.url), 'utf8')
|
||||
assert.match(source, /v-model="form.procurementDirection"/)
|
||||
assert.match(source, /regionText\('最终国内收件资料', form.procurementDirection\)/)
|
||||
})
|
||||
|
||||
|
||||
test('customer confirms with current workflow version and double-click only sends once', async () => {
|
||||
let resolve, calls = []
|
||||
const harness = viewHarness({ detailPage: true, api: { confirmProcurement: (orderNo, payload) => {
|
||||
calls.push({ orderNo, ...payload }); return new Promise(done => { resolve = done })
|
||||
} } })
|
||||
try {
|
||||
await flush()
|
||||
const first = harness.state.confirmReceived(); await flush(); await harness.state.confirmReceived()
|
||||
assert.equal(calls.length, 1); assert.equal(calls[0].version, 1); assert.equal(calls[0].orderNo, 'PO-1')
|
||||
assert.ok(calls[0].idempotencyKey)
|
||||
resolve({ orderNo: 'PO-1', version: 2, status: 'CONFIRMED' }); await first
|
||||
assert.equal(harness.state.workflow.value.status, 'CONFIRMED'); assert.equal(harness.state.canConfirm.value, false)
|
||||
} finally { harness.dispose() }
|
||||
})
|
||||
|
||||
test('failed customer confirmation preserves receipt context for recovery', async () => {
|
||||
const harness = viewHarness({ detailPage: true, api: { confirmProcurement: async () => { throw new ApiError('版本已更新,请刷新', 'A0409') } } })
|
||||
try {
|
||||
await flush(); await harness.state.confirmReceived()
|
||||
assert.equal(harness.state.workflow.value.status, 'WAIT_CUSTOMER_CONFIRM')
|
||||
assert.equal(harness.state.confirming.value, false); assert.equal(harness.state.confirmError.value, '版本已更新,请刷新')
|
||||
} finally { harness.dispose() }
|
||||
})
|
||||
|
||||
|
||||
test('unknown create and confirmation results reuse idempotency keys for unchanged retries', async () => {
|
||||
const creates = [], confirms = []
|
||||
const create = viewHarness({ createPage: true, api: { createProcurement: async payload => { creates.push(payload); throw new ApiError('timeout', 'TIMEOUT') } } })
|
||||
const confirm = viewHarness({ detailPage: true, api: { confirmProcurement: async (_, payload) => { confirms.push(payload); throw new ApiError('timeout', 'TIMEOUT') } } })
|
||||
try {
|
||||
Object.assign(create.state.form, draft()); await create.state.submit(); await create.state.submit()
|
||||
assert.equal(creates[0].idempotencyKey, creates[1].idempotencyKey)
|
||||
await flush(); await confirm.state.confirmReceived(); await confirm.state.confirmReceived()
|
||||
assert.equal(confirms[0].idempotencyKey, confirms[1].idempotencyKey)
|
||||
} finally { create.dispose(); confirm.dispose() }
|
||||
})
|
||||
|
||||
|
||||
test('bill-settled manual fees show review results without counting a balance debit', () => {
|
||||
const bill = determination => ({ ...fee('OTHER', 'NOT_REQUIRED', '100'), determination })
|
||||
assert.equal(presentation.feeStatus(bill('PENDING')), '账单结算 · 待审核')
|
||||
assert.equal(presentation.feeStatus(bill('APPROVED')), '账单结算 · 已确认')
|
||||
assert.equal(presentation.feeStatus(bill('REJECTED')), '账单结算 · 已拒绝')
|
||||
assert.equal(presentation.feeTone(bill('REJECTED')), 'danger')
|
||||
assert.equal(presentation.feeTotals([bill('PENDING'), bill('APPROVED'), bill('REJECTED')]).paid, '0.00')
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user