mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-05-13 05:12:55 -07:00
refactor: move toml-loader.test.ts to use real filesystem (#12969)
This commit is contained in:
@@ -4,72 +4,41 @@
|
|||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
||||||
import { ApprovalMode, PolicyDecision } from './types.js';
|
import { ApprovalMode, PolicyDecision } from './types.js';
|
||||||
import type { Dirent } from 'node:fs';
|
import * as fs from 'node:fs/promises';
|
||||||
import nodePath from 'node:path';
|
import * as path from 'node:path';
|
||||||
|
import * as os from 'node:os';
|
||||||
|
import { loadPoliciesFromToml } from './toml-loader.js';
|
||||||
import type { PolicyLoadResult } from './toml-loader.js';
|
import type { PolicyLoadResult } from './toml-loader.js';
|
||||||
|
|
||||||
async function runLoadPoliciesFromToml(
|
|
||||||
tomlContent: string,
|
|
||||||
fileName = 'test.toml',
|
|
||||||
): Promise<PolicyLoadResult> {
|
|
||||||
const actualFs =
|
|
||||||
await vi.importActual<typeof import('node:fs/promises')>(
|
|
||||||
'node:fs/promises',
|
|
||||||
);
|
|
||||||
|
|
||||||
const mockReaddir = vi.fn(
|
|
||||||
async (
|
|
||||||
path: string,
|
|
||||||
_options?: { withFileTypes: boolean },
|
|
||||||
): Promise<Dirent[]> => {
|
|
||||||
if (nodePath.normalize(path) === nodePath.normalize('/policies')) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: fileName,
|
|
||||||
isFile: () => true,
|
|
||||||
isDirectory: () => false,
|
|
||||||
} as Dirent,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const mockReadFile = vi.fn(async (path: string): Promise<string> => {
|
|
||||||
if (
|
|
||||||
nodePath.normalize(path) ===
|
|
||||||
nodePath.normalize(nodePath.join('/policies', fileName))
|
|
||||||
) {
|
|
||||||
return tomlContent;
|
|
||||||
}
|
|
||||||
throw new Error('File not found');
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.doMock('node:fs/promises', () => ({
|
|
||||||
...actualFs,
|
|
||||||
default: { ...actualFs, readFile: mockReadFile, readdir: mockReaddir },
|
|
||||||
readFile: mockReadFile,
|
|
||||||
readdir: mockReaddir,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { loadPoliciesFromToml: load } = await import('./toml-loader.js');
|
|
||||||
|
|
||||||
const getPolicyTier = (_dir: string) => 1;
|
|
||||||
return load(ApprovalMode.DEFAULT, ['/policies'], getPolicyTier);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('policy-toml-loader', () => {
|
describe('policy-toml-loader', () => {
|
||||||
beforeEach(() => {
|
let tempDir: string;
|
||||||
vi.resetModules();
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
tempDir = await fs.mkdtemp(path.join(os.tmpdir(), 'policy-test-'));
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {
|
afterEach(async () => {
|
||||||
vi.restoreAllMocks();
|
if (tempDir) {
|
||||||
vi.doUnmock('node:fs/promises');
|
await fs.rm(tempDir, {
|
||||||
|
recursive: true,
|
||||||
|
force: true,
|
||||||
|
maxRetries: 3,
|
||||||
|
retryDelay: 10,
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function runLoadPoliciesFromToml(
|
||||||
|
tomlContent: string,
|
||||||
|
fileName = 'test.toml',
|
||||||
|
): Promise<PolicyLoadResult> {
|
||||||
|
await fs.writeFile(path.join(tempDir, fileName), tomlContent);
|
||||||
|
const getPolicyTier = (_dir: string) => 1;
|
||||||
|
return loadPoliciesFromToml(ApprovalMode.DEFAULT, [tempDir], getPolicyTier);
|
||||||
|
}
|
||||||
|
|
||||||
describe('loadPoliciesFromToml', () => {
|
describe('loadPoliciesFromToml', () => {
|
||||||
it('should load and parse a simple policy file', async () => {
|
it('should load and parse a simple policy file', async () => {
|
||||||
const result = await runLoadPoliciesFromToml(`
|
const result = await runLoadPoliciesFromToml(`
|
||||||
@@ -277,73 +246,30 @@ priority = 100
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should handle a mix of valid and invalid policy files', async () => {
|
it('should handle a mix of valid and invalid policy files', async () => {
|
||||||
const actualFs =
|
await fs.writeFile(
|
||||||
await vi.importActual<typeof import('node:fs/promises')>(
|
path.join(tempDir, 'valid.toml'),
|
||||||
'node:fs/promises',
|
`
|
||||||
);
|
|
||||||
|
|
||||||
const mockReaddir = vi.fn(
|
|
||||||
async (
|
|
||||||
path: string,
|
|
||||||
_options?: { withFileTypes: boolean },
|
|
||||||
): Promise<Dirent[]> => {
|
|
||||||
if (nodePath.normalize(path) === nodePath.normalize('/policies')) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: 'valid.toml',
|
|
||||||
isFile: () => true,
|
|
||||||
isDirectory: () => false,
|
|
||||||
} as Dirent,
|
|
||||||
{
|
|
||||||
name: 'invalid.toml',
|
|
||||||
isFile: () => true,
|
|
||||||
isDirectory: () => false,
|
|
||||||
} as Dirent,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return [];
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const mockReadFile = vi.fn(async (path: string): Promise<string> => {
|
|
||||||
if (
|
|
||||||
nodePath.normalize(path) ===
|
|
||||||
nodePath.normalize(nodePath.join('/policies', 'valid.toml'))
|
|
||||||
) {
|
|
||||||
return `
|
|
||||||
[[rule]]
|
[[rule]]
|
||||||
toolName = "glob"
|
toolName = "glob"
|
||||||
decision = "allow"
|
decision = "allow"
|
||||||
priority = 100
|
priority = 100
|
||||||
`;
|
`,
|
||||||
}
|
);
|
||||||
if (
|
|
||||||
nodePath.normalize(path) ===
|
await fs.writeFile(
|
||||||
nodePath.normalize(nodePath.join('/policies', 'invalid.toml'))
|
path.join(tempDir, 'invalid.toml'),
|
||||||
) {
|
`
|
||||||
return `
|
|
||||||
[[rule]]
|
[[rule]]
|
||||||
toolName = "grep"
|
toolName = "grep"
|
||||||
decision = "allow"
|
decision = "allow"
|
||||||
priority = -1
|
priority = -1
|
||||||
`;
|
`,
|
||||||
}
|
);
|
||||||
throw new Error('File not found');
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.doMock('node:fs/promises', () => ({
|
|
||||||
...actualFs,
|
|
||||||
default: { ...actualFs, readFile: mockReadFile, readdir: mockReaddir },
|
|
||||||
readFile: mockReadFile,
|
|
||||||
readdir: mockReaddir,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { loadPoliciesFromToml: load } = await import('./toml-loader.js');
|
|
||||||
|
|
||||||
const getPolicyTier = (_dir: string) => 1;
|
const getPolicyTier = (_dir: string) => 1;
|
||||||
const result = await load(
|
const result = await loadPoliciesFromToml(
|
||||||
ApprovalMode.DEFAULT,
|
ApprovalMode.DEFAULT,
|
||||||
['/policies'],
|
[tempDir],
|
||||||
getPolicyTier,
|
getPolicyTier,
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -354,6 +280,7 @@ priority = -1
|
|||||||
expect(result.errors[0].errorType).toBe('schema_validation');
|
expect(result.errors[0].errorType).toBe('schema_validation');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Negative Tests', () => {
|
describe('Negative Tests', () => {
|
||||||
it('should return a schema_validation error if priority is missing', async () => {
|
it('should return a schema_validation error if priority is missing', async () => {
|
||||||
const result = await runLoadPoliciesFromToml(`
|
const result = await runLoadPoliciesFromToml(`
|
||||||
@@ -507,26 +434,14 @@ priority = 100
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return a file_read error if readdir fails', async () => {
|
it('should return a file_read error if readdir fails', async () => {
|
||||||
const actualFs =
|
// Create a file and pass it as a directory to trigger ENOTDIR
|
||||||
await vi.importActual<typeof import('node:fs/promises')>(
|
const filePath = path.join(tempDir, 'not-a-dir');
|
||||||
'node:fs/promises',
|
await fs.writeFile(filePath, 'content');
|
||||||
);
|
|
||||||
|
|
||||||
const mockReaddir = vi.fn(async () => {
|
|
||||||
throw new Error('Permission denied');
|
|
||||||
});
|
|
||||||
|
|
||||||
vi.doMock('node:fs/promises', () => ({
|
|
||||||
...actualFs,
|
|
||||||
default: { ...actualFs, readdir: mockReaddir },
|
|
||||||
readdir: mockReaddir,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { loadPoliciesFromToml: load } = await import('./toml-loader.js');
|
|
||||||
const getPolicyTier = (_dir: string) => 1;
|
const getPolicyTier = (_dir: string) => 1;
|
||||||
const result = await load(
|
const result = await loadPoliciesFromToml(
|
||||||
ApprovalMode.DEFAULT,
|
ApprovalMode.DEFAULT,
|
||||||
['/policies'],
|
[filePath],
|
||||||
getPolicyTier,
|
getPolicyTier,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user