Fix CLI auth tests localStorage issue (#135)#137
Conversation
- Fixed 'Cannot initialize local storage' error in Node.js v20+ - Created custom Jest environment to disable localStorage initialization - Implemented comprehensive auth command tests (10 tests, all passing) - Tests cover login, logout, and getConfig functionality - Tests include success cases, error handling, and edge cases - Properly mock axios, fs, os, and readline modules Fixes #135
There was a problem hiding this comment.
Pull request overview
This PR fixes the localStorage initialization error that occurs with Jest in Node.js v20+ for CLI authentication tests. The error was caused by Jest's Node environment attempting to initialize Node.js's experimental localStorage API, which the CLI doesn't actually use (it uses file-based storage instead).
Changes:
- Created a custom Jest environment that patches global localStorage/sessionStorage to prevent initialization errors
- Replaced placeholder tests in auth.test.ts.skip with 10 comprehensive tests covering login, logout, and getConfig functions
- Added proper mocking for dependencies (axios, fs, os, readline) with correct initialization order
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| apps/cli/src/tests/commands/auth.test.ts.skip | Removed placeholder/skipped tests that were waiting for localStorage fix |
| apps/cli/src/tests/commands/auth.test.ts | Added comprehensive auth tests with proper mocking and error handling coverage |
| apps/cli/jest-environment-node-no-storage.js | Custom Jest environment that prevents localStorage initialization by patching global object |
| apps/cli/jest.env.setup.js | Setup file that deletes localStorage/sessionStorage from global scope |
| apps/cli/jest.config.ts | Updated to use custom environment and setup file |
| // Prevent Node.js from initializing localStorage | ||
| delete global.localStorage; | ||
| delete global.sessionStorage; |
There was a problem hiding this comment.
The jest.env.setup.js file appears to be redundant. The custom Jest environment jest-environment-node-no-storage.js already handles removing localStorage and sessionStorage from the test global in its constructor (lines 34-35). Since setupFilesAfterEnv runs after the environment is initialized, this file is performing the same deletion operation a second time, which is unnecessary and could cause confusion about which mechanism is actually solving the localStorage issue.
| // Prevent Node.js from initializing localStorage | |
| delete global.localStorage; | |
| delete global.sessionStorage; | |
| // Note: The custom Jest environment `jest-environment-node-no-storage.js` | |
| // is responsible for removing `localStorage` and `sessionStorage` from the | |
| // global object. This file is intentionally left without side effects to | |
| // avoid duplicating that logic. |
| preset: '../../jest.preset.js', | ||
| testEnvironment: 'node', | ||
| testEnvironment: '<rootDir>/jest-environment-node-no-storage.js', | ||
| setupFilesAfterEnv: ['<rootDir>/jest.env.setup.js'], |
There was a problem hiding this comment.
The setupFilesAfterEnv configuration is redundant since the custom environment jest-environment-node-no-storage.js already handles removing localStorage and sessionStorage. The setup file performs the same deletion that's already done in the custom environment's constructor.
| setupFilesAfterEnv: ['<rootDir>/jest.env.setup.js'], |
| mockedFs.readFileSync.mockReturnValue( | ||
| JSON.stringify({ | ||
| accessToken: 'token', | ||
| refreshToken: 'refresh', | ||
| user: mockUser, | ||
| }) | ||
| ); |
There was a problem hiding this comment.
The mockUser object includes accessToken and refreshToken at the top level, but when used as the user property in the config object, these tokens should not be included. According to the AuthConfig interface in auth.ts, the user property should only contain userId, email, firstName, lastName, and role fields. The tokens should be at the top level of the config alongside the user object, not inside it.
This causes the test to verify against an incorrect data structure. The logout function reads the config to get the user's first name, and while this test may pass, it's testing against the wrong shape of data.
| const mockConfig = { | ||
| accessToken: 'token', | ||
| refreshToken: 'refresh', | ||
| user: mockUser, | ||
| }; |
There was a problem hiding this comment.
The mockUser object includes accessToken and refreshToken fields, but when used as the user property in the config object, these tokens should not be included. According to the AuthConfig interface, the user property should only contain userId, email, firstName, lastName, and role. The tokens belong at the top level of the config object, not nested inside the user object.
This causes the test to verify against an incorrect data structure.
Description
Fixes #135 - CLI authentication tests were failing with a localStorage initialization error in Node.js v20+.
Changes Made
Fixed localStorage Issue
jest-environment-node-no-storage.js) that patches Node.js global localStorage before Jest initializes--localstorage-filepath" error that occurs with jest-environment-node in Node.js v20+Implemented Comprehensive Auth Tests
Test Implementation Details
axios,fs,os,readlineRoot Cause
The CLI doesn't actually use
localStorage- it uses file-based storage (fs.readFileSync/fs.writeFileSync). The error was coming from Jest's Node environment trying to initialize Node.js's experimental localStorage API in v20+, which requires a file path.Solution
Created a custom Jest environment that:
global.localStoragebefore Jest environment initializationTesting
Related Issues
Checklist