This commit is contained in:
2026-10-29 13:37:28 +08:00
parent 57be5316d0
commit f51e51d50f
12 changed files with 133 additions and 40 deletions
+26 -1
View File
@@ -72,10 +72,11 @@ function viewHarness({ createPage = false, detailPage = false, api = {}, storage
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: () => {} }, ElMessageBox: { confirm: async () => {} } }
if (name === 'element-plus') return { ElMessage: { success: () => {} }, ElMessageBox: { confirm: async () => {}, prompt: async (...args) => { const value = api.rejectionReason ?? '照片不清晰'; const valid = args[2].inputValidator(value); if (valid !== true) throw new Error(valid); return { value } } } }
if (name === '@/api/types') return { ApiError }
if (name === '@/api/session') return { accessTokenIdentity: token => token }
if (name === '@/modules/auth/public') return { useAuthStore: () => auth }
if (name === '../api/orderBudgets') return { requireOrderBudget: api.requireOrderBudget || (async () => {}) }
if (name === '../api/procurement') return { ...defaults, ...api }
if (name === '../procurementPresentation') return presentation
if (name === '../procurementSubmission') return submission
@@ -265,3 +266,27 @@ test('bill-settled manual fees show review results without counting a balance de
assert.equal(presentation.feeTone(bill('REJECTED')), 'danger')
assert.equal(presentation.feeTotals([bill('PENDING'), bill('APPROVED'), bill('REJECTED')]).paid, '0.00')
})
test('insufficient balance and credit blocks procurement creation and preserves the draft', async () => {
let creates = 0
const harness = viewHarness({ createPage: true, api: { requireOrderBudget: async () => { throw new Error('余额及授信不足') }, createProcurement: async () => { creates++ } } })
try {
Object.assign(harness.state.form, draft()); await harness.state.submit()
assert.equal(creates, 0); assert.equal(harness.state.submitError.value, '余额及授信不足')
assert.equal(harness.state.form.productName, draft().productName)
} finally { harness.dispose() }
})
test('customer rejection requires a reason and carries current order version', async () => {
const calls = []
const harness = viewHarness({ detailPage: true, api: { rejectProcurement: async (orderNo, command) => { calls.push({ orderNo, ...command }); return { orderNo, status: 'RECEIVING', version: 2, rejectionReason: command.reason } } } })
try {
await flush(); await harness.state.rejectReceived()
assert.equal(calls.length, 1); assert.equal(calls[0].orderNo, 'PO-1'); assert.equal(calls[0].version, 1)
assert.equal(calls[0].reason, '照片不清晰'); assert.equal(harness.state.workflow.value.status, 'RECEIVING')
} finally { harness.dispose() }
const blank = viewHarness({ detailPage: true, api: { rejectionReason: ' ', rejectProcurement: async () => { throw new Error('不得发送空原因') } } })
try { await flush(); await blank.state.rejectReceived(); assert.match(blank.state.confirmError.value, /请填写驳回原因/) }
finally { blank.dispose() }
})