36 lines
3.9 KiB
TypeScript
36 lines
3.9 KiB
TypeScript
import assert from "node:assert/strict"
|
|
import {test} from "node:test"
|
|
import type {CertificateObserved,CertificatesState} from "@mmapp/contracts/certificates"
|
|
import {mergeCertificateSnapshots} from "./certificate-snapshots"
|
|
import {readCertificatesState} from "../shared/api/certificates"
|
|
const cert:CertificateObserved={id:"1:*A",rosId:"*A",name:"test-cert",serverId:"1",commonName:"test.example",sans:[],issuedBy:"—",validFrom:null,validUntil:null,rawValidFrom:null,rawValidUntil:null,daysLeft:null,keySize:null,trusted:null,status:"unknown",usage:[]}
|
|
const node={serverId:"1",serverName:"Router",collectedAt:"2026-10-01T00:00:00Z",certificates:[cert],error:null}
|
|
const state:CertificatesState={collectedAt:node.collectedAt,servers:[node]}
|
|
test("partial failure retains confirmed device snapshot, latest error and timestamp independently",()=>{
|
|
const first=mergeCertificateSnapshots({},state),second=mergeCertificateSnapshots(first,{...state,servers:[{...node,collectedAt:"2026-10-01T01:00:00Z",certificates:[],error:"offline"}]})
|
|
assert.equal(second["1"].confirmed?.certificates[0].name,cert.name);assert.equal(second["1"].confirmed?.collectedAt,node.collectedAt);assert.equal(second["1"].latest.error,"offline");assert.equal(second["1"].latest.collectedAt,"2026-10-01T01:00:00Z");assert.equal(first["1"].latest.error,null)
|
|
})
|
|
test("initial failure stays unknown, confirmed empty clears old rows, removed devices are removed",()=>{
|
|
const failure=mergeCertificateSnapshots({}, {...state,servers:[{...node,certificates:[],error:"offline"}]});assert.equal(failure["1"].confirmed,null)
|
|
const good=mergeCertificateSnapshots({},state);const empty=mergeCertificateSnapshots(good,{...state,servers:[{...node,certificates:[]}]});assert.deepEqual(empty["1"].confirmed?.certificates,[]);assert.deepEqual(mergeCertificateSnapshots(good,{...state,servers:[]}),{})
|
|
})
|
|
test("device failures are independent and recovery replaces only its snapshot",()=>{
|
|
const first=mergeCertificateSnapshots({}, {...state,servers:[node,{...node,serverId:"2",certificates:[],error:"offline"}]});assert.equal(first["2"].confirmed,null)
|
|
const recovered=mergeCertificateSnapshots(first,{...state,servers:[{...node,certificates:[],error:"offline"},{...node,serverId:"2",certificates:[]}]});assert.equal(recovered["1"].confirmed?.certificates.length,1);assert.deepEqual(recovered["2"].confirmed?.certificates,[])
|
|
})
|
|
test("HTTP reader preserves unknown values and rejects malformed/duplicate/foreign envelopes",async()=>{
|
|
const original=globalThis.fetch;let payload:unknown=state,seen="",signal:AbortSignal|null|undefined
|
|
globalThis.fetch=async(input,init)=>{seen=String(input);signal=init?.signal;return new Response(JSON.stringify(payload),{status:200,headers:{"content-type":"application/json"}})}
|
|
try{
|
|
const controller=new AbortController();const result=await readCertificatesState("https://api.example.test",{signal:controller.signal});assert.equal(seen,"https://api.example.test/api/certificates/state");assert.equal(result.servers[0].certificates[0].daysLeft,null);assert.equal(result.servers[0].certificates[0].status,"unknown");controller.abort();assert.equal(signal?.aborted,true)
|
|
for(const bad of [{certificates:[]},{...state,servers:[node,node]},{...state,servers:[{...node,certificates:[{...cert,serverId:"2"}]}]},{...state,servers:[{...node,certificates:[{...cert,status:"valid"}]}]}]){payload=bad;await assert.rejects(()=>readCertificatesState("https://api.example.test"))}
|
|
}finally{globalThis.fetch=original}
|
|
})
|
|
test("HTTP error/empty ack do not become a successful empty catalog",async()=>{
|
|
const original=globalThis.fetch
|
|
try{
|
|
globalThis.fetch=async()=>new Response(JSON.stringify({error:"forbidden"}),{status:403});await assert.rejects(()=>readCertificatesState("https://api.example.test"),/forbidden/)
|
|
globalThis.fetch=async()=>new Response(null,{status:204});await assert.rejects(()=>readCertificatesState("https://api.example.test"))
|
|
}finally{globalThis.fetch=original}
|
|
})
|