mirror of
https://github.com/block/buzz.git
synced 2026-10-29 13:31:44 +00:00
50 lines
3.5 KiB
TypeScript
50 lines
3.5 KiB
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { mkdtempSync, writeFileSync, rmSync } from 'node:fs';
|
|
import { createTestRenderer } from '@opentui/core/testing';
|
|
import { OpenTuiShell } from '../src/opentui-shell.ts';
|
|
import { HarnessInventoryController } from '../src/harness-inventory.ts';
|
|
import { localOwner } from '../src/owner-client.ts';
|
|
import { nip19 } from 'nostr-tools';
|
|
for (const [width, height] of [[120,40],[60,20]]) test(`real owner IPC: form failure/recovery, Desktop denial/mismatch, navigation fencing at ${width}x${height}`, async () => {
|
|
const home = mkdtempSync('/tmp/owner-tui-fixture-shell-');
|
|
const mode = (value: string) => writeFileSync(home+'/desktop-mode', value);
|
|
mode('available');
|
|
const ui = await createTestRenderer({width,height,exitOnCtrlC:false});
|
|
const client = localOwner({helper:new URL('./owner-tui-fixture-child.ts',import.meta.url),environment:{HOME:home,BEEHIVE_HOME:home,PATH:process.env.PATH}});
|
|
const inventory = new HarnessInventoryController({read:()=>({version:1,revision:0,agents:[],providers:[],runtimes:[]}),save:c=>c},async()=>[]);
|
|
const shell = new OpenTuiShell(ui.renderer,inventory,undefined,undefined,client);
|
|
const wait = async (predicate:()=>boolean) => { for(let i=0;i<200;i++) { if(predicate()) { await ui.renderOnce(); return; } await new Promise(r=>setTimeout(r,10)); } assert.fail('Owner state did not settle'); };
|
|
const input = ui.mockInput;
|
|
const enter = () => input.pressEnter();
|
|
const submit = () => { input.pressTab(); enter(); };
|
|
try {
|
|
await wait(()=>!client.snapshot().message.includes('Loading'));
|
|
for(let i=0;i<4;i++) input.pressArrow('right');
|
|
await wait(()=>client.snapshot().desktop==='available');
|
|
enter(); enter(); await ui.renderOnce();
|
|
input.typeText('relay.example'); submit(); await new Promise(r=>setTimeout(r,0)); await ui.renderOnce(); assert.doesNotMatch(ui.captureCharFrame(),/CHOOSE A RELAY/);
|
|
input.pressArrow('down'); enter(); input.typeText('invalid'); submit();
|
|
await wait(()=>client.snapshot().phase==='error');
|
|
assert.match(ui.captureCharFrame(),/valid owner nsec/);
|
|
enter(); input.typeText(nip19.nsecEncode(Buffer.from('1'.repeat(64),'hex')));
|
|
await wait(()=>client.snapshot().secretLength>0);
|
|
assert.doesNotMatch(ui.captureCharFrame(),/nsec1/); assert.match(ui.captureCharFrame(),/••/);
|
|
submit(); await wait(()=>client.snapshot().signedIn && shell.state.focus==='header');
|
|
assert.doesNotMatch(ui.captureCharFrame(),/Continue to/);
|
|
enter(); enter(); await wait(()=>!client.snapshot().signedIn);
|
|
mode('denied'); enter(); await wait(()=>client.snapshot().phase==='error');
|
|
assert.match(ui.captureCharFrame(),/key access failed/);
|
|
mode('mismatch'); enter(); await wait(()=>client.snapshot().phase==='error' && client.snapshot().message.includes('does not match'));
|
|
assert.match(ui.captureCharFrame(),/does not match/);
|
|
mode('delayed'); enter(); await wait(()=>client.snapshot().phase==='busy');
|
|
input.pressArrow('up'); input.pressArrow('left');
|
|
assert.equal(shell.state.activeSection,3);
|
|
await new Promise(r=>setTimeout(r,1400));
|
|
assert.equal(client.snapshot().signedIn,false); assert.equal(shell.state.activeSection,3);
|
|
input.pressArrow('right'); mode('available'); enter(); enter();
|
|
await wait(()=>client.snapshot().signedIn && shell.state.focus==='header');
|
|
assert.match(ui.captureCharFrame(),/SIGNED IN/);
|
|
} finally {shell.close();rmSync(home,{recursive:true,force:true});}
|
|
});
|