20 lines
2.6 KiB
TypeScript
20 lines
2.6 KiB
TypeScript
import assert from "node:assert/strict"
|
|
import {test} from "node:test"
|
|
import {getAlertsOutbox,retryAlertsOutbox} from "./alerts-outbox"
|
|
const empty={counts:{total:0,pending:0,processing:0,unknown:0,sent:0,failed:0,unrecognized:0},items:[],itemsLimit:20}
|
|
test("queue strict no-store reader distinguishes confirmed zero from malformed or missing held data",async()=>{
|
|
const original=globalThis.fetch;try{
|
|
globalThis.fetch=async(_url,init)=>{assert.equal(init?.cache,"no-store");return Response.json(empty)};assert.deepEqual(await getAlertsOutbox("https://backend.test"),empty)
|
|
for(const raw of [{},{...empty,counts:{...empty.counts,total:1}},{...empty,counts:{...empty.counts,total:1,unknown:1}},{...empty,secret:"private"}]){let calls=0;globalThis.fetch=async()=>{calls++;return Response.json(raw)};await assert.rejects(getAlertsOutbox("https://backend.test"),/не подтверждено/);assert.equal(calls,1)}
|
|
const controller=new AbortController();controller.abort();let calls=0;globalThis.fetch=async()=>{calls++;return Response.json(empty)};await assert.rejects(getAlertsOutbox("https://backend.test",{signal:controller.signal}));assert.equal(calls,0)
|
|
const late=new AbortController();globalThis.fetch=async()=>{late.abort();return Response.json(empty)};await assert.rejects(getAlertsOutbox("https://backend.test",{signal:late.signal}))
|
|
}finally{globalThis.fetch=original}
|
|
})
|
|
|
|
test("queue retry requires risk acknowledgement and strict matching receipt, one POST with no retry",async()=>{
|
|
const original=globalThis.fetch;try{let calls=0;globalThis.fetch=async(url,init)=>{calls++;assert.ok(String(url).endsWith("/api/alerts/outbox/a%2Fb/retry"));assert.equal(init?.method,"POST");assert.deepEqual(JSON.parse(String(init?.body)),{expectedVersion:3,acknowledgedDuplicateRisk:true});return Response.json({ok:true,id:"a/b",status:"pending",resolutionVersion:4})}
|
|
await assert.rejects(retryAlertsOutbox("https://backend.test","a/b",{expectedVersion:3,acknowledgedDuplicateRisk:false}));assert.equal(calls,0);assert.equal((await retryAlertsOutbox("https://backend.test","a/b",{expectedVersion:3,acknowledgedDuplicateRisk:true})).status,"pending");assert.equal(calls,1)
|
|
for(const raw of [{},{ok:true,id:"other",status:"pending",resolutionVersion:4},{ok:true,id:"a/b",status:"sent",resolutionVersion:4},{ok:true,id:"a/b",status:"pending",resolutionVersion:3}]){calls=0;globalThis.fetch=async()=>{calls++;return Response.json(raw)};await assert.rejects(retryAlertsOutbox("https://backend.test","a/b",{expectedVersion:3,acknowledgedDuplicateRisk:true}),/не подтверждена/);assert.equal(calls,1)}
|
|
}finally{globalThis.fetch=original}
|
|
})
|