Changeset 96c714f in Klonkt for test/push.test.js


Ignore:
Timestamp:
07/22/2026 07:12:11 AM (7 weeks ago)
Author:
Robin <roboburr@…>
Branches:
main
Children:
9a00f28
Parents:
8240e80
git-author:
Robin <roboburr@…> (07/22/2026 07:11:54 AM)
git-committer:
Robin <roboburr@…> (07/22/2026 07:12:11 AM)
Message:

Feature: web push slice 4, burst throttle + docs

  • Burst throttle: a wave of likes or a mass-follow becomes one ping, not a wave of pushes. Per (user, type) at most one push per window (like/boost 300s, follow 60s, reply/dm 30s, test never throttled); extras drop silently — the events themselves still land in Berichten, only the ping is deduped. In-memory (one process; a restart costs at most one extra ping). Pure throttled() exported and pinned by test.
  • README: push notifications feature bullet, VAPID_* in the config table, storage/.vapid in the auto-generated-secrets + backup section (restoring without it silently breaks every subscription).
  • .env.example: VAPID block in the SESSION_SECRET/PAID_SECRET style.

Pruning (404/410 → row deleted) and the iOS install hint already landed in
slices 1-2; this closes the plan from docs/webpush-design.md.

Changed files:
src/services/PushService.js

  • throttled() + window table; notifyUser checks it first

test/push.test.js

  • throttle windows, per-type/per-user independence, test bypass

README.md

  • feature bullet, VAPID config row, backup warning

.env.example

  • VAPID_PUBLIC_KEY / VAPID_PRIVATE_KEY / VAPID_SUBJECT

-robo
Co-Authored-By: Claude Opus 4.8 <noreply@…>

File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/push.test.js

    r8240e80 r96c714f  
    6565});
    6666
     67test('burst throttle: one ping per window per (user,type); test type never throttles', () => {
     68  assert.equal(Push.throttled('tu1', 'like', 1000), false);   // first passes
     69  assert.equal(Push.throttled('tu1', 'like', 1100), true);    // within 300s window
     70  assert.equal(Push.throttled('tu1', 'like', 1301), false);   // window elapsed
     71  assert.equal(Push.throttled('tu1', 'boost', 1000), false);  // other type independent
     72  assert.equal(Push.throttled('tu2', 'like', 1000), false);   // other user independent
     73  assert.equal(Push.throttled('tu1', 'test', 1000), false);   // test bypasses
     74  assert.equal(Push.throttled('tu1', 'test', 1001), false);
     75});
     76
    6777test('incomplete subscription payloads are refused', () => {
    6878  assert.equal(Push.saveSubscription({ endpoint: '', userId: 'u1', p256dh: 'x', auth: 'y' }), false);
Note: See TracChangeset for help on using the changeset viewer.