aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-01 12:35:15 -0700
committerAdam Soltys <[email protected]>2026-10-01 12:35:15 -0700
commit1da40523fc00b9963012abe067a6c4910c7578b6 (patch)
tree396b8fc8a66989fc56e61ad1370011b40cf93027 /tools
parent509d632595399bc355fcf3826875214dc9d3b68c (diff)
downloadcoinosv3-1da40523fc00b9963012abe067a6c4910c7578b6.tar.gz
coinosv3-1da40523fc00b9963012abe067a6c4910c7578b6.zip
Zaps and reactions get their own notification switches.
The notifier now watches kind-7 reactions p-tagged at the user (opt-in by an explicit flag, so older apps that can't word them stay quiet) and sends zap receipts as 'zap' to apps that report the category, 'payment' to older ones. Coinos zap receipts carry their amount into the push. The service worker names the reactor when it knows them and stays quiet for a muted one. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01VP5Ljqk7EYcm5QQAbzDwog
Diffstat (limited to 'tools')
-rw-r--r--tools/notif-categories-test.js39
1 files changed, 39 insertions, 0 deletions
diff --git a/tools/notif-categories-test.js b/tools/notif-categories-test.js
new file mode 100644
index 0000000..92b0c71
--- /dev/null
+++ b/tools/notif-categories-test.js
@@ -0,0 +1,39 @@
+// Settings → Notifications lists zaps and reactions as their own categories,
+// each with its own switch. Run: bun tools/notif-categories-test.js
+import assert from 'node:assert/strict';
+import puppeteer from 'puppeteer-core';
+import { buildHtml } from '../build.js';
+const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
+const html = await buildHtml({ minify: true, pwa: false });
+const server = Bun.serve({ port: 0, fetch: () => new Response(html, { headers: { 'content-type': 'text/html; charset=utf-8' } }) });
+const browser = await puppeteer.launch({ executablePath: '/usr/bin/google-chrome', headless: true, args: ['--no-sandbox'] });
+try {
+ const page = await browser.newPage();
+ const errors = [];
+ page.on('pageerror', (e) => errors.push(String(e)));
+ await page.setViewport({ width: 390, height: 844 });
+ await page.setRequestInterception(true);
+ page.on('request', (r) => r.url().startsWith(server.url.origin) ? r.continue() : r.abort());
+ const click = (x) => page.evaluate((x) => { const e = [...document.querySelectorAll('button')].find((n) => n.textContent.trim().toLowerCase().includes(x)); if (e) { e.click(); return true; } return false; }, x);
+ await page.goto(server.url.origin + '/', { waitUntil: 'domcontentloaded' });
+ await page.evaluate(() => localStorage.setItem('btc-wallet-network', 'regtest'));
+ await page.reload(); await sleep(500);
+ await click('create a new wallet'); await sleep(600);
+ await click('skip verification'); await sleep(300);
+ await page.waitForFunction(() => document.body.innerText.toLowerCase().includes('receive'), { timeout: 20000 });
+ await page.evaluate(() => [...document.querySelectorAll('button')].find((e) => e.getAttribute('aria-label') === 'Settings').click()); await sleep(600);
+ await page.evaluate(() => [...document.querySelectorAll('.settings-tile')].find((e) => /notification/i.test(e.textContent)).click()); await sleep(600);
+ const rows = () => page.evaluate(() => Object.fromEntries([...document.querySelectorAll('.card .row.between')]
+ .map((r) => [r.querySelector('span')?.textContent, r.querySelector('button')?.textContent])));
+ const before = await rows();
+ for (const k of ['Payments received', 'Zaps on your posts', 'Direct messages', 'Replies and mentions on nostr', 'Reactions to your posts'])
+ assert.equal(before[k], 'On', k + ' is listed and on by default');
+ await page.evaluate(() => [...document.querySelectorAll('.card .row.between')].find((r) => /Reactions/.test(r.textContent)).querySelector('button').click());
+ await sleep(500);
+ const after = await rows();
+ assert.equal(after['Reactions to your posts'], 'Off', 'reactions switch off on their own');
+ assert.equal(after['Zaps on your posts'], 'On');
+ assert.equal(after['Replies and mentions on nostr'], 'On');
+ assert.deepEqual(errors, []);
+ console.log('✓ zaps and reactions have their own switches', JSON.stringify(after));
+} finally { await browser.close(); server.stop(true); }