mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 21:32:56 -07:00
fix(cli): hide read-only settings scopes (#26249)
This commit is contained in:
@@ -25,7 +25,10 @@ import { waitFor } from '../../test-utils/async.js';
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
||||
import { SettingsDialog } from './SettingsDialog.js';
|
||||
import { SettingScope } from '../../config/settings.js';
|
||||
import { createMockSettings } from '../../test-utils/settings.js';
|
||||
import {
|
||||
createMockSettings,
|
||||
type MockSettingsFile,
|
||||
} from '../../test-utils/settings.js';
|
||||
import { makeFakeConfig } from '@google/gemini-cli-core';
|
||||
import { act } from 'react';
|
||||
import { TEST_ONLY } from '../../utils/settingsUtils.js';
|
||||
@@ -250,6 +253,17 @@ const renderDialog = async (
|
||||
},
|
||||
);
|
||||
|
||||
const createSettingsFile = (
|
||||
path: string,
|
||||
settings: Record<string, unknown> = {},
|
||||
readOnly?: boolean,
|
||||
): MockSettingsFile => ({
|
||||
settings,
|
||||
originalSettings: settings,
|
||||
path,
|
||||
readOnly,
|
||||
});
|
||||
|
||||
describe('SettingsDialog', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
@@ -618,6 +632,131 @@ describe('SettingsDialog', () => {
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should not offer read-only system settings as an editable target', async () => {
|
||||
const settings = createMockSettings({
|
||||
system: createSettingsFile('', {}, true),
|
||||
});
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, unmount } = await renderDialog(settings, onSelect);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(lastFrame()).toContain('Apply To');
|
||||
});
|
||||
|
||||
const output = lastFrame();
|
||||
expect(output).toContain('User Settings');
|
||||
expect(output).toContain('Workspace Settings');
|
||||
expect(output).not.toContain('System Settings');
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should not offer a read-only home-directory workspace as an editable target', async () => {
|
||||
const settings = createMockSettings({
|
||||
user: createSettingsFile('/mock/home/.gemini/settings.json'),
|
||||
system: createSettingsFile('/mock/system/settings.json', {}, true),
|
||||
systemDefaults: createSettingsFile(
|
||||
'/mock/system-defaults/settings.json',
|
||||
{},
|
||||
true,
|
||||
),
|
||||
workspace: createSettingsFile('', {}, true),
|
||||
});
|
||||
const setValueSpy = vi.spyOn(settings, 'setValue');
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(lastFrame()).toContain('Vim Mode');
|
||||
});
|
||||
|
||||
const output = lastFrame();
|
||||
expect(output).not.toContain('Workspace Settings');
|
||||
expect(output).not.toContain('System Settings');
|
||||
|
||||
await act(async () => {
|
||||
stdin.write(TerminalKeys.ENTER as string);
|
||||
});
|
||||
await waitUntilReady();
|
||||
|
||||
expect(setValueSpy).toHaveBeenCalledWith(
|
||||
SettingScope.User,
|
||||
'general.vimMode',
|
||||
true,
|
||||
);
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should fall back to the first writable scope when the selected scope is read-only', async () => {
|
||||
const settings = createMockSettings({
|
||||
user: createSettingsFile('', {}, true),
|
||||
system: createSettingsFile('', {}, true),
|
||||
workspace: createSettingsFile('/mock/workspace/.gemini/settings.json'),
|
||||
});
|
||||
const setValueSpy = vi.spyOn(settings, 'setValue');
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(lastFrame()).toContain('Vim Mode');
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
stdin.write(TerminalKeys.ENTER as string);
|
||||
});
|
||||
await waitUntilReady();
|
||||
|
||||
expect(setValueSpy).toHaveBeenCalledWith(
|
||||
SettingScope.Workspace,
|
||||
'general.vimMode',
|
||||
true,
|
||||
);
|
||||
|
||||
unmount();
|
||||
});
|
||||
|
||||
it('should not save when all editable scopes are read-only', async () => {
|
||||
const settings = createMockSettings({
|
||||
user: createSettingsFile('', {}, true),
|
||||
system: createSettingsFile('', {}, true),
|
||||
workspace: createSettingsFile(
|
||||
'/mock/workspace/.gemini/settings.json',
|
||||
{},
|
||||
true,
|
||||
),
|
||||
});
|
||||
const setValueSpy = vi.spyOn(settings, 'setValue');
|
||||
const onSelect = vi.fn();
|
||||
|
||||
const { lastFrame, stdin, unmount, waitUntilReady } = await renderDialog(
|
||||
settings,
|
||||
onSelect,
|
||||
);
|
||||
|
||||
await waitFor(() => {
|
||||
expect(lastFrame()).toContain('Vim Mode');
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
stdin.write(TerminalKeys.ENTER as string);
|
||||
});
|
||||
await waitUntilReady();
|
||||
|
||||
expect(setValueSpy).not.toHaveBeenCalled();
|
||||
|
||||
unmount();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Restart Prompt', () => {
|
||||
|
||||
Reference in New Issue
Block a user