import {test} from 'node:test' import assert from 'node:assert/strict' import {installUnreadBadge} from './unread-badge.mjs' function fixture(){let handler,badges=[],total=12,user='one',quit=false;const frame={url:'https://fixture.local/chat'},contents={mainFrame:frame},win={webContents:contents};const controller=installUnreadBadge({ipcMain:{handle(_name,fn){handler=fn},removeHandler(){}},app:{dock:{setBadge:v=>badges.push(v)}},owner:()=>win,origins:()=>['https://fixture.local'],url:()=>frame.url,quitting:()=>quit,fetch:async url=>({ok:true,status:200,json:async()=>url.includes('bootstrap')?{userId:user}:{total}}),interval:100000});return {controller,badges,event:{sender:contents,senderFrame:frame},invoke:(e,v)=>handler(e,v),setTotal:v=>total=v,setUser:v=>user=v,setQuit:v=>quit=v}} test('authority continues while owner is hidden/closed-to-tray and clears logout scope',async()=>{const f=fixture();try{await f.invoke(f.event,'one');assert.equal(f.badges.at(-1),'12');f.setTotal(103);await f.controller.refresh();assert.equal(f.badges.at(-1),'103');await f.invoke(f.event,null);assert.equal(f.badges.at(-1),'');await f.invoke(f.event,'one');f.setUser('two');await f.controller.refresh();assert.equal(f.badges.at(-1),'');f.setTotal(0);await f.invoke(f.event,'two');assert.equal(f.badges.at(-1),'')}finally{f.controller.stop()}}) test('rejects subframe, foreign webContents, origin and malformed input without weakening frame checks',async()=>{const f=fixture();try{for(const e of [{...f.event,sender:{}},{...f.event,senderFrame:{url:'https://fixture.local/chat'}},{...f.event,senderFrame:{url:'https://bad.local'}}])await assert.rejects(f.invoke(e,'one'));await assert.rejects(f.invoke(f.event,{count:3}));f.setQuit(true);await assert.rejects(f.invoke(f.event,'one'))}finally{f.controller.stop()}})