@@ -2,10 +2,14 @@ import { Command } from 'commander'
22import { afterEach , beforeEach , describe , expect , it , vi } from 'vitest'
33
44// Mock the auth module
5- vi . mock ( '../lib/auth.js' , ( ) => ( {
6- saveApiToken : vi . fn ( ) ,
7- clearApiToken : vi . fn ( ) ,
8- } ) )
5+ vi . mock ( '../lib/auth.js' , async ( importOriginal ) => {
6+ const actual = await importOriginal < typeof import ( '../lib/auth.js' ) > ( )
7+ return {
8+ ...actual ,
9+ saveApiToken : vi . fn ( ) ,
10+ clearApiToken : vi . fn ( ) ,
11+ }
12+ } )
913
1014// Mock the api module
1115vi . mock ( '../lib/api/core.js' , ( ) => ( {
@@ -54,7 +58,7 @@ import { createInterface, type Interface } from 'node:readline'
5458import open from 'open'
5559import { registerAuthCommand } from '../commands/auth.js'
5660import { getApi } from '../lib/api/core.js'
57- import { clearApiToken , saveApiToken } from '../lib/auth.js'
61+ import { NoTokenError , clearApiToken , saveApiToken } from '../lib/auth.js'
5862import { startCallbackServer } from '../lib/oauth-server.js'
5963import { exchangeCodeForToken } from '../lib/oauth.js'
6064import { createMockApi } from './helpers/mock-api.js'
@@ -88,6 +92,7 @@ describe('auth command', () => {
8892 afterEach ( ( ) => {
8993 consoleSpy . mockRestore ( )
9094 errorSpy . mockRestore ( )
95+ process . exitCode = undefined
9196 } )
9297
9398 describe ( 'token subcommand' , ( ) => {
@@ -328,18 +333,37 @@ describe('auth command', () => {
328333
329334 it ( 'outputs JSON error when --json flag is used and not authenticated' , async ( ) => {
330335 const program = createProgram ( )
331- mockGetApi . mockRejectedValue ( new Error ( 'No API token found' ) )
336+ mockGetApi . mockRejectedValue ( new NoTokenError ( ) )
332337
333338 await program . parseAsync ( [ 'node' , 'td' , 'auth' , 'status' , '--json' ] )
334339
335340 expect ( consoleSpy ) . toHaveBeenCalledWith (
336341 JSON . stringify ( { error : 'Not authenticated' } , null , 2 ) ,
337342 )
343+ expect ( process . exitCode ) . toBe ( 1 )
344+ } )
345+
346+ it ( 'rethrows non-auth errors in JSON mode' , async ( ) => {
347+ const program = createProgram ( )
348+ mockGetApi . mockRejectedValue ( new Error ( 'Network timeout' ) )
349+
350+ await expect (
351+ program . parseAsync ( [ 'node' , 'td' , 'auth' , 'status' , '--json' ] ) ,
352+ ) . rejects . toThrow ( 'Network timeout' )
353+ } )
354+
355+ it ( 'rethrows non-auth errors in human-readable mode' , async ( ) => {
356+ const program = createProgram ( )
357+ mockGetApi . mockRejectedValue ( new Error ( 'Network timeout' ) )
358+
359+ await expect ( program . parseAsync ( [ 'node' , 'td' , 'auth' , 'status' ] ) ) . rejects . toThrow (
360+ 'Network timeout' ,
361+ )
338362 } )
339363
340364 it ( 'shows not authenticated when no token' , async ( ) => {
341365 const program = createProgram ( )
342- mockGetApi . mockRejectedValue ( new Error ( 'No API token found' ) )
366+ mockGetApi . mockRejectedValue ( new NoTokenError ( ) )
343367
344368 await program . parseAsync ( [ 'node' , 'td' , 'auth' , 'status' ] )
345369
0 commit comments