test(cli): migrate comprehensive test suite from test/cli-integration-coverage#427
test(cli): migrate comprehensive test suite from test/cli-integration-coverage#427dongmucat wants to merge 5 commits into
Conversation
…-coverage Migrated 39 test files covering CLI integration and unit testing: - 6 new integration tests (auth-resolution, concurrency, cross-command, inventory-resilience, multi-registry, version-upgrade-flow) - Enhanced 7 existing integration tests with comprehensive scenarios - Updated 2 unit tests with correct exit code expectations All tests use fake registry approach (no E2E/browser required) and pass lint/build/test checks.
There was a problem hiding this comment.
Code Review
This pull request significantly expands the integration test suite, adding comprehensive coverage for authentication resolution, concurrency, cross-command flows, and specific command behaviors like install, publish, and doctor. It introduces critical checks for symlink safety and server error mapping. However, the PR removes a substantial number of unit tests for NpmRegistryClient, leading to a regression in coverage for registry resolution and error handling. Additionally, a contradiction was identified in a test case where the name implies a non-zero exit code while the assertion allows for success.
| test('classifies network failures as CLI errors', async () => { | ||
| const failingFetch = (async () => { | ||
| throw new TypeError('fetch failed') | ||
| }) as unknown as typeof fetch | ||
| const client = new NpmRegistryClient(failingFetch, 10_000, { | ||
| NPM_CONFIG_REGISTRY: 'https://registry.example.test' | ||
| }) | ||
| const client = new NpmRegistryClient(failingFetch) | ||
|
|
||
| await expect(client.latestVersion()).rejects.toMatchObject({ | ||
| message: 'npm registry unreachable', | ||
| exitCode: 3, | ||
| details: { | ||
| registry: 'https://registry.example.test', | ||
| cause: 'fetch failed', | ||
| next: 'check npm registry/proxy configuration and retry' | ||
| } | ||
| }) | ||
| }) | ||
|
|
||
| test('reports registry context for non-2xx responses', async () => { | ||
| const failingFetch = (async () => new Response('{}', { status: 503 })) as unknown as typeof fetch | ||
| const client = new NpmRegistryClient(failingFetch, 10_000, { | ||
| SKILLHUB_NPM_REGISTRY: 'https://registry.example.test' | ||
| }) | ||
|
|
||
| await expect(client.latestVersion()).rejects.toMatchObject({ | ||
| message: 'npm registry returned 503', | ||
| exitCode: 3, | ||
| details: { | ||
| registry: 'https://registry.example.test' | ||
| } | ||
| }) | ||
| }) | ||
|
|
||
| test('rejects registry responses without a version', async () => { | ||
| const failingFetch = (async () => Response.json({ name: '@astron-team/skillhub' })) as unknown as typeof fetch | ||
| const client = new NpmRegistryClient(failingFetch, 10_000, { | ||
| npm_config_registry: 'https://registry.example.test' | ||
| }) | ||
|
|
||
| await expect(client.latestVersion()).rejects.toMatchObject({ | ||
| message: 'npm registry response missing version', | ||
| exitCode: 3, | ||
| details: { | ||
| registry: 'https://registry.example.test' | ||
| } | ||
| }) | ||
| }) | ||
|
|
||
| test('rejects invalid JSON registry responses', async () => { | ||
| const failingFetch = (async () => new Response('<html>not json</html>')) as unknown as typeof fetch | ||
| const client = new NpmRegistryClient(failingFetch, 10_000, { | ||
| npm_config_registry: 'https://registry.example.test' | ||
| }) | ||
|
|
||
| await expect(client.latestVersion()).rejects.toMatchObject({ | ||
| message: 'npm registry response invalid', | ||
| exitCode: 3, | ||
| details: { | ||
| registry: 'https://registry.example.test' | ||
| } | ||
| }) | ||
| }) | ||
|
|
||
| test('rejects invalid registry configuration', async () => { | ||
| const client = new NpmRegistryClient(fetch, 10_000, { | ||
| npm_config_registry: 'https://[' | ||
| }) | ||
|
|
||
| await expect(client.latestVersion()).rejects.toMatchObject({ | ||
| message: 'invalid npm registry URL', | ||
| exitCode: 5, | ||
| details: { | ||
| registry: 'https://[', | ||
| next: 'check npm registry configuration and retry' | ||
| } | ||
| exitCode: 3 | ||
| }) | ||
| }) |
There was a problem hiding this comment.
This PR removes nearly all unit tests for NpmRegistryClient, resulting in a significant regression in test coverage. The deleted tests covered critical logic including registry resolution priority (e.g., SKILLHUB_NPM_REGISTRY vs npm_config_registry), case-insensitive environment variable handling, and various error conditions (non-2xx responses, malformed JSON, missing fields).
Furthermore, the remaining test has been weakened by removing assertions on the details object of the CliError. Since the implementation in cli/src/clients/npm-registry-client.ts still contains this logic and populates these details, these tests should be preserved and updated to match current conventions rather than being discarded.
| } | ||
| }) | ||
|
|
||
| test('publish response missing required fields surfaces a non-zero exit', async () => { |
There was a problem hiding this comment.
The test name contradicts the implementation. The name states that it verifies a "non-zero exit", but the assertion on line 489 (expect([0, 1, 2, 3]).toContain(result.exitCode)) allows for a successful exit code of 0.
If the intention is to verify that the CLI does not crash (as suggested by the comment on line 487), the test name should be updated to reflect that it is verifying "no-crash" behavior. If the intention is to enforce an error state for invalid server responses, the assertion should be tightened to exclude 0.
| test('publish response missing required fields surfaces a non-zero exit', async () => { | |
| test('publish response missing required fields does not crash (no-crash pin)', async () => { |
- Fix Windows test failure by using regex that accepts both / and \ path separators in install-command.test.ts - Rename contradictory test case in publish-command.test.ts from "surfaces a non-zero exit" to "is handled without crash" to match actual assertion behavior
Windows ZIP library produces backslashes in file paths while Unix uses forward slashes. Normalize all paths to forward slashes before assertion to ensure tests pass on all platforms.
Ensures both key listing and content access work on Windows by normalizing all ZIP entry keys to forward slashes immediately after unzipSync.
6a35719 to
cedf839
Compare
…name Restore 9 deleted unit tests covering registry URL resolution priority, case-insensitive env lookup, empty env fallback, default registry, non-2xx responses, invalid JSON, missing version, and invalid registry URL. Fix misleading test name in publish-command: 503 maps to EXIT.network (not EXIT.generic) per the 502/503 special-case in skillhub-client.ts.
Summary
Migrated comprehensive CLI test suite from the
test/cli-integration-coveragebranch to improve test coverage and maintainability.Test Results
Changes
15 files changed: +2,934 lines, -142 lines