# test-utils ## Purpose `test-utils.tsx` provides the in-memory `FakeSession` and the `withProvider` wrapper used by every chunk-C hook + component test. The fake mirrors the canonical `StreamSessionLike` contract from the spec — same method names, same event channels — so tests exercise the real React render path without booting transports or audio engines. Tests inject the fake via the provider's `sessionFactory`, drive state mutations through the public API, and assert the rendered DOM, hook return value, and recorded method calls. The file lives at the package root rather than inside a feature directory because it is shared by every feature module; `vitest.config.ts` excludes it from coverage. ## Features - `FakeSession` — `StreamSessionLike` implementation with synchronous mutators, an internal `calls` recorder, and helpers (`pushPeer`, `setMixer`, `triggerInterruption`) that emit the matching event channel. - `withProvider(session)` — returns a `wrapper` suitable for `renderHook`/`render({ wrapper })`. - Strongly typed: every method signature matches the canonical spec so a compile-time break in chunks A+B surfaces here first. ## Usage: Basic ```tsx import { renderHook } from "@testing-library/react"; import { FakeSession, withProvider } from "../../test-utils.js"; import { useStreamSession } from "./use-stream-session.js"; const session = new FakeSession(); const { result } = renderHook(() => useStreamSession(), { wrapper: withProvider(session), }); ``` ## Usage: Advanced ```tsx const session = new FakeSession({ state: "joined", peers: [{ id: "alice", displayName: "Alice", connectionState: "connected", rttMs: 32 }], }); // Drive state changes deterministically: await act(async () => session.pushPeer({ id: "bob", ... })); expect(result.current.peers).toHaveLength(2); expect(session.calls.setTrackVolume).toEqual([["alice", -3]]); ``` ## API Reference - `FakeSessionInit` — constructor options bag. - `FakeSession` — `StreamSessionLike` plus `calls`, `pushPeer`, `setPeers`, `setMixer`, `setLocalLevel`, `setPeerLevel`, `triggerInterruption`. - `withProvider(session)` — `(props: { children }) => ReactNode`. ## Implementation Notes The fake's event-emit path is synchronous (no microtask hop) so test assertions can run immediately after the mutation without `act` for simple cases. When tests need to observe a React re-render fence, they wrap the mutator in `act(() => session.foo())`. The recorded `calls` arrays let solo-semantics tests verify that mutations route through the session's `setTrackVolume` / `setTrackMute` / `setTrackSolo` rather than being re-implemented inside the hook.