fix: return completed loading tasks to the task list
This commit is contained in:
@@ -2,6 +2,8 @@ import test from 'node:test'
|
||||
import assert from 'node:assert/strict'
|
||||
import vm from 'node:vm'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
import { navigateBackOr } from '../utils/navigation.js'
|
||||
import { COMPLETION_PHASE, observeLoadingCompletion, resolveCompletionPhase, shouldReconcileCompletion } from '../utils/loading-completion-state.js'
|
||||
|
||||
const source = await readFile(new URL('../pages/picking/picking.vue', import.meta.url), 'utf8')
|
||||
const script = source.match(/<script>([\s\S]*?)<\/script>/)[1]
|
||||
@@ -107,6 +109,82 @@ test('failed request releases submit guard and retry keeps operation identity',
|
||||
|
||||
const task = () => ({ taskId: 'task', recordStatus: 'ACTIVE', loadingPlanId: 'plan', containerBookingId: 'container',
|
||||
currentContainerNo: 'TEST', version: 1, workflowStatus: 'UNASSIGNED', items: [{ id: 'item', packageCount: 2, itemStatus: 'PENDING' }] })
|
||||
|
||||
test('refreshing a completed task returns to the list before claiming or loading evidence', async () => {
|
||||
const destinations = []; let claims = 0, evidence = 0
|
||||
const { ctx } = mount({ getContainerPickingTask: async () => ({ ...task(), taskStatus: 'COMPLETED', workflowStatus: 'COMPLETED' }),
|
||||
navigateBackOr: url => destinations.push(url),
|
||||
claimContainerPickingTask: async () => { claims++ } }, { loadLoadingEvidence: async () => { evidence++ } })
|
||||
await ctx.syncRemoteTask()
|
||||
assert.deepEqual(destinations, ['/pages/tasks/tasks'])
|
||||
assert.equal(ctx.remotePick.taskStatus, 'COMPLETED')
|
||||
assert.equal(claims, 0); assert.equal(evidence, 0); assert.equal(ctx.remoteLoading, false)
|
||||
})
|
||||
|
||||
for (const entry of ['completion', 'refresh']) {
|
||||
for (const control of ['dropdown', 'overlay']) {
|
||||
test(`${entry} returns through onBackPress even when the ${control} opens before completion`, async t => {
|
||||
const previousUni = globalThis.uni, previousPages = globalThis.getCurrentPages
|
||||
t.after(() => { globalThis.uni = previousUni; globalThis.getCurrentPages = previousPages })
|
||||
const response = deferred(), destinations = []; let popupClosed = 0
|
||||
const completed = { ...task(), taskStatus: 'COMPLETED', workflowStatus: 'COMPLETED' }
|
||||
const { page, ctx } = mount({ navigateBackOr, COMPLETION_PHASE, observeLoadingCompletion,
|
||||
resolveCompletionPhase, shouldReconcileCompletion,
|
||||
completeContainerPickingTask: () => response.promise, getContainerPickingTask: () => response.promise },
|
||||
{ evidenceIdentity: { taskId: 'task', warehouseId: 'warehouse' }, evidenceComplete: true,
|
||||
currentBoxIndex: 0, activeOverlay: '', boxDropdownOpen: false,
|
||||
requireEvidenceStage: () => true, isEvidenceContextActive: () => true,
|
||||
$nextTick: callback => callback(), $refs: { boxListPopup: { open() {}, close() { popupClosed++ } } } })
|
||||
ctx.openOverlay = page.methods.openOverlay.bind(ctx)
|
||||
globalThis.getCurrentPages = () => [{ route: 'pages/tasks/tasks' }, { route: 'pages/picking/picking' }]
|
||||
globalThis.uni = {
|
||||
// App 将返回钩子的拦截视为成功;仅调用导航函数不能证明页面已返回。
|
||||
navigateBack() { if (!page.onBackPress.call(ctx)) destinations.push('/pages/tasks/tasks') },
|
||||
reLaunch: ({ url }) => destinations.push(url)
|
||||
}
|
||||
const pending = entry === 'completion' ? ctx.completeLoadingTask() : ctx.syncRemoteTask()
|
||||
if (control === 'dropdown') ctx.toggleBoxDropdown()
|
||||
else ctx.openOverlay('boxList')
|
||||
response.resolve(completed)
|
||||
await pending
|
||||
assert.deepEqual(destinations, ['/pages/tasks/tasks'])
|
||||
assert.equal(ctx.boxDropdownOpen, false); assert.equal(ctx.activeOverlay, '')
|
||||
assert.equal(popupClosed, control === 'overlay' ? 1 : 0)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
test('completed tasks update the real history state while clearing only their own persisted draft', async t => {
|
||||
const previousUni = globalThis.uni
|
||||
t.after(() => { globalThis.uni = previousUni })
|
||||
const moduleUrl = value => `data:text/javascript;base64,${Buffer.from(value).toString('base64')}`
|
||||
let storeSource = await readFile(new URL('../stores/picking.js', import.meta.url), 'utf8')
|
||||
for (const path of ['data/demo-data.js', 'utils/picking-state.js', 'utils/task-identity.js']) {
|
||||
storeSource = storeSource.replace(`@/${path}`, moduleUrl(await readFile(new URL(`../${path}`, import.meta.url), 'utf8')))
|
||||
}
|
||||
const store = await import(moduleUrl(storeSource)), storage = new Map(), writes = []
|
||||
globalThis.uni = { getStorageSync: key => storage.get(key),
|
||||
setStorageSync: (key, value) => { writes.push(key); storage.set(key, value) }, removeStorageSync: key => storage.delete(key) }
|
||||
const identity = { operatorId: 'operator', taskId: 'task', loadingPlanId: 'plan', containerBookingId: 'container' }
|
||||
const { page, ctx } = mount({ clearPickingDraft: store.clearPickingDraft, savePickingSession: store.savePickingSession },
|
||||
{ remotePick: { taskStatus: 'LOADING' }, draftIdentity: () => identity, currentBoxIndex: 0,
|
||||
boxes: [{ taskId: 'task', cabinetNo: 'D2126', items: [] }], boxDrafts: {}, scanHistory: [] })
|
||||
ctx.persistSession = page.methods.persistSession.bind(ctx)
|
||||
ctx.persistSession()
|
||||
const draftKey = store.getPickingDraftKey(identity)
|
||||
assert.equal(storage.has(draftKey), true); assert.equal(store.getPickingOverview().completedCount, 0)
|
||||
storage.set('another-task-draft', { keep: true })
|
||||
writes.length = 0
|
||||
ctx.remotePick = { taskStatus: 'COMPLETED' }
|
||||
ctx.persistSession()
|
||||
page.onUnload.call(ctx)
|
||||
assert.equal(store.getPickingOverview().completedCount, 1)
|
||||
assert.equal(store.getPickingOverview().completedBoxes[0], true)
|
||||
assert.equal(store.getPickingOverview().boxes[0].taskId, 'task')
|
||||
assert.equal(storage.has(draftKey), false); assert.equal(storage.has('another-task-draft'), true)
|
||||
assert.deepEqual(writes, [])
|
||||
})
|
||||
|
||||
for (const hook of ['onHide', 'onUnload']) {
|
||||
test(`${hook} while detail is pending prevents claim and evidence requests`, async () => {
|
||||
const detail = deferred(); let claims = 0, evidence = 0
|
||||
|
||||
Reference in New Issue
Block a user