# Tasks: enterprise-network-testing **Change ID**: enterprise-network-testing **Package**: `@suaveplan/network-testing` **Target path**: `universal/network/network-testing` **Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/testing` --- ## 1. Scaffold - [x] Create `universal/network/network-testing/` with `src/`, `tests/`, and all feature subdirectories. - [x] Write `package.json` at version `0.1.0`: `"sideEffects": false`, exports map, deps per `proposal.md`. - [x] Write `tsconfig.json`, `vitest.config.ts`, scripts. --- ## 2. Types and error codes - [x] Define all public types in `src/types/common.ts`: `MemoryTransport`, `MemoryTransportPair`, `MemoryTransportOptions`, `FakeWebSocketAdapter`, `FakeWebSocketHandle`, `FakeWebSocketOptions`, `NetworkConditions`, `LatencyDistribution`, `ConditionSimulator`, `SimulationStats`, `TestPeer`, `TestPeerOptions`, `NetworkEventCapture`. - [x] Write `src/types/common.md` (≥200 words, simple + advanced examples). - [x] Define error codes in `src/error-codes.ts`. - [x] Write Zod schemas in `src/types/schemas.ts` + `src/types/schemas.md`. --- ## 3. Memory transport (`src/transports/memory-transport/`) - [x] Implement `createMemoryTransport(options?)` — returns `MemoryTransportPair`: - Two ends share a queue; `client.send(m)` pushes to `server.messages`, calls `server`'s `onmessage`. - `connect()` sets both ends to `connected`. - `disconnect()` sets both ends to `disconnected`, fires `ondisconnect`. - Injectable `Clock` for `latencyMs` simulation (use `setTimeout` equivalent on clock). - [x] Write `memory-transport.test.ts` (≤500 lines): send client→server, server→client, disconnect, latency. - [x] Write `memory-transport.md` (≥200 words). --- ## 4. Fake WebSocket adapter (`src/transports/fake-websocket/`) - [x] Implement `createFakeWebSocketAdapter(options?)`: - `connect(url, protocols?)` — creates a `FakeWebSocketHandle`, stores in `connections`. - `simulateMessage(data)` — calls `onmessage` on all handles. - `simulateError(error)` — calls `onerror` on all handles. - `simulateClose(code?, reason?)` — calls `onclose` on all handles. - `FakeWebSocketHandle.send(data)` — pushes to `sentMessages`. - `autoConnect: true` (default) calls `onopen` immediately after `connect`. - [x] Write `fake-websocket.test.ts` (≤500 lines): connect, send tracked, simulateMessage received, close, error. - [x] Write `fake-websocket.md` (≥200 words). --- ## 5. Condition simulator (`src/simulators/condition-simulator/`) - [x] Implement `createConditionSimulator(conditions)`: - `wrap(transport)` — returns a proxy that intercepts `send()`: - Roll packet drop: if `rng.next() < conditions.packetLossRate`, drop (return without sending). - Compute latency: sample from `conditions.latencyMs` distribution using injectable `Rng`. - Add jitter: ± `conditions.jitterMs` random offset. - After delay, call real `transport.send()`. - `setConditions(partial)` — update conditions on the fly. - `reset()` — restore original conditions, clear stats. - Track `sentMessages`, `droppedMessages`, `totalLatencyMs`. - [x] Write `condition-simulator.test.ts` (≤500 lines): packet drop rate, latency added, stats tracked. - [x] Write `condition-simulator.md` (≥200 words). --- ## 6. Test peer factory (`src/factories/test-peer/`) - [x] Implement `createTestPeer(options?)`: - Auto-generates `id` (`test-peer-${n}`) and `address` (`127.0.0.1:${port}`). - Fluent builder: `withCapabilities`, `withRegion`, `withHealth`. - `asRegistryEntry()` — returns `RegistryEntry` compatible shape. - `asBootstrapSeed()` — returns `SeedConfig` compatible shape. - [x] Write `test-peer.test.ts` + `test-peer.md`. --- ## 7. Network event capture (`src/assertions/event-capture/`) - [x] Implement `createNetworkEventCapture(eventBus)`: - Subscribes to all events on the bus; pushes to `events` array. - `waitFor(event, timeout?)` — returns a `Promise` that resolves when the event fires; rejects after timeout. - `assertEventEmitted(event, predicate?)` — throws `NetworkTestingError(NET_TEST_EVENT_NOT_EMITTED)` if not found. - `assertEventCount(event, count)` — throws if actual count !== expected. - `clear()` — empties `events`. - [x] Write `event-capture.test.ts` + `event-capture.md`. --- ## 8. Integration test (`tests/integration.test.ts`) - [x] Create a `MemoryTransportPair`, send messages, verify receipt. - [x] Wrap a transport with `ConditionSimulator` (50% packet loss), send 100 messages, verify ~50 dropped. - [x] Use `FakeWebSocketAdapter` with a hypothetical client, simulate messages, verify received. --- ## 9. Docs and verify - [x] All per-file `.md` files per layout in `proposal.md`. - [x] `universal/network/network-testing/README.md`. - [x] `bunx turbo lint typecheck test test:coverage --filter=@suaveplan/network-testing` — all green, 100%. - [x] `bun scripts/publish.ts --package @suaveplan/network-testing`. - [x] Update `CLAUDE.md`. Archive change folder.