Download packages/core/src/sandbox/utils/proactivePermissions.test.ts from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 6.92 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/core/src/sandbox/utils/proactivePermissions.test.ts
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/core/src/sandbox/utils/proactivePermissions.test.ts
-
curl -L -o proactivePermissions.test.ts https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/core/src/sandbox/utils/proactivePermissions.test.ts
6.92 kB
| /** | |
| * @license | |
| * Copyright 2026 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { describe, it, expect, vi, beforeEach } from 'vitest'; | |
| import { | |
| getProactiveToolSuggestions, | |
| isNetworkReliantCommand, | |
| } from './proactivePermissions.js'; | |
| import os from 'node:os'; | |
| import path from 'node:path'; | |
| import fs from 'node:fs'; | |
| vi.mock('node:os'); | |
| vi.mock('node:fs', () => ({ | |
| default: { | |
| promises: { | |
| access: vi.fn(), | |
| }, | |
| constants: { | |
| F_OK: 0, | |
| }, | |
| }, | |
| promises: { | |
| access: vi.fn(), | |
| }, | |
| constants: { | |
| F_OK: 0, | |
| }, | |
| })); | |
| describe('proactivePermissions', () => { | |
| const homeDir = '/Users/testuser'; | |
| beforeEach(() => { | |
| vi.clearAllMocks(); | |
| vi.mocked(os.homedir).mockReturnValue(homeDir); | |
| vi.mocked(os.platform).mockReturnValue('darwin'); | |
| }); | |
| describe('isNetworkReliantCommand', () => { | |
| it('should return true for always-network tools', () => { | |
| expect(isNetworkReliantCommand('ssh')).toBe(true); | |
| expect(isNetworkReliantCommand('git')).toBe(true); | |
| expect(isNetworkReliantCommand('curl')).toBe(true); | |
| }); | |
| it('should return true for network-heavy node subcommands', () => { | |
| expect(isNetworkReliantCommand('npm', 'install')).toBe(true); | |
| expect(isNetworkReliantCommand('yarn', 'add')).toBe(true); | |
| expect(isNetworkReliantCommand('bun', '')).toBe(true); | |
| }); | |
| it('should return false for local node subcommands', () => { | |
| expect(isNetworkReliantCommand('npm', 'test')).toBe(false); | |
| expect(isNetworkReliantCommand('yarn', 'run')).toBe(false); | |
| }); | |
| it('should return false for unknown tools', () => { | |
| expect(isNetworkReliantCommand('ls')).toBe(false); | |
| }); | |
| }); | |
| describe('getProactiveToolSuggestions', () => { | |
| it('should return undefined for unknown tools', async () => { | |
| expect(await getProactiveToolSuggestions('ls')).toBeUndefined(); | |
| expect(await getProactiveToolSuggestions('node')).toBeUndefined(); | |
| }); | |
| it('should return permissions for npm if paths exist', async () => { | |
| vi.mocked(fs.promises.access).mockImplementation( | |
| (p: fs.PathLike, _mode?: number) => { | |
| const pathStr = p.toString(); | |
| if ( | |
| pathStr === path.join(homeDir, '.npm') || | |
| pathStr === path.join(homeDir, '.cache') || | |
| pathStr === path.join(homeDir, '.npmrc') | |
| ) { | |
| return Promise.resolve(); | |
| } | |
| return Promise.reject(new Error('ENOENT')); | |
| }, | |
| ); | |
| const permissions = await getProactiveToolSuggestions('npm'); | |
| expect(permissions).toBeDefined(); | |
| expect(permissions?.network).toBe(true); | |
| // .npmrc should be read-only | |
| expect(permissions?.fileSystem?.read).toContain( | |
| path.join(homeDir, '.npmrc'), | |
| ); | |
| expect(permissions?.fileSystem?.write).not.toContain( | |
| path.join(homeDir, '.npmrc'), | |
| ); | |
| // .npm should be read-write | |
| expect(permissions?.fileSystem?.read).toContain( | |
| path.join(homeDir, '.npm'), | |
| ); | |
| expect(permissions?.fileSystem?.write).toContain( | |
| path.join(homeDir, '.npm'), | |
| ); | |
| // .cache should be read-write | |
| expect(permissions?.fileSystem?.write).toContain( | |
| path.join(homeDir, '.cache'), | |
| ); | |
| // should NOT contain .ssh or .gitconfig for npm | |
| expect(permissions?.fileSystem?.read).not.toContain( | |
| path.join(homeDir, '.ssh'), | |
| ); | |
| }); | |
| it('should grant network access and suggest primary cache paths even if they do not exist', async () => { | |
| vi.mocked(fs.promises.access).mockRejectedValue(new Error('ENOENT')); | |
| const permissions = await getProactiveToolSuggestions('npm'); | |
| expect(permissions).toBeDefined(); | |
| expect(permissions?.network).toBe(true); | |
| expect(permissions?.fileSystem?.write).toContain( | |
| path.join(homeDir, '.npm'), | |
| ); | |
| // .cache is optional and should NOT be included if it doesn't exist | |
| expect(permissions?.fileSystem?.write).not.toContain( | |
| path.join(homeDir, '.cache'), | |
| ); | |
| }); | |
| it('should suggest .ssh and .gitconfig only for git', async () => { | |
| vi.mocked(fs.promises.access).mockImplementation( | |
| (p: fs.PathLike, _mode?: number) => { | |
| const pathStr = p.toString(); | |
| if ( | |
| pathStr === path.join(homeDir, '.ssh') || | |
| pathStr === path.join(homeDir, '.gitconfig') | |
| ) { | |
| return Promise.resolve(); | |
| } | |
| return Promise.reject(new Error('ENOENT')); | |
| }, | |
| ); | |
| const permissions = await getProactiveToolSuggestions('git'); | |
| expect(permissions?.network).toBe(true); | |
| expect(permissions?.fileSystem?.read).toContain( | |
| path.join(homeDir, '.ssh'), | |
| ); | |
| expect(permissions?.fileSystem?.read).toContain( | |
| path.join(homeDir, '.gitconfig'), | |
| ); | |
| }); | |
| it('should suggest .ssh but NOT .gitconfig for ssh', async () => { | |
| vi.mocked(fs.promises.access).mockImplementation( | |
| (p: fs.PathLike, _mode?: number) => { | |
| const pathStr = p.toString(); | |
| if (pathStr === path.join(homeDir, '.ssh')) { | |
| return Promise.resolve(); | |
| } | |
| return Promise.reject(new Error('ENOENT')); | |
| }, | |
| ); | |
| const permissions = await getProactiveToolSuggestions('ssh'); | |
| expect(permissions?.network).toBe(true); | |
| expect(permissions?.fileSystem?.read).toContain( | |
| path.join(homeDir, '.ssh'), | |
| ); | |
| expect(permissions?.fileSystem?.read).not.toContain( | |
| path.join(homeDir, '.gitconfig'), | |
| ); | |
| }); | |
| it('should handle Windows specific paths', async () => { | |
| vi.mocked(os.platform).mockReturnValue('win32'); | |
| const appData = 'C:\\Users\\testuser\\AppData\\Roaming'; | |
| vi.stubEnv('AppData', appData); | |
| vi.mocked(fs.promises.access).mockImplementation( | |
| (p: fs.PathLike, _mode?: number) => { | |
| const pathStr = p.toString(); | |
| if (pathStr === path.join(appData, 'npm')) { | |
| return Promise.resolve(); | |
| } | |
| return Promise.reject(new Error('ENOENT')); | |
| }, | |
| ); | |
| const permissions = await getProactiveToolSuggestions('npm.exe'); | |
| expect(permissions).toBeDefined(); | |
| expect(permissions?.fileSystem?.read).toContain( | |
| path.join(appData, 'npm'), | |
| ); | |
| vi.unstubAllEnvs(); | |
| }); | |
| it('should include bun, pnpm, and yarn specific paths', async () => { | |
| vi.mocked(fs.promises.access).mockResolvedValue(undefined); | |
| const bun = await getProactiveToolSuggestions('bun'); | |
| expect(bun?.fileSystem?.read).toContain(path.join(homeDir, '.bun')); | |
| expect(bun?.fileSystem?.read).not.toContain(path.join(homeDir, '.yarn')); | |
| const yarn = await getProactiveToolSuggestions('yarn'); | |
| expect(yarn?.fileSystem?.read).toContain(path.join(homeDir, '.yarn')); | |
| }); | |
| }); | |
| }); | |