Add comprehensive E2E test suite for error handling - #4
Merged
Conversation
- tests/auth.test.ts (T1-T3, T9-T13): loadCredentials, runSaveToken - tests/v1Client.test.ts (T4-T8): mocked fetch covers HTTP 401 and network errors - tests/cli.test.ts (T14-T16): subprocess test against built dist/index.js - tests/util.test.ts (T16): parseIntOption direct unit test - tests/helpers.ts: mocks process.exit + console; snapshots stderr at first exit so the v1Client catch-handler doesn't pollute assertions Adds vitest devDep, npm test / test:watch scripts, vitest.config.ts. https://claude.ai/code/session_013SjRYb8WkckP4ZVXyYSJYr
Replaces unit-test approach (which mocked process.exit, fs, and global.fetch inside the test process) with end-to-end tests that exercise the built CLI binary as a real subprocess. - tests/e2e.test.ts: single file, 16 cases organized by category (T1-T16) matching the original error-handling test plan. - tests/helpers.ts: runCli (async spawn + capture stdout/stderr/exit code), startMockServer (in-process HTTP server), tmp dir helpers. Note: runCli uses async spawn, not spawnSync. spawnSync would block the parent's event loop, freezing the in-process mock server's accept() loop and causing the CLI subprocess to hang on connect. T4-T5 (HTTP 401) and T8 (timeout) use a local mock HTTP server bound to 127.0.0.1:0 instead of hitting s-api.cookiy.ai. T6 picks an ephemeral port, closes the listener, then connects to get a deterministic ECONNREFUSED (avoids ":1" being rejected as a "bad port" by undici). https://claude.ai/code/session_013SjRYb8WkckP4ZVXyYSJYr
…bidden
- T4/T5: hit the real production API (no COOKIY_SERVER_URL override). The
real server returns 401 for fake tokens, exercising dieNoAccess() against
actual server behavior rather than a mock.
- T_403 (new): mock server returns 403 with "host not in allowlist" body.
The real API doesn't easily reproduce this, so a local mock is justified.
Verifies the CLI prints [HTTP 403] + body details and does NOT trigger
the auth-redirect banner (that path is reserved for missing/empty token
files and 401 responses).
- Annotated each describe block: [no network], [real network], [mock — ...],
[no mock] so it's obvious at a glance which tests reach external systems.
Mock usage summary:
• T_403 — mock 403 server (real API can't be made to return 403 easily)
• T8 — mock hanging server (real API responds in ms, not seconds)
• T6 — opens then immediately closes a local listener to get a closed
port; not strictly a mock, just a way to find a deterministically
refused address
All other tests use either pure local I/O (T1–T3, T9–T16) or the real
s-api.cookiy.ai (T4, T5) or real DNS lookups (T7).
https://claude.ai/code/session_013SjRYb8WkckP4ZVXyYSJYr
…st.ts - T_HTML (new): mock server returns 502 with an HTML body (typical reverse- proxy error page). Verifies that formatBody/summarizeHtml emits a one-line "(HTML body) <title>" summary instead of dumping raw HTML to stderr, and that the [HTTP 502] header is present. Real API returns JSON, so a mock is required to exercise this path. - Renamed tests/e2e.test.ts → tests/error-handling.e2e.test.ts to make the scope explicit (the file covers error-handling scenarios end-to-end). https://claude.ai/code/session_013SjRYb8WkckP4ZVXyYSJYr
Triggers: - pull_request (any branch → any base) - push to main - workflow_dispatch (manual) Job: test - ubuntu-latest, Node 22.x - npm ci → typecheck → build → npm test (vitest E2E) - 10-minute job timeout - npm cache via setup-node - concurrency group cancels superseded runs on the same ref Note: T4/T5 hit s-api.cookiy.ai over the public internet — accepted tradeoff for genuine integration coverage of the 401 response shape. https://claude.ai/code/session_013SjRYb8WkckP4ZVXyYSJYr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds a comprehensive end-to-end test suite that validates error handling across the CLI, covering token validation, HTTP error responses, network failures, the
save-tokencommand, and CLI argument parsing.Key Changes
New test file
tests/error-handling.e2e.test.ts: 16 test cases organized into 7 test suites covering:save-tokencommand validation and file writingNew test helpers
tests/helpers.ts: Utility functions for:Test configuration
vitest.config.ts: Vitest setup with Node environment and 20-second timeoutUpdated
package.json: Addedvitestas a dev dependency andtest/test:watchnpm scriptsNotable Implementation Details
spawnSync) to avoid blocking the parent event loop, which is necessary since mock HTTP servers run in the same Node processhttps://claude.ai/code/session_013SjRYb8WkckP4ZVXyYSJYr