import { test } from 'node:test'; import assert from 'node:assert/strict'; import { MatrixError } from 'matrix-js-sdk'; import { PresenceDeduper, describePresenceError, setPresenceWithRetry } from './presenceWrite'; const limited = (retryMs = 3000) => new MatrixError( { errcode: 'M_LIMIT_EXCEEDED', error: 'Too Many Requests', retry_after_ms: retryMs }, 429, ); test('429 is retried after Retry-After, then succeeds', async () => { let n = 0; const waits: number[] = []; const mx = { setPresence: async () => { n += 1; if (n < 3) throw limited(3000); return {}; }, }; await setPresenceWithRetry( mx, { presence: 'online', status_msg: 'hi' }, { sleepFn: async (ms) => { waits.push(ms); }, }, ); assert.equal(n, 3); assert.deepEqual(waits, [3000, 3000]); }); test('gives up once the total wait would exceed the cap; other errors are not retried', async () => { const mx = { setPresence: async () => { throw limited(20_000); }, }; await assert.rejects( () => setPresenceWithRetry( mx, { presence: 'online' }, { maxWaitMs: 25_000, sleepFn: async () => undefined }, ), /Too Many/, ); let calls = 0; const forbidden = { setPresence: async () => { calls += 1; throw new MatrixError({ errcode: 'M_FORBIDDEN', error: 'nope' }, 403); }, }; await assert.rejects(() => setPresenceWithRetry(forbidden, { presence: 'online' })); assert.equal(calls, 1); }); test('deduper skips identical writes and notices changes', () => { const d = new PresenceDeduper(); assert.equal(d.shouldSend({ presence: 'online', status_msg: 'a' }), true); d.sent({ presence: 'online', status_msg: 'a' }); assert.equal(d.shouldSend({ presence: 'online', status_msg: 'a' }), false); assert.equal(d.shouldSend({ presence: 'unavailable', status_msg: 'a' }), true); assert.equal(d.shouldSend({ presence: 'online', status_msg: 'b' }), true); d.reset(); assert.equal(d.shouldSend({ presence: 'online', status_msg: 'a' }), true); }); test('error wording', () => { assert.match(describePresenceError(limited()), /once every 10 seconds/); assert.equal( describePresenceError( new MatrixError({ errcode: 'M_FORBIDDEN', error: 'Presence is disabled' }, 403), ), 'Failed to save status: Presence is disabled', ); assert.match(describePresenceError(new TypeError('Failed to fetch')), /couldn't reach/); });