diff --git a/extension/tests/connection.test.mjs b/extension/tests/connection.test.mjs new file mode 100644 index 0000000..184709b --- /dev/null +++ b/extension/tests/connection.test.mjs @@ -0,0 +1,22 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; +import {CONNECTION} from '../connection-state.mjs'; + +test('page handshake is exact-origin, read-only, owner-bound and live-validated', async () => { + let grant=true, hint={owner:'test-owner'}, calls=0, valid=true; + globalThis.chrome={runtime:{getManifest:()=>({version:'0.3.4'}),onMessageExternal:{addListener(){}},onConnect:{addListener(){}} }, + storage:{local:{get:async()=>({[CONNECTION]:hint})}},permissions:{onRemoved:{addListener(){}},contains:async()=>grant}}; + globalThis.fetch=async()=>{calls++;return new Response(JSON.stringify({owner:valid?'test-owner':'other-owner',items:[]}),{headers:{'content-type':'application/json'}})}; + const {connectionStatus}=await import('../connection.mjs'); + const message={type:'persimmons.connection.v1',owner:'test-owner'}; + const sender={origin:'https://persimmons.app',url:'https://persimmons.app/',frameId:0}; + assert.deepEqual(await connectionStatus(message,sender),{connected:true,version:'0.3.4',initialized:false,unlocked:false,empty:true}); + for(const bad of [{...sender,origin:'https://evil.example'},{...sender,url:'https://evil.example/'},{...sender,frameId:1}]) assert.equal(await connectionStatus(message,bad),null); + assert.equal(await connectionStatus({...message,type:'unlock'},sender),null); + assert.deepEqual(await connectionStatus({type:'persimmons.connection.v1'},sender),{connected:false,version:'0.3.4'}); + assert.equal(calls,1); + assert.equal((await connectionStatus({...message,owner:'other-owner'},sender)).connected,false); + grant=false; assert.equal((await connectionStatus(message,sender)).connected,false); assert.equal(calls,1); + grant=true; valid=false; assert.equal((await connectionStatus(message,sender)).connected,false); + hint=null; assert.equal((await connectionStatus(message,sender)).connected,false); +});