1// Exercise the production keydown handler without loading the rest of the page.
2import assert from 'node:assert/strict';
3import { readFileSync } from 'node:fs';
4import { test } from 'node:test';
5const src = readFileSync(new URL('../static/js/ermite.js', import.meta.url), 'utf8');
6const block = src.slice(src.indexOf(' // 1. Keys.'), src.indexOf(' // 2. A [data-fire]'));
7
8function page({ owner = true, off = false, typing = false, dialog = false } = {}) {
9 let handler;
10 const fired = [];
11 const window = { ermiteKeys: { blocks: () => off } };
12 const $ = (s) => s === 'dialog[open]' ? dialog : s === '[data-inbox]' ? owner : null;
13 new Function('window', '$', 'ermite', 'addEventListener', block)(window, $, { fire: (n) => fired.push(n) }, (_, f) => { handler = f; });
14 return (key) => {
15 const e = { key, shiftKey: key === 'I', preventDefault() {}, target: { closest: (s) => s.startsWith('input') && typing } };
16 handler(e);
17 return fired;
18 };
19}
20test('Shift+I opens inbox while lowercase i retains the issues tab', () => {
21 const press = page();
22 assert.deepEqual(press('I'), ['inbox']);
23 assert.deepEqual(press('i'), ['inbox', 'i']);
24});
25test('inbox shortcut respects preference, fields, dialogs, and owner target', () => {
26 for (const options of [{ off: true }, { typing: true }, { dialog: true }, { owner: false }]) {
27 assert.deepEqual(page(options)('I'), [], JSON.stringify(options));
28 }
29});