89 lines
4.4 KiB
JavaScript
89 lines
4.4 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
import { readFileSync } from 'node:fs'
|
|
import ts from 'typescript'
|
|
import * as vue from 'vue'
|
|
import dayjs from 'dayjs'
|
|
|
|
function harness(t) {
|
|
const source = readFileSync(new URL('./views/DeliveryOrdersView.vue', import.meta.url), 'utf8')
|
|
.match(/<script setup lang="ts">([\s\S]*?)<\/script>/)[1]
|
|
const code = ts.transpileModule(source + '\nexport { filters, queryFields, tableColumns, page, pageSize, search, reset, loadOrders, records, total, loading, errorMessage }', {
|
|
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, esModuleInterop: true },
|
|
}).outputText
|
|
const calls = [], mounted = []
|
|
const dependencies = {
|
|
vue: { ...vue, onMounted: callback => mounted.push(callback) }, dayjs,
|
|
'vue-router': { useRouter: () => ({ push() {} }) },
|
|
'@/modules/auth/public': { useAuthStore: () => ({ hasPermission: () => true }) },
|
|
'../api/deliveryOrders': { listDeliveryOrders: query => new Promise((resolve, reject) => calls.push({ query, resolve, reject })) },
|
|
}
|
|
const scope = vue.effectScope(), view = {}
|
|
scope.run(() => new Function('require', 'exports', code)(id => {
|
|
assert.ok(id in dependencies, id)
|
|
return dependencies[id]
|
|
}, view))
|
|
t.after(() => scope.stop())
|
|
return { view, calls, mount: () => mounted.forEach(fn => fn()) }
|
|
}
|
|
const result = name => ({ records: [{ deliveryNo: name }], total: 1 })
|
|
|
|
test('formal delivery filters submit exact values and format each known method in Chinese', async t => {
|
|
const { view, calls } = harness(t)
|
|
const expected = { FBA_PICKUP: 'FBA 自提', CUSTOMER_PICKUP: '客户自提', TRUCK_PALLET: '卡派打托', TRUCK_FLOOR: '卡派地板', EXPRESS: '快递', OUTSOURCED: '外配', DEDICATED_TRUCK: '专车直送', LTL: '零担派送', TRUCK: '卡车派送' }
|
|
const options = view.queryFields.find(f => f.key === 'deliveryMethod').options
|
|
assert.deepEqual(Object.fromEntries(options.map(o => [o.value, o.label])), expected)
|
|
const column = view.tableColumns.find(c => c.prop === 'deliveryMethod')
|
|
for (const [value, label] of Object.entries(expected)) {
|
|
view.filters.deliveryMethod = value
|
|
const pending = view.loadOrders()
|
|
assert.equal(calls.at(-1).query.deliveryMethod, value)
|
|
calls.at(-1).resolve(result(value)); await pending
|
|
assert.equal(column.formatter({}, {}, value), label)
|
|
}
|
|
assert.equal(column.formatter({}, {}, null), '—')
|
|
})
|
|
|
|
test('newest result survives older success and older failure', async t => {
|
|
for (const oldFailure of [false, true]) {
|
|
const { view, calls } = harness(t)
|
|
view.filters.documentNo = 'old'; const old = view.loadOrders()
|
|
view.filters.documentNo = 'new'; const current = view.loadOrders()
|
|
calls[1].resolve(result('new')); await current
|
|
if (oldFailure) calls[0].reject(new Error('old failed'))
|
|
else calls[0].resolve(result('old'))
|
|
await old
|
|
assert.equal(view.records.value[0].deliveryNo, 'new')
|
|
assert.equal(view.errorMessage.value, '')
|
|
assert.equal(view.total.value, 1)
|
|
assert.equal(calls.length, 2)
|
|
}
|
|
})
|
|
|
|
test('older completion cannot clear current loading; current failure can be retried', async t => {
|
|
const { view, calls } = harness(t)
|
|
const old = view.loadOrders(), current = view.loadOrders()
|
|
calls[0].resolve(result('old')); await old
|
|
assert.equal(view.loading.value, true)
|
|
assert.equal(view.records.value.length, 0)
|
|
calls[1].reject(new Error('current failed')); await current
|
|
assert.equal(view.loading.value, false)
|
|
assert.equal(view.errorMessage.value, 'current failed')
|
|
const retry = view.loadOrders(); calls[2].resolve(result('retry')); await retry
|
|
assert.equal(view.records.value[0].deliveryNo, 'retry')
|
|
assert.equal(view.errorMessage.value, '')
|
|
})
|
|
|
|
test('mount, search from later page, page-size change and reset each issue one request', async t => {
|
|
const { view, calls, mount } = harness(t)
|
|
mount(); await vue.nextTick(); assert.equal(calls.length, 1)
|
|
view.page.value = 3; await vue.nextTick(); assert.equal(calls.length, 2)
|
|
view.search(); await vue.nextTick(); assert.equal(calls.length, 3)
|
|
assert.equal(calls[2].query.page, 1)
|
|
view.page.value = 4; await vue.nextTick(); assert.equal(calls.length, 4)
|
|
view.pageSize.value = 50; await vue.nextTick(); assert.equal(calls.length, 5)
|
|
assert.equal(calls[4].query.page, 1); assert.equal(calls[4].query.size, 50)
|
|
view.reset(); await vue.nextTick(); assert.equal(calls.length, 6)
|
|
calls.forEach(call => call.resolve(result('resolved')))
|
|
})
|