优化
This commit is contained in:
@@ -41,7 +41,7 @@ export async function verifyWorkbench(read, customerId) {
|
||||
const checks = []
|
||||
const check = (name, ok) => { requireFact(ok, name); checks.push({ name, passed: true }) }
|
||||
async function all(path, workbench = false, params = {}) {
|
||||
let rows = [], expected = null, first
|
||||
let rows = [], progress = [], expected = null, first
|
||||
for (let number = 1; ; number++) {
|
||||
const query = new URLSearchParams({ ...params, page: String(number), size: '200' })
|
||||
const response = await read(`${path}?${query}`)
|
||||
@@ -49,31 +49,44 @@ export async function verifyWorkbench(read, customerId) {
|
||||
if (number === 1) { expected = Number(page.total); first = response }
|
||||
requireFact(Number(page.total) === expected, 'Dataset changed while paging; rerun in a stable window')
|
||||
requireFact(page.records.every(row => String(row.tenantId) === String(customerId)), 'Customer scope mismatch')
|
||||
if (workbench) {
|
||||
requireFact(Array.isArray(response.progress) && response.progress.length === page.records.length
|
||||
&& new Set(response.progress.map(p => String(p.orderId))).size === page.records.length
|
||||
&& response.progress.every(p => page.records.some(r => String(r.orderId) === String(p.orderId))
|
||||
&& ['none','loaded','declared','cleared','scheduled','delivering','delivered'].includes(p.stage)
|
||||
&& typeof p.partial === 'boolean'), 'Invalid progress coverage')
|
||||
progress.push(...response.progress)
|
||||
}
|
||||
rows.push(...page.records)
|
||||
if (number >= Number(page.pages)) break
|
||||
requireFact(number < 1000, 'Pagination safety bound exceeded')
|
||||
}
|
||||
requireFact(rows.length === expected && new Set(ids(rows)).size === expected, 'Duplicate or missing orders across pages')
|
||||
return { rows, first }
|
||||
return { rows, first, progress }
|
||||
}
|
||||
const workbench = await all(endpoint, true)
|
||||
check('sample actually exceeds the former 200-order limit', workbench.rows.length > 200)
|
||||
const formal = await all('/merchant/v1/orders')
|
||||
check('all formal orders match the independent unified query', equalIds(workbench.rows.filter(r => r.mainStatus !== 'DRAFT'), formal.rows))
|
||||
const queues = workbench.first.queues
|
||||
for (const name of ['all', 'fee', 'customs', 'draft']) {
|
||||
for (const name of ['all', 'fee', 'customs', 'draft', 'loaded', 'declared', 'cleared', 'scheduled', 'delivering', 'delivered']) {
|
||||
check(`queue ${name} has a valid count`, Number.isSafeInteger(Number(queues?.[name])) && Number(queues[name]) >= 0)
|
||||
}
|
||||
check('all queue count matches complete rows', Number(queues.all) === workbench.rows.length)
|
||||
check('fee count matches authoritative confirmation flags', Number(queues.fee) === workbench.rows.filter(r => r.customerFeeConfirmationRequired === true).length)
|
||||
check('draft count matches draft rows', Number(queues.draft) === workbench.rows.filter(r => r.mainStatus === 'DRAFT').length)
|
||||
for (const queue of ['fee', 'customs', 'draft']) {
|
||||
for (const queue of ['fee', 'customs', 'draft', 'loaded', 'declared', 'cleared', 'scheduled', 'delivering', 'delivered']) {
|
||||
const selected = await all(endpoint, true, { queue })
|
||||
check(`${queue} complete page count`, selected.rows.length === Number(queues[queue]))
|
||||
const own = new Set(ids(workbench.rows))
|
||||
check(`${queue} contains only listed customer orders`, ids(selected.rows).every(id => own.has(id)))
|
||||
if (queue === 'fee') check('fee queue exact membership', equalIds(selected.rows, workbench.rows.filter(r => r.customerFeeConfirmationRequired === true)))
|
||||
if (queue === 'draft') check('draft queue exact membership', equalIds(selected.rows, workbench.rows.filter(r => r.mainStatus === 'DRAFT')))
|
||||
if (['loaded','declared','cleared','scheduled','delivering','delivered'].includes(queue)) {
|
||||
const expectedIds = new Set(workbench.progress.filter(p => p.stage === queue).map(p => String(p.orderId)))
|
||||
check(`${queue} progress exact membership`, selected.rows.length === expectedIds.size && ids(selected.rows).every(id => expectedIds.has(id)))
|
||||
check(`${queue} selected progress agrees`, selected.progress.every(p => p.stage === queue))
|
||||
}
|
||||
}
|
||||
for (const [page, size] of [[21, 10], [2, 50]]) {
|
||||
const result = await read(`${endpoint}?page=${page}&size=${size}`)
|
||||
|
||||
@@ -25,8 +25,10 @@ function fixture() {
|
||||
mainStatus: i < 3 ? 'DRAFT' : 'LOADED', customerFeeConfirmationRequired: i >= 10 && i < 12,
|
||||
channelName: i % 2 ? 'SEA' : 'AIR' }))
|
||||
const calls = []
|
||||
const stages = ['loaded','declared','cleared','scheduled','delivering','delivered']
|
||||
const stage = row => row.mainStatus === 'DRAFT' ? 'none' : stages[Number(row.orderId) % stages.length]
|
||||
const queues = list => ({ all: list.length, fee: list.filter(r => r.customerFeeConfirmationRequired).length,
|
||||
customs: list.filter(r => r.orderId === '1012').length, draft: list.filter(r => r.mainStatus === 'DRAFT').length })
|
||||
customs: list.filter(r => r.orderId === '1012').length, draft: list.filter(r => r.mainStatus === 'DRAFT').length, ...Object.fromEntries(stages.map(key => [key, list.filter(r => stage(r) === key).length])) })
|
||||
function read(path) {
|
||||
calls.push(path)
|
||||
const url = new URL(path, 'https://test.invalid'), q = url.searchParams
|
||||
@@ -36,9 +38,10 @@ function fixture() {
|
||||
if (q.get('queue') === 'fee') selected = selected.filter(r => r.customerFeeConfirmationRequired)
|
||||
if (q.get('queue') === 'customs') selected = selected.filter(r => r.orderId === '1012')
|
||||
if (q.get('queue') === 'draft') selected = selected.filter(r => r.mainStatus === 'DRAFT')
|
||||
if (stages.includes(q.get('queue'))) selected = selected.filter(r => stage(r) === q.get('queue'))
|
||||
const number = Number(q.get('page')), size = Number(q.get('size'))
|
||||
const page = { page: number, size, total: selected.length, pages: Math.ceil(selected.length / size), records: selected.slice((number - 1) * size, number * size).map(r => ({ ...r })) }
|
||||
return url.pathname.endsWith('/workbench') ? { page, queues: counts, channelNames: ['AIR', 'SEA'] } : page
|
||||
return url.pathname.endsWith('/workbench') ? { page, queues: counts, channelNames: ['AIR', 'SEA'], progress: page.records.map(row => ({ orderId: row.orderId, stage: stage(row), partial: false })) } : page
|
||||
}
|
||||
return { read, calls, rows }
|
||||
}
|
||||
@@ -55,6 +58,8 @@ for (const [name, mutate, expected] of [
|
||||
['customer leakage', r => { (r.page ?? r).records[0].tenantId = '22' }, /Customer scope/],
|
||||
['duplicate identity', r => { const p = r.page ?? r; if (p.records.length > 1) p.records[1] = p.records[0] }, /duplicate/],
|
||||
['partial response', r => { (r.page ?? r).records.pop() }, /Truncated/],
|
||||
['missing progress', r => { if (r.queues) delete r.progress }, /progress coverage/],
|
||||
['wrong clearing count', r => { if (r.queues) r.queues.cleared = 99 }, /cleared complete page count/],
|
||||
['wrong fee count', r => { if (r.queues) r.queues.fee = 99 }, /fee count/],
|
||||
['wrong draft count', r => { if (r.queues) r.queues.draft = 0 }, /draft count/],
|
||||
['missing channel option', r => { if (r.queues) r.channelNames = ['SEA'] }, /channel options/],
|
||||
|
||||
Reference in New Issue
Block a user