aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-18 09:48:13 -0700
committerAdam Soltys <[email protected]>2026-10-18 09:48:13 -0700
commit5869fa2ce351efa485ae6547d618a216b09a47c1 (patch)
tree6894739087f320bd48c18c58fd5ca6fe8d8d6781 /tools
parentaaebbd5d51e0e149c36975122dd0ae59e6c011bb (diff)
downloadcoinosv3-5869fa2ce351efa485ae6547d618a216b09a47c1.tar.gz
coinosv3-5869fa2ce351efa485ae6547d618a216b09a47c1.zip
A call from someone you don't follow and haven't written to no longer vanishes: it doesn't ring, but it's a missed call in your conversation with them, saying it didn't ring and why, a tap away from calling back (with the app shut, the worker notes it for the app, without a notification). A muted person's still leaves nothing. A logged call no longer counts as having written to someone.
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_013ZDf1cyCQLkfjftYhymZAg
Diffstat (limited to 'tools')
-rw-r--r--tools/call-test.js13
-rw-r--r--tools/call-wake-test.js11
2 files changed, 19 insertions, 5 deletions
diff --git a/tools/call-test.js b/tools/call-test.js
index 2958187..7e9a99c 100644
--- a/tools/call-test.js
+++ b/tools/call-test.js
@@ -2,8 +2,8 @@
// between them. The caller's 📞 / 🎥 in their conversation rings the other
// over whatever page they're on; Answer connects them — each hears and sees
// the other — mute and camera-off reach the other side, hang-up ends it on
-// both. A call can be declined, and a stranger (neither followed nor written
-// to) doesn't ring at all. Everything on the wire is an ephemeral gift wrap.
+// both. A call can be declined, and a stranger's (neither followed nor
+// written to) doesn't ring, but is in the conversation as a missed call. Everything on the wire is an ephemeral gift wrap.
// Run: bun tools/call-test.js (NO_BUILD=1 to reuse dist/)
import puppeteer from './puppeteer.js';
import { cacheKeyFor } from '../src/wallet.js';
@@ -162,6 +162,15 @@ try {
await sleep(5000);
check('someone Bob neither follows nor wrote to doesn\'t ring him', !(await B.page.evaluate(() => !!document.querySelector('.call-overlay'))));
await C.page.evaluate(() => document.querySelector('.call-hang')?.click());
+ await waitFor(C.page, () => !document.querySelector('.call-overlay'), 6000);
+ await C.page.evaluate(() => document.querySelector('.call-start[data-call="voice"]').click());
+ await waitFor(C.page, () => /calling/i.test(document.querySelector('.call-overlay')?.innerText || ''), 10000);
+ await sleep(4000);
+ check('...nor does their next call (a logged call isn\'t having written to them)', !(await B.page.evaluate(() => !!document.querySelector('.call-overlay'))));
+ await C.page.evaluate(() => document.querySelector('.call-hang')?.click());
+ await openDm(B, C.pk);
+ check('...but it\'s in his conversation with them, as a call that didn\'t ring, and why', await waitFor(B.page, () => [...document.querySelectorAll('.chat-row.call-log.missed')].some((r) => /Missed voice call/.test(r.innerText) && /people you follow or have written to/i.test(r.innerText)), 8000),
+ JSON.stringify(await B.page.evaluate(() => [...document.querySelectorAll('.chat-row.call-log')].map((r) => r.innerText))));
check('...the caller who gave up has it as cancelled', await waitFor(C.page, () => [...document.querySelectorAll('.chat-row.call-log')].some((r) => /Cancelled voice call/.test(r.innerText)), 6000));
for (const w of [A, B, C]) check(w.name + ': no page errors', !w.page.errs.length, w.page.errs.join(' | '));
} catch (e) { console.error(e); ok = false; } finally {
diff --git a/tools/call-wake-test.js b/tools/call-wake-test.js
index e14935a..54c42ee 100644
--- a/tools/call-wake-test.js
+++ b/tools/call-wake-test.js
@@ -26,10 +26,11 @@ console.log('[the worker\'s check]');
const box = [{ pubkey: B, sk: bytesToHex(bob), follows: [Al], known: [], muted: [], names: { [Al]: 'Alice' } }];
const offer = (sk, ago = 0, kind = CALL.OFFER, to = B) => wrapCall(finalizeEvent({ ...callEvent(kind, to, 'id-1', 'v=0', kind === CALL.OFFER ? [['call-type', 'video']] : []), created_at: Math.floor(Date.now() / 1000) - ago }, sk), to);
const r = await classifyCall(offer(alice), box);
- check('a fresh offer from someone followed rings, named, video', !!r && r.name === 'Alice' && r.type === 'video' && r.offer.pubkey === Al);
- check('...a stranger\'s doesn\'t', (await classifyCall(offer(eve), box)) === null);
+ check('a fresh offer from someone followed rings, named, video', !!r && !r.quiet && r.name === 'Alice' && r.type === 'video' && r.offer.pubkey === Al);
+ check('...a stranger\'s doesn\'t ring, but is kept as quiet', (await classifyCall(offer(eve), box))?.quiet === true);
check('...nor someone muted', (await classifyCall(offer(alice), [{ ...box[0], muted: [Al] }])) === null);
- check('...but someone written to does', !!(await classifyCall(offer(eve), [{ ...box[0], known: [E] }])));
+ check('...but someone written to rings', (await classifyCall(offer(eve), [{ ...box[0], rings: [E] }]))?.quiet === false);
+ check('...not someone who only wrote to us', (await classifyCall(offer(eve), [{ ...box[0], known: [E], rings: [] }]))?.quiet === true);
check('...an offer over a minute old doesn\'t', (await classifyCall(offer(alice, 90), box)) === null);
check('...nor a candidate or a hang-up', (await classifyCall(offer(alice, 0, CALL.ICE), box)) === null && (await classifyCall(offer(alice, 0, CALL.HANGUP), box)) === null);
check('...nor a wrap for someone else', (await classifyCall(offer(alice, 0, CALL.OFFER, E), box)) === null);
@@ -176,6 +177,10 @@ try {
await B.page.goto(`http://localhost:${PORT}/`, { waitUntil: 'domcontentloaded' });
await B.waitText('receive');
check('a stranger\'s offer, or one gone, rings nothing', !(await notifications(B.page)).some((n) => /calling/.test(n)) && !(await B.page.evaluate(() => !!document.querySelector('.call-overlay'))));
+ await B.page.goto(`http://localhost:${PORT}/` + npubEncode(getPublicKey(eve)), { waitUntil: 'domcontentloaded' });
+ await B.page.waitForSelector('.prof-actions', { timeout: 20000 });
+ await B.page.evaluate(() => [...document.querySelectorAll('.prof-actions button')].find((x) => /message/i.test(x.textContent)).click());
+ check('...but the stranger\'s call is in the app once it opens: missed, didn\'t ring', await waitFor(B.page, () => [...document.querySelectorAll('.chat-row.call-log.missed')].some((r) => /didn.t ring/i.test(r.innerText)), 10000));
console.log('\n[rung while closed, and nobody came]');
await B.page.goto('about:blank');