fix(cli): resolve environment loading and auth validation issues in ACP mode (#18025)

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
Bryan Morgan
2026-02-03 00:54:10 -05:00
committed by GitHub
parent 1b274b081d
commit e7bfd2bf83
12 changed files with 477 additions and 40 deletions

View File

@@ -29,10 +29,11 @@ vi.mock('./settings.js', async (importActual) => {
});
// Mock trustedFolders
import * as trustedFolders from './trustedFolders.js';
vi.mock('./trustedFolders.js', () => ({
isWorkspaceTrusted: vi
.fn()
.mockReturnValue({ isTrusted: true, source: 'file' }),
isWorkspaceTrusted: vi.fn(),
isFolderTrustEnabled: vi.fn(),
loadTrustedFolders: vi.fn(),
}));
vi.mock('./settingsSchema.js', async (importOriginal) => {
@@ -151,7 +152,7 @@ describe('Settings Loading and Merging', () => {
(mockFsExistsSync as Mock).mockReturnValue(false);
(fs.readFileSync as Mock).mockReturnValue('{}'); // Return valid empty JSON
(mockFsMkdirSync as Mock).mockImplementation(() => undefined);
vi.mocked(isWorkspaceTrusted).mockReturnValue({
vi.spyOn(trustedFolders, 'isWorkspaceTrusted').mockReturnValue({
isTrusted: true,
source: 'file',
});
@@ -1635,7 +1636,7 @@ describe('Settings Loading and Merging', () => {
});
it('should NOT merge workspace settings when workspace is not trusted', () => {
vi.mocked(isWorkspaceTrusted).mockReturnValue({
vi.spyOn(trustedFolders, 'isWorkspaceTrusted').mockReturnValue({
isTrusted: false,
source: 'file',
});
@@ -1666,23 +1667,60 @@ describe('Settings Loading and Merging', () => {
expect(settings.merged.context?.fileName).toBe('USER.md'); // User setting
expect(settings.merged.ui?.theme).toBe('dark'); // User setting
});
it('should NOT merge workspace settings when workspace trust is undefined', () => {
vi.spyOn(trustedFolders, 'isWorkspaceTrusted').mockReturnValue({
isTrusted: undefined,
source: undefined,
});
(mockFsExistsSync as Mock).mockReturnValue(true);
const userSettingsContent = {
ui: { theme: 'dark' },
tools: { sandbox: false },
context: { fileName: 'USER.md' },
};
const workspaceSettingsContent = {
tools: { sandbox: true },
context: { fileName: 'WORKSPACE.md' },
};
(fs.readFileSync as Mock).mockImplementation(
(p: fs.PathOrFileDescriptor) => {
if (p === USER_SETTINGS_PATH)
return JSON.stringify(userSettingsContent);
if (p === MOCK_WORKSPACE_SETTINGS_PATH)
return JSON.stringify(workspaceSettingsContent);
return '{}';
},
);
const settings = loadSettings(MOCK_WORKSPACE_DIR);
expect(settings.merged.tools?.sandbox).toBe(false); // User setting
expect(settings.merged.context?.fileName).toBe('USER.md'); // User setting
});
});
describe('loadEnvironment', () => {
function setup({
isFolderTrustEnabled = true,
isWorkspaceTrustedValue = true,
isWorkspaceTrustedValue = true as boolean | undefined,
}) {
delete process.env['TESTTEST']; // reset
const geminiEnvPath = path.resolve(path.join(GEMINI_DIR, '.env'));
const geminiEnvPath = path.resolve(
path.join(MOCK_WORKSPACE_DIR, GEMINI_DIR, '.env'),
);
vi.mocked(isWorkspaceTrusted).mockReturnValue({
vi.spyOn(trustedFolders, 'isWorkspaceTrusted').mockReturnValue({
isTrusted: isWorkspaceTrustedValue,
source: 'file',
});
(mockFsExistsSync as Mock).mockImplementation((p: fs.PathLike) =>
[USER_SETTINGS_PATH, geminiEnvPath].includes(p.toString()),
);
(mockFsExistsSync as Mock).mockImplementation((p: fs.PathLike) => {
const normalizedP = path.resolve(p.toString());
return [path.resolve(USER_SETTINGS_PATH), geminiEnvPath].includes(
normalizedP,
);
});
const userSettingsContent: Settings = {
ui: {
theme: 'dark',
@@ -1698,9 +1736,10 @@ describe('Settings Loading and Merging', () => {
};
(fs.readFileSync as Mock).mockImplementation(
(p: fs.PathOrFileDescriptor) => {
if (p === USER_SETTINGS_PATH)
const normalizedP = path.resolve(p.toString());
if (normalizedP === path.resolve(USER_SETTINGS_PATH))
return JSON.stringify(userSettingsContent);
if (p === geminiEnvPath) return 'TESTTEST=1234';
if (normalizedP === geminiEnvPath) return 'TESTTEST=1234';
return '{}';
},
);
@@ -1708,14 +1747,34 @@ describe('Settings Loading and Merging', () => {
it('sets environment variables from .env files', () => {
setup({ isFolderTrustEnabled: false, isWorkspaceTrustedValue: true });
loadEnvironment(loadSettings(MOCK_WORKSPACE_DIR).merged);
const settings = {
security: { folderTrust: { enabled: false } },
} as Settings;
loadEnvironment(settings, MOCK_WORKSPACE_DIR, isWorkspaceTrusted);
expect(process.env['TESTTEST']).toEqual('1234');
});
it('does not load env files from untrusted spaces', () => {
setup({ isFolderTrustEnabled: true, isWorkspaceTrustedValue: false });
loadEnvironment(loadSettings(MOCK_WORKSPACE_DIR).merged);
const settings = {
security: { folderTrust: { enabled: true } },
} as Settings;
loadEnvironment(settings, MOCK_WORKSPACE_DIR, isWorkspaceTrusted);
expect(process.env['TESTTEST']).not.toEqual('1234');
});
it('does not load env files when trust is undefined', () => {
delete process.env['TESTTEST'];
// isWorkspaceTrusted returns {isTrusted: undefined} for matched rules with no trust value, or no matching rules.
setup({ isFolderTrustEnabled: true, isWorkspaceTrustedValue: undefined });
const settings = {
security: { folderTrust: { enabled: true } },
} as Settings;
const mockTrustFn = vi.fn().mockReturnValue({ isTrusted: undefined });
loadEnvironment(settings, MOCK_WORKSPACE_DIR, mockTrustFn);
expect(process.env['TESTTEST']).not.toEqual('1234');
});
@@ -1731,7 +1790,7 @@ describe('Settings Loading and Merging', () => {
mockFsExistsSync.mockReturnValue(true);
mockFsReadFileSync = vi.mocked(fs.readFileSync);
mockFsReadFileSync.mockReturnValue('{}');
vi.mocked(isWorkspaceTrusted).mockReturnValue({
vi.spyOn(trustedFolders, 'isWorkspaceTrusted').mockReturnValue({
isTrusted: true,
source: undefined,
});