test(appointments): verify stable batches and current HTTP contracts

This commit is contained in:
2026-10-15 18:13:52 +08:00
parent 204ae10737
commit caff693ad8
5 changed files with 335 additions and 55 deletions
+18 -2
View File
@@ -25,8 +25,8 @@ function harness(fixture=sample()) {
requests.push({actor,method,path,body:clone(body)})
if(actor==='anonymous')return response(null,401,'A0401')
if(actor==='merchant'||actor==='reader'&&method==='POST')return response(null,403,'A0403')
if(path===`${WORK}/summary`)return response({all:1,followToday:0,overdue:0,undated:1,review:0})
if(path.startsWith(`${WORK}/items?`))return response({records:[clone(detail.item)],page:1,size:100,total:1,pages:1})
if(path===`${WORK}/summary`)return response({all:'1',followToday:'0',overdue:'0',undated:'1',review:'0'})
if(path.startsWith(`${WORK}/items?`))return response({records:[clone(detail.item)],page:'1',size:'100',total:'1',pages:'1'})
if(path===`${WORK}/items/WORK-1`&&method==='GET')return response(clone(detail))
if(path===`${API}/dispatches/D-20`)return response({id:'20',dispatchNo:'D-20',packageCount:4,items:[{planPalletId:'10',packageCount:4}]})
if(path===`${WORK}/items/WORK-1/commands`) {
@@ -71,6 +71,22 @@ test('pagination and actual evidence cannot silently truncate or invent completi
assert.throws(()=>assertItem({...item,actual:{localOccurredAt:'2026-10-15T11:00:00',occurredAt:null,timezone:null}},c))
assert.throws(()=>assertItem({...item,containers:[{containerBookingId:'foreign'}]},c))
})
test('Long wire counters preserve exact pagination and reject missing or unsafe counts',()=>{
const page={records:[{workItemKey:'WORK-1'}],page:'1',size:'100',total:'1',pages:'1'}
assert.equal(validatePage(page,1).length,1)
for(const total of [null,undefined,'',true,'1.5','01','9007199254740993',-1])assert.throws(()=>validatePage({...page,total},1))
assert.throws(()=>validatePage({...page,page:null},1))
assert.throws(()=>validatePage({...page,pages:'2'},1))
})
test('omitted nullable wire fields remain unknown and never imply completion',()=>{
const c=sample().cases[0], item=workItem(c)
delete item.actual; delete item.calendarDate
assert.equal(assertItem(item,c),item)
assert.throws(()=>assertItem({...item,actual:{localOccurredAt:'2026-10-15T10:00:00'}},c))
assert.throws(()=>assertItem({...item,executionStatus:undefined},c))
})
test('workflow runs denial/replay/stale/no-booking checks without original-business writes',async()=>{
const h=harness(),result=await verify(h,sample(),{mode:'workflow',runId:'aw-test'})
assert.ok(result.checks.includes('no booking does not mean executed'))