Download packages/cli/src/config/extension-manager-scope.test.ts from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 6.78 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/config/extension-manager-scope.test.ts
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/cli/src/config/extension-manager-scope.test.ts
-
curl -L -o extension-manager-scope.test.ts https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/cli/src/config/extension-manager-scope.test.ts
6.78 kB
| /** | |
| * @license | |
| * Copyright 2025 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; | |
| import * as fs from 'node:fs'; | |
| import * as path from 'node:path'; | |
| import * as os from 'node:os'; | |
| import { ExtensionManager } from './extension-manager.js'; | |
| import { createTestMergedSettings } from './settings.js'; | |
| import { cleanupTmpDir } from '@google/gemini-cli-test-utils'; | |
| import { | |
| loadAgentsFromDirectory, | |
| loadSkillsFromDir, | |
| } from '@google/gemini-cli-core'; | |
| let currentTempHome = ''; | |
| vi.mock('@google/gemini-cli-core', async (importOriginal) => { | |
| const actual = | |
| await importOriginal<typeof import('@google/gemini-cli-core')>(); | |
| return { | |
| ...actual, | |
| homedir: () => currentTempHome, | |
| debugLogger: { | |
| log: vi.fn(), | |
| error: vi.fn(), | |
| warn: vi.fn(), | |
| }, | |
| loadAgentsFromDirectory: vi.fn().mockImplementation(async () => ({ | |
| agents: [], | |
| errors: [], | |
| })), | |
| loadSkillsFromDir: vi.fn().mockImplementation(async () => []), | |
| }; | |
| }); | |
| describe('ExtensionManager Settings Scope', () => { | |
| const extensionName = 'test-extension'; | |
| let tempWorkspace: string; | |
| let extensionsDir: string; | |
| let extensionDir: string; | |
| beforeEach(async () => { | |
| vi.mocked(loadAgentsFromDirectory).mockResolvedValue({ | |
| agents: [], | |
| errors: [], | |
| }); | |
| vi.mocked(loadSkillsFromDir).mockResolvedValue([]); | |
| currentTempHome = fs.mkdtempSync( | |
| path.join(os.tmpdir(), 'gemini-cli-test-home-'), | |
| ); | |
| tempWorkspace = fs.mkdtempSync( | |
| path.join(os.tmpdir(), 'gemini-cli-test-workspace-'), | |
| ); | |
| extensionsDir = path.join(currentTempHome, '.gemini', 'extensions'); | |
| extensionDir = path.join(extensionsDir, extensionName); | |
| fs.mkdirSync(extensionDir, { recursive: true }); | |
| // Create gemini-extension.json | |
| const extensionConfig = { | |
| name: extensionName, | |
| version: '1.0.0', | |
| settings: [ | |
| { | |
| name: 'Test Setting', | |
| envVar: 'TEST_SETTING', | |
| description: 'A test setting', | |
| }, | |
| ], | |
| }; | |
| fs.writeFileSync( | |
| path.join(extensionDir, 'gemini-extension.json'), | |
| JSON.stringify(extensionConfig), | |
| ); | |
| // Create install metadata | |
| const installMetadata = { | |
| source: extensionDir, | |
| type: 'local', | |
| }; | |
| fs.writeFileSync( | |
| path.join(extensionDir, 'install-metadata.json'), | |
| JSON.stringify(installMetadata), | |
| ); | |
| }); | |
| afterEach(async () => { | |
| await cleanupTmpDir(currentTempHome); | |
| await cleanupTmpDir(tempWorkspace); | |
| vi.clearAllMocks(); | |
| }); | |
| it('should prioritize workspace settings over user settings and report correct scope', async () => { | |
| // 1. Set User Setting | |
| const userSettingsPath = path.join(extensionDir, '.env'); | |
| fs.writeFileSync(userSettingsPath, 'TEST_SETTING=user-value'); | |
| // 2. Set Workspace Setting | |
| const workspaceSettingsPath = path.join(tempWorkspace, '.env'); | |
| fs.writeFileSync(workspaceSettingsPath, 'TEST_SETTING=workspace-value'); | |
| const extensionManager = new ExtensionManager({ | |
| workspaceDir: tempWorkspace, | |
| requestConsent: async () => true, | |
| requestSetting: async () => '', | |
| settings: createTestMergedSettings({ | |
| telemetry: { enabled: false }, | |
| experimental: { extensionConfig: true }, | |
| security: { folderTrust: { enabled: false } }, | |
| }), | |
| }); | |
| const extensions = await extensionManager.loadExtensions(); | |
| const extension = extensions.find((e) => e.name === extensionName); | |
| expect(extension).toBeDefined(); | |
| // Verify resolved settings | |
| const setting = extension?.resolvedSettings?.find( | |
| (s) => s.envVar === 'TEST_SETTING', | |
| ); | |
| expect(setting).toBeDefined(); | |
| expect(setting?.value).toBe('workspace-value'); | |
| expect(setting?.scope).toBe('workspace'); | |
| expect(setting?.source).toBe(workspaceSettingsPath); | |
| // Verify output string contains (Workspace - <path>) | |
| const output = extensionManager.toOutputString(extension!); | |
| expect(output).toContain( | |
| `Test Setting: workspace-value (Workspace - ${workspaceSettingsPath})`, | |
| ); | |
| }); | |
| it('should fallback to user settings if workspace setting is missing', async () => { | |
| // 1. Set User Setting | |
| const userSettingsPath = path.join(extensionDir, '.env'); | |
| fs.writeFileSync(userSettingsPath, 'TEST_SETTING=user-value'); | |
| // 2. No Workspace Setting | |
| const extensionManager = new ExtensionManager({ | |
| workspaceDir: tempWorkspace, | |
| requestConsent: async () => true, | |
| requestSetting: async () => '', | |
| settings: createTestMergedSettings({ | |
| telemetry: { enabled: false }, | |
| experimental: { extensionConfig: true }, | |
| security: { folderTrust: { enabled: false } }, | |
| }), | |
| }); | |
| const extensions = await extensionManager.loadExtensions(); | |
| const extension = extensions.find((e) => e.name === extensionName); | |
| expect(extension).toBeDefined(); | |
| // Verify resolved settings | |
| const setting = extension?.resolvedSettings?.find( | |
| (s) => s.envVar === 'TEST_SETTING', | |
| ); | |
| expect(setting).toBeDefined(); | |
| expect(setting?.value).toBe('user-value'); | |
| expect(setting?.scope).toBe('user'); | |
| expect(setting?.source?.endsWith(path.join(extensionName, '.env'))).toBe( | |
| true, | |
| ); | |
| // Verify output string contains (User - <path>) | |
| const output = extensionManager.toOutputString(extension!); | |
| expect(output).toContain( | |
| `Test Setting: user-value (User - ${userSettingsPath})`, | |
| ); | |
| }); | |
| it('should report unset if neither is present', async () => { | |
| // No settings files | |
| const extensionManager = new ExtensionManager({ | |
| workspaceDir: tempWorkspace, | |
| requestConsent: async () => true, | |
| requestSetting: async () => '', | |
| settings: createTestMergedSettings({ | |
| telemetry: { enabled: false }, | |
| experimental: { extensionConfig: true }, | |
| security: { folderTrust: { enabled: false } }, | |
| }), | |
| }); | |
| const extensions = await extensionManager.loadExtensions(); | |
| const extension = extensions.find((e) => e.name === extensionName); | |
| expect(extension).toBeDefined(); | |
| // Verify resolved settings | |
| const setting = extension?.resolvedSettings?.find( | |
| (s) => s.envVar === 'TEST_SETTING', | |
| ); | |
| expect(setting).toBeDefined(); | |
| expect(setting?.value).toBeUndefined(); | |
| expect(setting?.scope).toBeUndefined(); | |
| // Verify output string does not contain scope | |
| const output = extensionManager.toOutputString(extension!); | |
| expect(output).toContain('Test Setting: [not set]'); | |
| expect(output).not.toContain('Test Setting: [not set] (User)'); | |
| expect(output).not.toContain('Test Setting: [not set] (Workspace)'); | |
| }); | |
| }); | |