优化
This commit is contained in:
@@ -1,6 +1,88 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
import { pickerFixtureSuffix } from './phase4-overseas-pda.mjs'
|
||||
import { pickerFixtureSuffix, createPicker, disablePicker, pickerSessionHandoff } from './phase4-overseas-pda.mjs'
|
||||
import { verifyPdaWarehouseRevocation } from './unified-pda-session-revocation.mjs'
|
||||
|
||||
test('fixed PDA actors are leased separately and only logged out, never modified', async () => {
|
||||
const actors = ['11', '12'].map(membershipId => ({ membershipId, warehouseId: '91', username: `test-${membershipId}`, password: 'fixture-only' }))
|
||||
const calls = [], gaps = []
|
||||
const context = { options: { fixedCustomerId: '101', fixedPdaActors: actors },
|
||||
async request(method, path, body) {
|
||||
calls.push({ method, path })
|
||||
let data = {}
|
||||
if (path.includes('/iam/users?')) data = { total: 2, records: actors.map(actor => ({ ...actor,
|
||||
overseasWarehouseId: '91', tenantId: '0', status: 'ACTIVE', roleIds: ['7'] })) }
|
||||
if (path === '/api/auth/login') data = { accessToken: body.loginId, refreshToken: `refresh-${body.loginId}` }
|
||||
return { http: 200, body: { code: '200', data } }
|
||||
},
|
||||
apiSuccess(_module, _name, result) { return result.body.data }, addStep() {},
|
||||
addCoverageGap(...args) { gaps.push(args) },
|
||||
}
|
||||
const primary = await createPicker(context, 1, '91', { role: { id: '7' } })
|
||||
const secondary = await createPicker(context, 2, '91', { role: { id: '7' } })
|
||||
assert.notEqual(primary.membershipId, secondary.membershipId)
|
||||
assert.equal(await createPicker(context, 3, '91', { role: { id: '7' } }), null)
|
||||
const handoff = pickerSessionHandoff(primary)
|
||||
assert.equal(handoff.reused, true)
|
||||
assert.equal(handoff.password, undefined)
|
||||
await verifyPdaWarehouseRevocation(context, handoff)
|
||||
assert.equal(gaps.length, 1)
|
||||
await disablePicker(context, handoff, 1)
|
||||
await disablePicker(context, primary, 1)
|
||||
await disablePicker(context, secondary, 2)
|
||||
assert.equal(context.fixedPdaLeases.size, 0)
|
||||
assert.equal(calls.filter(call => call.path === '/api/auth/logout').length, 2)
|
||||
assert.ok(calls.every(call => call.method === 'GET' || ['/api/auth/login', '/api/auth/logout'].includes(call.path)))
|
||||
})
|
||||
|
||||
test('missing fixed PDA pool stops before network or phone allocation', async () => {
|
||||
const context = { options: { fixedCustomerId: '101' }, addStep() {},
|
||||
request() { throw Error('unexpected HTTP') }, findAvailablePhone() { throw Error('unexpected allocation') } }
|
||||
assert.equal(await createPicker(context, 1, '91', { role: { id: '7' } }), null)
|
||||
})
|
||||
|
||||
test('failed PDA projection checks logout and retains leases on rejected or uncertain logout', async () => {
|
||||
for (const logout of ['success', 'rejected', 'throws']) {
|
||||
const actor = { membershipId: '11', warehouseId: '91', username: 'fixture-actor', password: 'fixture-only' }
|
||||
const steps = [], calls = []
|
||||
const context = { options: { fixedCustomerId: '101', fixedPdaActors: [actor] },
|
||||
async request(method, path) {
|
||||
calls.push(path)
|
||||
if (path.includes('/iam/users?')) return { body: { data: { records: [{ ...actor,
|
||||
overseasWarehouseId: '91', tenantId: '0', status: 'ACTIVE', roleIds: ['7'] }] } } }
|
||||
if (path === '/api/auth/login') return { body: { data: { accessToken: 'fixture-token', refreshToken: 'fixture-refresh' } } }
|
||||
if (path === '/api/auth/logout' && logout === 'throws') throw Error('network failure')
|
||||
return { http: 200, body: { code: path === '/api/auth/logout' && logout === 'success' ? '200' : 'A0403' } }
|
||||
},
|
||||
apiSuccess(_module, _name, response) { return response.body.data },
|
||||
addStep(...args) { steps.push(args) },
|
||||
}
|
||||
assert.equal(await createPicker(context, 1, '91', { role: { id: '7' } }), null)
|
||||
assert.equal(calls.filter(path => path === '/api/auth/logout').length, 1)
|
||||
assert.equal(context.fixedPdaLeases.has('11'), logout !== 'success')
|
||||
assert.ok(steps.some(step => step[1].includes('核验失败') && step[3] === false))
|
||||
if (logout !== 'success') {
|
||||
assert.ok(steps.some(step => step[1].includes('退出固定PDA') && step[3] === false))
|
||||
const before = calls.length
|
||||
assert.equal(await createPicker(context, 2, '91', { role: { id: '7' } }), null)
|
||||
assert.equal(calls.length, before)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
test('logout exception does not prevent remaining fixed actors from being cleaned up', async () => {
|
||||
const calls = []
|
||||
const context = { fixedPdaLeases: new Set(['11', '12']), addStep() {},
|
||||
async request(_method, _path, body) {
|
||||
calls.push(body.refreshToken)
|
||||
if (body.refreshToken === 'first') throw Error('network failure')
|
||||
return { http: 200, body: { code: '200' } }
|
||||
} }
|
||||
await disablePicker(context, { membershipId: '11', refreshToken: 'first', reused: true }, 1)
|
||||
await disablePicker(context, { membershipId: '12', refreshToken: 'second', reused: true }, 2)
|
||||
assert.deepEqual(calls, ['first', 'second'])
|
||||
assert.deepEqual([...context.fixedPdaLeases], ['11'])
|
||||
})
|
||||
|
||||
test('长场景尾部相同时PDA账号仍保留完整运行标识的区别', () => {
|
||||
const first = { marker: 'ADMIN-API-20261005134027677-COMPLETED-F40-PDA' }
|
||||
|
||||
Reference in New Issue
Block a user