Files
goauto/web/tests/unit/syb-inner-code-apply-selection.test.cjs
T

78 lines
4.8 KiB
JavaScript

const { test } = require('node:test')
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const source = fs.readFileSync(path.join(__dirname, '../../src/views/goauto/syb-inner-codes/index.vue'), 'utf8').split('<script>')[1].split('</script>')[0].replace(/^import .*$/gm, '').replace('export default', 'return')
function instance(preview = async ids => ({ data: { records: ids.length, inboundCodes: ids.length, blocked: [] } }), apply = async body => ({ data: { batchId: 'mock-batch', queued: body.ids.length } })) {
const previews = []; const writes = []
const options = new Function('previewSybInnerCodeApply', 'applySybInnerCodes', 'createRequestId', 'ElMessage', source)(async ids => { previews.push(ids); return preview(ids) }, async body => { writes.push(body); return apply(body) }, () => 'mock-request', { success() {} })
const vm = { ...options.data(), ...options.methods, load: async () => {}, startPolling() {} }
for (const [key, get] of Object.entries(options.computed)) Object.defineProperty(vm, key, { get: () => get.call(vm) })
vm.items = ['updated', 'ready', 'failed', 'ready'].map((status, i) => ({ id: i + 1, status }))
return { vm, previews, writes }
}
test('mixed selection only previews and submits frozen current-page ready IDs', async () => {
const { vm, previews, writes } = instance()
vm.selected = [...vm.items, vm.items[1], { id: 999, status: 'ready' }]
assert.equal(vm.applyEligibleCount, 2)
await vm.openApply()
assert.deepEqual(previews, [[2, 4]])
assert.equal(vm.applyDialog.selectedCount, 4)
assert.equal(vm.applyDialog.ready, true)
vm.selected = [{ id: 123, status: 'ready' }]; vm.items = vm.selected
await vm.confirmApply()
assert.deepEqual(writes[0].ids, [2, 4]); assert.equal(writes.length, 1)
assert.equal(vm.applyDialog.open, false)
})
test('blocked preview candidates are removed and metrics reloaded for remaining IDs', async () => {
const { vm, previews, writes } = instance(async ids => ({ data: { records: ids.length, inboundCodes: ids.length === 2 ? 7 : 3, blocked: ids.length === 2 ? [{ id: 4, status: 'updated' }] : [] } }))
vm.selected = vm.items
await vm.openApply()
assert.deepEqual(previews, [[2, 4], [2]])
assert.deepEqual(vm.applyDialog.ids, [2]); assert.equal(vm.applyDialog.preview.inboundCodes, 3)
assert.equal(vm.applyDialog.selectedCount - vm.applyDialog.ids.length, 3)
await vm.confirmApply(); assert.deepEqual(writes[0].ids, [2])
})
test('all blocked candidates or preview failures cannot submit', async () => {
for (const preview of [async ids => ({ data: { records: ids.length, blocked: ids.map(id => ({ id })) } }), async () => { throw new Error('mock network error') }, async () => ({ data: { records: 999, blocked: [] } })]) {
const { vm, writes } = instance(preview); vm.selected = vm.items
await vm.openApply(); assert.equal(vm.applyDialog.ready, false); assert.ok(vm.applyDialog.error)
await vm.confirmApply(); assert.equal(writes.length, 0)
}
})
test('zero eligible, loading, error, busy and active matching do not preview', async () => {
const empty = instance(); await empty.vm.openApply(); assert.equal(empty.previews.length, 0)
for (const field of ['loading', 'loadError', 'busy', 'importing', 'matchSubmitting']) {
const { vm, previews } = instance(); vm.selected = vm.items; vm[field] = field === 'loadError' ? 'mock' : true
await vm.openApply(); assert.equal(previews.length, 0)
}
})
test('canceled preview cannot authorize a later dialog and double clicks do not submit twice', async () => {
let resolvePreview
const { vm, writes } = instance(() => new Promise(resolve => { resolvePreview = resolve }))
vm.selected = vm.items; const pending = vm.openApply(); const original = vm.applyDialog
original.open = false; vm.applyDialog = { ...original, ready: false }
resolvePreview({ data: { records: 2, blocked: [] } }); await pending
assert.equal(vm.applyDialog.ready, false); await vm.confirmApply(); assert.equal(writes.length, 0)
let resolveApply
const running = instance(undefined, () => new Promise(resolve => { resolveApply = resolve }))
running.vm.selected = running.vm.items; await running.vm.openApply()
const submit = running.vm.confirmApply(); await running.vm.confirmApply()
assert.equal(running.writes.length, 1)
resolveApply({ data: { batchId: 'mock-batch', queued: 2 } }); await submit
})
test('submission conflict or unknown result disables retry without changing selection', async () => {
const { vm, writes } = instance(undefined, async () => { throw new Error('mock unknown result') })
vm.selected = vm.items; await vm.openApply(); await vm.confirmApply(); await vm.confirmApply()
assert.equal(writes.length, 1); assert.equal(vm.applyDialog.ready, false); assert.ok(vm.applyDialog.error)
assert.equal(vm.busy, false); assert.equal(vm.applyDialog.saving, false); assert.equal(vm.selected.length, 4)
})