@@ -12,48 +12,46 @@ import {
1212 beforeEach ,
1313 afterEach ,
1414 type MockInstance ,
15- type Mock ,
1615} from 'vitest' ;
1716import { handleInstall , installCommand } from './install.js' ;
1817import yargs from 'yargs' ;
1918import * as core from '@google/gemini-cli-core' ;
20- import {
21- ExtensionManager ,
22- type inferInstallMetadata ,
23- } from '../../config/extension-manager.js' ;
24- import type {
25- promptForConsentNonInteractive ,
26- requestConsentNonInteractive ,
27- } from '../../config/extensions/consent.js' ;
28- import type {
29- isWorkspaceTrusted ,
30- loadTrustedFolders ,
31- } from '../../config/trustedFolders.js' ;
32- import type * as fs from 'node:fs/promises' ;
3319import type { Stats } from 'node:fs' ;
3420import * as path from 'node:path' ;
21+ import { promptForSetting } from '../../config/extensions/extensionSettings.js' ;
22+
23+ const {
24+ mockInstallOrUpdateExtension,
25+ mockLoadExtensions,
26+ mockExtensionManager,
27+ mockRequestConsentNonInteractive,
28+ mockPromptForConsentNonInteractive,
29+ mockStat,
30+ mockInferInstallMetadata,
31+ mockIsWorkspaceTrusted,
32+ mockLoadTrustedFolders,
33+ mockDiscover,
34+ } = vi . hoisted ( ( ) => {
35+ const mockLoadExtensions = vi . fn ( ) ;
36+ const mockInstallOrUpdateExtension = vi . fn ( ) ;
37+ const mockExtensionManager = vi . fn ( ) . mockImplementation ( ( ) => ( {
38+ loadExtensions : mockLoadExtensions ,
39+ installOrUpdateExtension : mockInstallOrUpdateExtension ,
40+ } ) ) ;
3541
36- const mockInstallOrUpdateExtension : Mock <
37- typeof ExtensionManager . prototype . installOrUpdateExtension
38- > = vi . hoisted ( ( ) => vi . fn ( ) ) ;
39- const mockRequestConsentNonInteractive : Mock <
40- typeof requestConsentNonInteractive
41- > = vi . hoisted ( ( ) => vi . fn ( ) ) ;
42- const mockPromptForConsentNonInteractive : Mock <
43- typeof promptForConsentNonInteractive
44- > = vi . hoisted ( ( ) => vi . fn ( ) ) ;
45- const mockStat : Mock < typeof fs . stat > = vi . hoisted ( ( ) => vi . fn ( ) ) ;
46- const mockInferInstallMetadata : Mock < typeof inferInstallMetadata > = vi . hoisted (
47- ( ) => vi . fn ( ) ,
48- ) ;
49- const mockIsWorkspaceTrusted : Mock < typeof isWorkspaceTrusted > = vi . hoisted ( ( ) =>
50- vi . fn ( ) ,
51- ) ;
52- const mockLoadTrustedFolders : Mock < typeof loadTrustedFolders > = vi . hoisted ( ( ) =>
53- vi . fn ( ) ,
54- ) ;
55- const mockDiscover : Mock < typeof core . FolderTrustDiscoveryService . discover > =
56- vi . hoisted ( ( ) => vi . fn ( ) ) ;
42+ return {
43+ mockLoadExtensions,
44+ mockInstallOrUpdateExtension,
45+ mockExtensionManager,
46+ mockRequestConsentNonInteractive : vi . fn ( ) ,
47+ mockPromptForConsentNonInteractive : vi . fn ( ) ,
48+ mockStat : vi . fn ( ) ,
49+ mockInferInstallMetadata : vi . fn ( ) ,
50+ mockIsWorkspaceTrusted : vi . fn ( ) ,
51+ mockLoadTrustedFolders : vi . fn ( ) ,
52+ mockDiscover : vi . fn ( ) ,
53+ } ;
54+ } ) ;
5755
5856vi . mock ( '../../config/extensions/consent.js' , ( ) => ( {
5957 requestConsentNonInteractive : mockRequestConsentNonInteractive ,
@@ -84,6 +82,7 @@ vi.mock('../../config/extension-manager.js', async (importOriginal) => ({
8482 ...( await importOriginal <
8583 typeof import ( '../../config/extension-manager.js' )
8684 > ( ) ) ,
85+ ExtensionManager : mockExtensionManager ,
8786 inferInstallMetadata : mockInferInstallMetadata ,
8887} ) ) ;
8988
@@ -117,19 +116,18 @@ describe('handleInstall', () => {
117116 let processSpy : MockInstance ;
118117
119118 beforeEach ( ( ) => {
120- debugLogSpy = vi . spyOn ( core . debugLogger , 'log' ) ;
121- debugErrorSpy = vi . spyOn ( core . debugLogger , 'error' ) ;
119+ debugLogSpy = vi
120+ . spyOn ( core . debugLogger , 'log' )
121+ . mockImplementation ( ( ) => { } ) ;
122+ debugErrorSpy = vi
123+ . spyOn ( core . debugLogger , 'error' )
124+ . mockImplementation ( ( ) => { } ) ;
122125 processSpy = vi
123126 . spyOn ( process , 'exit' )
124127 . mockImplementation ( ( ) => undefined as never ) ;
125128
126- vi . spyOn ( ExtensionManager . prototype , 'loadExtensions' ) . mockResolvedValue (
127- [ ] ,
128- ) ;
129- vi . spyOn (
130- ExtensionManager . prototype ,
131- 'installOrUpdateExtension' ,
132- ) . mockImplementation ( mockInstallOrUpdateExtension ) ;
129+ mockLoadExtensions . mockResolvedValue ( [ ] ) ;
130+ mockInstallOrUpdateExtension . mockReset ( ) ;
133131
134132 mockIsWorkspaceTrusted . mockReturnValue ( { isTrusted : true , source : 'file' } ) ;
135133 mockDiscover . mockResolvedValue ( {
@@ -163,12 +161,7 @@ describe('handleInstall', () => {
163161 } ) ;
164162
165163 afterEach ( ( ) => {
166- mockInstallOrUpdateExtension . mockClear ( ) ;
167- mockRequestConsentNonInteractive . mockClear ( ) ;
168- mockStat . mockClear ( ) ;
169- mockInferInstallMetadata . mockClear ( ) ;
170164 vi . clearAllMocks ( ) ;
171- vi . restoreAllMocks ( ) ;
172165 } ) ;
173166
174167 function createMockExtension (
@@ -288,6 +281,39 @@ describe('handleInstall', () => {
288281 expect ( processSpy ) . toHaveBeenCalledWith ( 1 ) ;
289282 } ) ;
290283
284+ it ( 'should pass promptForSetting when skipSettings is not provided' , async ( ) => {
285+ mockInstallOrUpdateExtension . mockResolvedValue ( {
286+ name : 'test-extension' ,
287+ } as unknown as core . GeminiCLIExtension ) ;
288+
289+ await handleInstall ( {
290+ source : 'http://google.com' ,
291+ } ) ;
292+
293+ expect ( mockExtensionManager ) . toHaveBeenCalledWith (
294+ expect . objectContaining ( {
295+ requestSetting : promptForSetting ,
296+ } ) ,
297+ ) ;
298+ } ) ;
299+
300+ it ( 'should pass null for requestSetting when skipSettings is true' , async ( ) => {
301+ mockInstallOrUpdateExtension . mockResolvedValue ( {
302+ name : 'test-extension' ,
303+ } as unknown as core . GeminiCLIExtension ) ;
304+
305+ await handleInstall ( {
306+ source : 'http://google.com' ,
307+ skipSettings : true ,
308+ } ) ;
309+
310+ expect ( mockExtensionManager ) . toHaveBeenCalledWith (
311+ expect . objectContaining ( {
312+ requestSetting : null ,
313+ } ) ,
314+ ) ;
315+ } ) ;
316+
291317 it ( 'should proceed if local path is already trusted' , async ( ) => {
292318 mockInstallOrUpdateExtension . mockResolvedValue (
293319 createMockExtension ( {
0 commit comments