11import { type UpdateCheckResult , checkForUpdate , printUpdateNotification } from '../update-notifier.js' ;
22import { rmSync } from 'fs' ;
3- import { mkdir , readFile , writeFile } from 'fs/promises' ;
3+ import { chmod , mkdir , readFile , writeFile } from 'fs/promises' ;
44import { join } from 'path' ;
55import { afterAll , afterEach , beforeEach , describe , expect , it , vi } from 'vitest' ;
66
7- const tmpDir = vi . hoisted ( ( ) => {
8- /* eslint-disable @typescript-eslint/no-require-imports */
9- const fs = require ( 'fs' ) ;
10- const os = require ( 'os' ) ;
11- const path = require ( 'path' ) ;
12- /* eslint-enable @typescript-eslint/no-require-imports */
13- return fs . mkdtempSync ( path . join ( os . tmpdir ( ) , 'update-notifier-test-' ) ) ;
14- } ) ;
7+ /* eslint-disable @typescript-eslint/no-require-imports -- vi.hoisted runs before ESM imports are available */
8+ const tmpDir = vi . hoisted ( ( ) =>
9+ require ( 'fs' ) . mkdtempSync ( require ( 'path' ) . join ( require ( 'os' ) . tmpdir ( ) , 'update-notifier-test-' ) )
10+ ) ;
11+ /* eslint-enable @typescript-eslint/no-require-imports */
12+
13+ const mockFetchLatestVersion = vi . hoisted ( ( ) => vi . fn ( ) ) ;
1514
1615vi . mock ( '../../lib/schemas/io/global-config.js' , ( ) => ( {
1716 GLOBAL_CONFIG_DIR : tmpDir ,
1817} ) ) ;
1918
20- vi . mock ( '../constants.js' , async importOriginal => {
21- const actual = await importOriginal < typeof import ( '../constants.js' ) > ( ) ;
22- return { ...actual , PACKAGE_VERSION : '1.0.0' } ;
23- } ) ;
24-
25- const { mockFetchLatestVersion } = vi . hoisted ( ( ) => ( {
26- mockFetchLatestVersion : vi . fn ( ) ,
19+ vi . mock ( '../constants.js' , async importOriginal => ( {
20+ ...( await importOriginal < typeof import ( '../constants.js' ) > ( ) ) ,
21+ PACKAGE_VERSION : '1.0.0' ,
2722} ) ) ;
2823
2924vi . mock ( '../commands/update/action.js' , async importOriginal => {
3025 const actual = await importOriginal < typeof import ( '../commands/update/action.js' ) > ( ) ;
3126 return { ...actual , fetchLatestVersion : mockFetchLatestVersion } ;
3227} ) ;
3328
34- const CACHE_DIR = tmpDir ;
3529const CACHE_FILE = join ( tmpDir , 'update-check.json' ) ;
3630
3731describe ( 'checkForUpdate' , ( ) => {
3832 beforeEach ( ( ) => {
3933 vi . spyOn ( Date , 'now' ) . mockReturnValue ( 1708646400000 ) ;
40- try {
41- rmSync ( CACHE_DIR , { recursive : true } ) ;
42- } catch { }
34+ rmSync ( tmpDir , { recursive : true , force : true } ) ;
4335 } ) ;
4436
4537 afterEach ( ( ) => {
@@ -48,7 +40,7 @@ describe('checkForUpdate', () => {
4840 } ) ;
4941
5042 afterAll ( ( ) => {
51- rmSync ( tmpDir , { recursive : true } ) ;
43+ rmSync ( tmpDir , { recursive : true , force : true } ) ;
5244 } ) ;
5345
5446 it ( 'fetches from registry when no cache exists' , async ( ) => {
@@ -61,7 +53,7 @@ describe('checkForUpdate', () => {
6153 } ) ;
6254
6355 it ( 'uses cache when last check was less than 24 hours ago' , async ( ) => {
64- await mkdir ( CACHE_DIR , { recursive : true } ) ;
56+ await mkdir ( tmpDir , { recursive : true } ) ;
6557 await writeFile ( CACHE_FILE , JSON . stringify ( { lastCheck : 1708646400000 - 1000 , latestVersion : '2.0.0' } ) , 'utf-8' ) ;
6658
6759 const result = await checkForUpdate ( ) ;
@@ -71,7 +63,7 @@ describe('checkForUpdate', () => {
7163 } ) ;
7264
7365 it ( 'fetches from registry when cache is expired' , async ( ) => {
74- await mkdir ( CACHE_DIR , { recursive : true } ) ;
66+ await mkdir ( tmpDir , { recursive : true } ) ;
7567 await writeFile (
7668 CACHE_FILE ,
7769 JSON . stringify ( { lastCheck : 1708646400000 - 25 * 60 * 60 * 1000 , latestVersion : '1.5.0' } ) ,
@@ -119,7 +111,7 @@ describe('checkForUpdate', () => {
119111 } ) ;
120112
121113 it ( 'returns null on cache parse error and fetch error' , async ( ) => {
122- await mkdir ( CACHE_DIR , { recursive : true } ) ;
114+ await mkdir ( tmpDir , { recursive : true } ) ;
123115 await writeFile ( CACHE_FILE , 'invalid json' , 'utf-8' ) ;
124116 mockFetchLatestVersion . mockRejectedValue ( new Error ( 'network error' ) ) ;
125117
@@ -129,18 +121,19 @@ describe('checkForUpdate', () => {
129121 } ) ;
130122
131123 it ( 'succeeds even when cache write fails' , async ( ) => {
132- await mkdir ( CACHE_DIR , { recursive : true } ) ;
124+ await mkdir ( tmpDir , { recursive : true } ) ;
133125 await writeFile ( CACHE_FILE , '' , 'utf-8' ) ;
134- const { chmod } = await import ( 'fs/promises' ) ;
135- await chmod ( CACHE_DIR , 0o444 ) ;
126+ await chmod ( tmpDir , 0o444 ) ;
136127
137- mockFetchLatestVersion . mockResolvedValue ( '2.0.0' ) ;
138-
139- const result = await checkForUpdate ( ) ;
128+ try {
129+ mockFetchLatestVersion . mockResolvedValue ( '2.0.0' ) ;
140130
141- expect ( result ) . toEqual ( { updateAvailable : true , latestVersion : '2.0.0' } ) ;
131+ const result = await checkForUpdate ( ) ;
142132
143- await chmod ( CACHE_DIR , 0o755 ) ;
133+ expect ( result ) . toEqual ( { updateAvailable : true , latestVersion : '2.0.0' } ) ;
134+ } finally {
135+ await chmod ( tmpDir , 0o755 ) ;
136+ }
144137 } ) ;
145138} ) ;
146139
0 commit comments