Skip to content

test: cover SSE reconnect cleanup, settings fallback, streaming pause, and malformed events (#1781, #1782, #1783, #1784) - #1811

Open
mskdylan wants to merge 1 commit into
LabsCrypt:mainfrom
mskdylan:test/issues-1781-1782-1783-1784-hook-regression-tests
Open

mskdylan wants to merge 1 commit into
LabsCrypt:mainfrom
mskdylan:test/issues-1781-1782-1783-1784-hook-regression-tests

Conversation

@mskdylan

Copy link
Copy Markdown

Summary

Test-only PR that adds deterministic regression tests for four hook-level issues in one coordinated change. No production code was modified — every test asserts the hooks' existing documented behavior and error contracts. All tests use Vitest fake timers and controlled clocks (no real sleeps).

#1783 — SSE reconnect timer cleanup (frontend/src/__tests__/useStreamEvents.test.tsx)

  • Unmounting while a reconnect backoff timer is pending clears the timer (vi.getTimerCount() → 0) and no new EventSource is ever created, even after advancing the clock far past the delay.
  • Unmounting one tick (1 ms) before the retry delay elapses leaves no timers and no reconnect.
  • Unmount closes the active connection; events emitted on the stale source afterwards are dropped.
  • A burst of repeated error events in the same tick schedules exactly one reconnect timer (no stacking), and the grown backoff delay is honored.
  • After the reconnect-attempt cap (20) is exhausted, no timers remain scheduled.
  • reconnecting/connected/error state is correct while a retry is pending and cleans up on unmount.

#1784 — Invalid decimal settings fallback (frontend/src/hooks/useSettings.test.ts)

  • Missing or empty stored flowfi-decimal-places falls back to the documented default of 7.
  • Supported values 2/4/7 hydrate and format at exactly the requested precision (boundaries covered).
  • Fractional stored values (4.9, 2.7) are truncated to their integer prefix per parseInt semantics; leading zeros and surrounding whitespace are tolerated.
  • Out-of-range values (12, 100) stay parseable but formatting never exceeds the 7 fractional digits that exist on-chain.
  • Negative values (-2) never throw; malformed values (abc, seven, NaN, —) yield NaN and degrade to integer-only formatting without throwing.
  • The hook hydrates malformed/out-of-range values without crashing, and a valid value set afterwards is applied (recovery). Empty currency/format values fall back to USD/full.

#1781 — Streaming amount pause transitions (frontend/src/hooks/useStreamingAmount.test.tsx)

  • Initial state is 0 at stream start and accrues normally.
  • Pausing freezes the value, removes the frame loop (0 timers); resuming restores accrual from the pre-pause value with exactly one frame loop (no duplicate timers).
  • Repeated pause/resume cycles exclude paused time via totalPausedDuration and keep timer counts consistent.
  • Boundary cases: stream paused at its start time stays 0; zero-rate and fully-withdrawn streams never schedule a frame loop.
  • Clock drift: a 60 s wall-clock jump does not affect frame-driven accrual; the visibilitychange resync corrects the value to true elapsed time without duplicating timers.
  • Unmount while streaming cancels the frame loop (cancelAnimationFrame, 0 timers) and no stale ticker mutates state; unmount while paused leaves nothing scheduled.

#1782 — Malformed SSE event recovery (frontend/src/__tests__/useStreamEvents.test.tsx)

  • Malformed JSON, plain text, and empty payloads on subscribed event types are silently ignored (no crash, no error state, connection stays healthy, no reconnect timers scheduled).
  • Valid events delivered after malformed payloads are processed normally.
  • Unknown event types never reach the hook (transport-level contract) and do not affect processing.
  • Partially delivered frames are treated as malformed per the parser contract; interleaved malformed payloads never corrupt the event list (order and contents verified).

Tests executed (actual results)

Command (in frontend/) Result
npx vitest run src/__tests__/useStreamEvents.test.tsx src/hooks/useSettings.test.ts src/hooks/useStreamingAmount.test.tsx src/__tests__/useStreamingAmount.test.tsx ✅ 4 files, all tests passed (33 new tests added)
npm run test (full frontend suite, re-run on this branch rebased on main) ✅ 80 files, 768/768 tests passed
npm run test:coverage ✅ passed, thresholds met
npm run lint ✅ 0 errors (18 pre-existing warnings, none in touched files)
npx tsc --noEmit ✅ clean
npm run build (Next.js) ✅ passed

No existing tests were weakened, skipped, or deleted; no flaky real-time waits were introduced.

Closes #1781
Closes #1782
Closes #1783
Closes #1784

…, and malformed events

Add deterministic regression tests for four hook-level issues:

- LabsCrypt#1783: unmounting useStreamEvents during a pending reconnect clears the
  backoff timer, closes the EventSource, and never reconnects; repeated
  error bursts keep exactly one timer and honor the attempt cap.
- LabsCrypt#1784: invalid decimal settings (missing, empty, negative, out-of-range,
  malformed, fractional) fall back per the parseInt contract without
  throwing, and valid values still apply after invalid ones.
- LabsCrypt#1781: useStreamingAmount freezes on pause, resumes without duplicate
  frame loops, excludes paused time across repeated cycles, resyncs after
  clock drift, and cleans up when unmounted while streaming or paused.
- LabsCrypt#1782: malformed JSON, unknown event types, and partial frames are
  ignored without corrupting subsequent valid event processing.

All tests use fake timers and controlled clocks; no production code changed.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant