| |
| |
| |
| |
| |
|
|
| |
|
|
| import { describe, it, expect, vi, beforeEach, type Mock } from 'vitest'; |
| import * as fs from 'node:fs'; |
|
|
| const mockCoreEvents = vi.hoisted(() => ({ |
| emitFeedback: vi.fn(), |
| emitConsoleLog: vi.fn(), |
| emitOutput: vi.fn(), |
| emitModelChanged: vi.fn(), |
| drainBacklogs: vi.fn(), |
| })); |
|
|
| const mockIsWorkspaceTrusted = vi.hoisted(() => |
| vi.fn().mockReturnValue({ isTrusted: true, source: 'file' }), |
| ); |
|
|
| vi.mock('@google/gemini-cli-core', async (importOriginal) => { |
| const actual = |
| await importOriginal<typeof import('@google/gemini-cli-core')>(); |
| return { |
| ...actual, |
| coreEvents: mockCoreEvents, |
| homedir: () => '/mock/home/user', |
| Storage: class extends actual.Storage { |
| static override getGlobalSettingsPath = () => |
| '/mock/home/user/.gemini/settings.json'; |
| override getWorkspaceSettingsPath = () => |
| '/mock/workspace/.gemini/settings.json'; |
| static override getGlobalGeminiDir = () => '/mock/home/user/.gemini'; |
| }, |
| }; |
| }); |
|
|
| vi.mock('./trustedFolders.js', () => ({ |
| isWorkspaceTrusted: mockIsWorkspaceTrusted, |
| loadTrustedFolders: vi.fn().mockReturnValue({ |
| isPathTrusted: vi.fn().mockReturnValue(true), |
| user: { config: {} }, |
| errors: [], |
| }), |
| isFolderTrustEnabled: vi.fn().mockReturnValue(false), |
| TrustLevel: { |
| TRUST_FOLDER: 'TRUST_FOLDER', |
| TRUST_PARENT: 'TRUST_PARENT', |
| DO_NOT_TRUST: 'DO_NOT_TRUST', |
| }, |
| })); |
|
|
| vi.mock('os', async (importOriginal) => { |
| const actual = await importOriginal<typeof import('node:os')>(); |
| return { |
| ...actual, |
| homedir: () => '/mock/home/user', |
| platform: () => 'linux', |
| totalmem: () => 16 * 1024 * 1024 * 1024, |
| }; |
| }); |
|
|
| vi.mock('fs', async (importOriginal) => { |
| const actualFs = await importOriginal<typeof fs>(); |
| return { |
| ...actualFs, |
| existsSync: vi.fn(), |
| readFileSync: vi.fn(), |
| writeFileSync: vi.fn(), |
| mkdirSync: vi.fn(), |
| renameSync: vi.fn(), |
| realpathSync: (p: string) => p, |
| }; |
| }); |
|
|
| |
| import { |
| loadSettings, |
| USER_SETTINGS_PATH, |
| type LoadedSettings, |
| resetSettingsCacheForTesting, |
| } from './settings.js'; |
|
|
| const MOCK_WORKSPACE_DIR = '/mock/workspace'; |
|
|
| describe('Settings Validation Warning', () => { |
| beforeEach(() => { |
| vi.clearAllMocks(); |
| resetSettingsCacheForTesting(); |
| (fs.readFileSync as Mock).mockReturnValue('{}'); |
| (fs.existsSync as Mock).mockReturnValue(false); |
| }); |
|
|
| it('should emit a warning and NOT throw when settings are invalid', () => { |
| (fs.existsSync as Mock).mockImplementation( |
| (p: string) => p === USER_SETTINGS_PATH, |
| ); |
|
|
| const invalidSettingsContent = { |
| ui: { |
| customThemes: { |
| terafox: { |
| name: 'terafox', |
| type: 'custom', |
| DiffModified: '#ffffff', |
| }, |
| }, |
| }, |
| }; |
|
|
| (fs.readFileSync as Mock).mockImplementation((p: string) => { |
| if (p === USER_SETTINGS_PATH) |
| return JSON.stringify(invalidSettingsContent); |
| return '{}'; |
| }); |
|
|
| |
| let settings: LoadedSettings | undefined; |
| expect(() => { |
| settings = loadSettings(MOCK_WORKSPACE_DIR); |
| }).not.toThrow(); |
|
|
| |
| expect( |
| settings?.errors.some((e) => |
| e.message.includes("Unrecognized key(s) in object: 'DiffModified'"), |
| ), |
| ).toBe(true); |
| }); |
|
|
| it('should throw a fatal error when settings file is not a valid JSON object', () => { |
| (fs.existsSync as Mock).mockImplementation( |
| (p: string) => p === USER_SETTINGS_PATH, |
| ); |
|
|
| (fs.readFileSync as Mock).mockImplementation((p: string) => { |
| if (p === USER_SETTINGS_PATH) return '[]'; |
| return '{}'; |
| }); |
|
|
| expect(() => { |
| loadSettings(MOCK_WORKSPACE_DIR); |
| }).toThrow(); |
| }); |
|
|
| it('should throw a fatal error when settings file contains invalid JSON', () => { |
| (fs.existsSync as Mock).mockImplementation( |
| (p: string) => p === USER_SETTINGS_PATH, |
| ); |
|
|
| (fs.readFileSync as Mock).mockImplementation((p: string) => { |
| if (p === USER_SETTINGS_PATH) return '{ "invalid": "json", }'; |
| return '{}'; |
| }); |
|
|
| expect(() => { |
| loadSettings(MOCK_WORKSPACE_DIR); |
| }).toThrow(); |
| }); |
| }); |
|
|