owner_app/test-console.cjs
Read-only source from the unchanged 0.3.4 kit. Existing license terms apply.
// Minimal DOM harness for event-handler regressions; not a browser rendering test.
const fs = require('node:fs');
const vm = require('node:vm');
const assert = require('node:assert/strict');
const cryptoApi = require('node:crypto').webcrypto;
globalThis.crypto = cryptoApi;
const AILCrypto = require('./ail-crypto.js');
class Element {
constructor() { this.value='';this.files=[];this.dataset={};this.children=[];this.handlers={};this.textContent='';this.disabled=false;
const classes=new Set();this.classList={add:(...a)=>a.forEach(x=>classes.add(x)),remove:(...a)=>a.forEach(x=>classes.delete(x)),toggle:(x,b)=>b?classes.add(x):classes.delete(x),contains:x=>classes.has(x)};
}
addEventListener(n,f){this.handlers[n]=f;}
async fire(n='click'){return this.handlers[n]?.call(this);}
append(...x){this.children.push(...x);}
appendChild(x){this.append(x);}
replaceChildren(...x){this.children=x;}
click(){} remove(){}
}
(async()=>{
const html=fs.readFileSync(__dirname+'/index.html','utf8');
const elements=Object.fromEntries([...html.matchAll(/id="([^"]+)"/g)].map(m=>[m[1],new Element()]));
const e=id=>{assert.ok(elements[id],'missing DOM id: '+id);return elements[id];};
const downloadWallet=e('download-wallet');
const sandbox={AILCrypto,document:{getElementById:e,createElement:()=>new Element(),body:new Element(),querySelectorAll:()=>Object.values(elements)},Blob,URL,setTimeout:()=>{},confirm:()=>true,navigator:{clipboard:{writeText:async()=>{}}}};
vm.runInNewContext(fs.readFileSync(__dirname+'/app.js','utf8'),sandbox);
await e('generate').fire();assert.equal(e('create-error').classList.contains('hidden'),false);
e('display-name').value='Console Test';e('principal').value='urn:ail:principal:console-test';
e('new-password').value=e('confirm-password').value='console-test-password';
await e('generate').fire();assert.equal(e('create-result').classList.contains('hidden'),false);
assert.equal(e('download-wallet'),downloadWallet);assert.ok(e('created-key-id').textContent.startsWith('Key fingerprint: sha256:'));
const wallet=await AILCrypto.generateWallet({display_name:'Console Test',principal:'urn:ail:principal:console-test'},'console-test-password');
const file=obj=>({size:1000,text:async()=>JSON.stringify(obj)});
e('wallet-file').files=[file(wallet)];e('wallet-password').value='wrong';await e('sign-packet').fire();
assert.equal(e('sign-error').classList.contains('hidden'),false);
e('wallet-password').value='console-test-password';await e('sign-packet').fire();
assert.equal(e('sign-result').classList.contains('hidden'),false);
const packet=await AILCrypto.createIdentityPacket(wallet,'console-test-password');
e('packet-file').files=[file(packet)];e('trusted-fingerprint').value='sha256:'+'0'.repeat(64);await e('verify-packet').fire();
assert.equal(e('verify-result').classList.contains('error'),true);
e('trusted-fingerprint').value=wallet.key.key_id;await e('verify-packet').fire();
assert.equal(e('verify-result').classList.contains('error'),false);assert.equal(e('download-report').disabled,false);
await e('trusted-fingerprint').fire('input');assert.equal(e('download-report').disabled,true);
e('packet-file').files=[{size:1048577}];await e('verify-packet').fire();assert.equal(e('verify-result').classList.contains('error'),true);
await e('clear-session').fire();assert.equal(e('wallet-password').value,'');assert.equal(e('download-report').disabled,true);
console.log('console-handler-tests: PASS (retry, sign recovery, key mismatch, match, stale report, file size, session clear)');
})().catch(e=>{console.error(e);process.exitCode=1;});