test(e2e): scheduled messages and offline outbox; retry rate-limited scheduled-message calls #476

Merged
jared merged 1 commits from test/lotus-feature-e2e into lotus 2026-10-28 07:03:36 -04:00
Owner

New end-to-end coverage for two Lotus features the October audit (#281) listed as untested. Each step is checked against the server, not just the UI.

e2e/scheduled-messages.spec.ts

  • Schedule a message two hours ahead: the tray shows "1 scheduled message", the server holds exactly one delayed event in this room, and nothing is in the timeline.
  • Send now: the message arrives exactly once, and the delayed event is gone.
  • Cancel a second one: it's gone from the server, and its text never appears in /messages.

e2e/offline-outbox.spec.ts

  • Offline: three messages each show "Queued. Will send when you're back online".
  • Back online: the server has each message exactly once and in order, and the queued marks clear.

A bug found by the new test, and fixed

  • Cause: Synapse rate-limits delayed-event management per user (listing, send now, cancel and restart all count). A quick "Send now" followed by "Cancel" got HTTP 429, so the tray showed "Could not cancel this message. Try again." even though nothing was wrong.
  • Fix: all scheduled-message calls (schedule, list, send now, cancel, restart) now go through withRateLimitRetry. It waits out Retry-After (at least 200 ms, at most 10 s per wait, 15 s in total) and retries. A 429 means the request wasn't processed, and scheduling reuses its txnId, so a retry can't duplicate anything.
  • Unit test for the helper: it retries a 429 and then succeeds; other errors and waits over budget throw.

Tested

  • Both specs pass 3/3 with --repeat-each=3; boot passes.
  • 1,447 unit tests pass; lint is at 28 warnings; Prettier is clean.

Not covered yet: calls, the soundboard and call PiP. They need LiveKit, which scripts/dev-homeserver.sh only starts in its calls mode, not in CI.

🤖 Generated with Claude Code

https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5

New end-to-end coverage for two Lotus features the October audit (#281) listed as untested. Each step is checked **against the server**, not just the UI. **`e2e/scheduled-messages.spec.ts`** - **Schedule** a message two hours ahead: the tray shows "1 scheduled message", the server holds exactly one delayed event in this room, and nothing is in the timeline. - **Send now:** the message arrives exactly once, and the delayed event is gone. - **Cancel** a second one: it's gone from the server, and its text never appears in `/messages`. **`e2e/offline-outbox.spec.ts`** - **Offline:** three messages each show "Queued. Will send when you're back online". - **Back online:** the server has each message **exactly once and in order**, and the queued marks clear. **A bug found by the new test, and fixed** - **Cause:** Synapse rate-limits delayed-event management per user (listing, send now, cancel and restart all count). A quick "Send now" followed by "Cancel" got **HTTP 429**, so the tray showed "Could not cancel this message. Try again." even though nothing was wrong. - **Fix:** all scheduled-message calls (schedule, list, send now, cancel, restart) now go through `withRateLimitRetry`. It waits out `Retry-After` (at least 200 ms, at most 10 s per wait, 15 s in total) and retries. A 429 means the request wasn't processed, and scheduling reuses its txnId, so a retry can't duplicate anything. - **Unit test** for the helper: it retries a 429 and then succeeds; other errors and waits over budget throw. **Tested** - Both specs pass 3/3 with `--repeat-each=3`; boot passes. - 1,447 unit tests pass; lint is at 28 warnings; Prettier is clean. **Not covered yet:** calls, the soundboard and call PiP. They need LiveKit, which `scripts/dev-homeserver.sh` only starts in its `calls` mode, not in CI. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared added 1 commit 2026-10-28 06:41:07 -04:00
test(e2e): scheduled messages and offline outbox; retry rate-limited scheduled-message calls
CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Build & Quality Checks (pull_request) Successful in 3m16s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 8s
CI / Playwright smoke (e2e) (pull_request) Successful in 19m2s
56af9520bd
New end-to-end coverage for two Lotus features the October audit listed as
untested, checked against the server at each step:
- scheduled-messages.spec: schedule (tray + one delayed event on the
  server), Send now (arrives once, delayed event gone), cancel (gone from the
  server, never sent).
- offline-outbox.spec: offline, three messages show "Queued. Will send when
  you are back online"; back online, the server has each exactly once and in
  order; the queued marks clear.

The scheduled-messages test found a real bug: Synapse rate-limits delayed
event management per user, and a quick Send now then Cancel got a 429, so
the tray showed "Could not cancel this message" although nothing was wrong.
All scheduled-message calls (schedule, list, send now, cancel, restart) now
wait out a 429 (Retry-After, bounded) and retry; scheduling reuses its txnId.
Unit test for the retry helper.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared scheduled this pull request to auto merge when all checks succeed 2026-10-28 06:41:12 -04:00
jared merged commit 843a48dd10 into lotus 2026-10-28 07:03:36 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#476