const {test} = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const source = fs.readFileSync('src/main/frontend/push-worker.js', 'utf8'); const modulePromise = import('data:text/javascript;base64,' + Buffer.from(source).toString('base64')); const scope = 'https://werkjournal.example/'; function fixture(install) { const events = {}, shown = [], opened = []; const worker = { registration: {scope, async showNotification(...args) { shown.push(args); }}, clients: {async matchAll() { return []; }, async openWindow(url) { opened.push(url); }}, addEventListener(name, handler) { events[name] = handler; } }; install(worker); return {worker, events, shown, opened}; } async function fire(handler, event) { let pending; handler({...event, waitUntil(promise) { pending = promise; }}); await pending; } test('push shows the dated reminder with the journal icon and a stable daily tag', async () => { const {installPushHandlers} = await modulePromise; const f = fixture(installPushHandlers); await fire(f.events.push, {data: {json: () => ({title:'ignored', body:'Record work', url:'/work?date=2026-09-09&new=true'})}}); assert.equal(f.shown.length, 1); assert.equal(f.shown[0][0], 'Werkjournal'); assert.equal(f.shown[0][1].icon, scope + 'icons/journal.png'); assert.equal(f.shown[0][1].tag, 'work-2026-09-09'); await fire(f.events.push, {data: {json: () => { throw Error('malformed'); }}}); assert.equal(f.shown.length, 1); }); test('unsafe or invalid destinations are rejected', async () => { const {reminderUrl} = await modulePromise; for (const url of ['https://evil.example/work?date=2026-09-09&new=true', '/settings', '/work?date=2026-02-30&new=true', 'javascript:alert(1)', '/work?date=2026-09-09&new=true#other']) { assert.equal(reminderUrl(url, scope), null); } assert.equal(reminderUrl('work?date=2026-09-09&new=true', scope + 'app/'), scope + 'app/work?date=2026-09-09&new=true'); }); test('notification click opens the dated form and reuses an existing app window', async () => { const {installPushHandlers} = await modulePromise; const f = fixture(installPushHandlers); const url = scope + 'work?date=2026-09-09&new=true'; let closed = 0, focused = 0, navigated; const notification = {data: {url}, close() { closed++; }}; await fire(f.events.notificationclick, {notification}); assert.deepEqual(f.opened, [url]); f.worker.clients.matchAll = async () => [{url: scope + 'reports', async navigate(target) { navigated = target; return {async focus() { focused++; }}; }}]; await fire(f.events.notificationclick, {notification}); assert.equal(navigated, url); assert.equal(focused, 1); assert.equal(closed, 2); assert.equal(f.opened.length, 1); });