719032b19f
Update Schema / Update configuration json schema (push) Has been cancelled
Memory Benchmark / Memory Test (Full Analysis) (push) Has been cancelled
CI Quality / Lint GitHub Actions (actionlint) (push) Has been cancelled
CI Quality / Lint GitHub Actions (zizmor) (push) Has been cancelled
CI Quality / Check typos (push) Has been cancelled
CI / Test coverage (push) Has been cancelled
CI / Test (22.x, windows-latest) (push) Has been cancelled
CI / Test (24.x, macos-latest) (push) Has been cancelled
CI / Test (24.x, ubuntu-latest) (push) Has been cancelled
CI / Test (24.x, windows-latest) (push) Has been cancelled
CI / Test (26.x, macos-latest) (push) Has been cancelled
CI / Test (26.x, ubuntu-latest) (push) Has been cancelled
CI / Test (26.x, windows-latest) (push) Has been cancelled
CI / Test with Bun (latest, macos-latest) (push) Has been cancelled
CI / Test with Bun (latest, ubuntu-latest) (push) Has been cancelled
CI / Test with Bun (latest, windows-latest) (push) Has been cancelled
CI / Build and run (22.x, macos-latest) (push) Has been cancelled
CI / Build and run (22.x, ubuntu-latest) (push) Has been cancelled
CI / Build and run (22.x, windows-latest) (push) Has been cancelled
autofix.ci / autofix (push) Has been cancelled
CI Browser Extension / Lint Browser Extension (push) Has been cancelled
CI Browser Extension / Test Browser Extension (push) Has been cancelled
Memory Benchmark / Memory Test (push) Has been cancelled
CI Website / Lint Website Client (push) Has been cancelled
CI Website / Lint Website Server (push) Has been cancelled
CI Website / Test Website Server (push) Has been cancelled
CI Website / Bundle Website Server (push) Has been cancelled
CI / Lint Biome (push) Has been cancelled
CI / Lint oxlint (push) Has been cancelled
CI / Lint TypeScript (push) Has been cancelled
CI / Lint Secretlint (push) Has been cancelled
CI / Test (22.x, macos-latest) (push) Has been cancelled
CI / Test (22.x, ubuntu-latest) (push) Has been cancelled
CI / Build and run (24.x, macos-latest) (push) Has been cancelled
CI / Build and run (24.x, ubuntu-latest) (push) Has been cancelled
CI / Build and run (24.x, windows-latest) (push) Has been cancelled
CI / Build and run (26.x, macos-latest) (push) Has been cancelled
CI / Build and run (26.x, ubuntu-latest) (push) Has been cancelled
CI / Build and run (26.x, windows-latest) (push) Has been cancelled
CI / Build and run with Bun (latest, macos-latest) (push) Has been cancelled
CI / Build and run with Bun (latest, ubuntu-latest) (push) Has been cancelled
CI / Build and run with Bun (latest, windows-latest) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
Docker / build (linux/amd64, ubuntu-latest) (push) Has been cancelled
Docker / build (linux/arm/v7, ubuntu-24.04-arm) (push) Has been cancelled
Docker / build (linux/arm64, ubuntu-24.04-arm) (push) Has been cancelled
Docker / merge (push) Has been cancelled
Pack repository with Repomix / pack-repo (push) Has been cancelled
Performance Benchmark History / Benchmark (macos-latest) (push) Has been cancelled
Performance Benchmark History / Benchmark (ubuntu-latest) (push) Has been cancelled
Performance Benchmark History / Benchmark (windows-latest) (push) Has been cancelled
Performance Benchmark History / Store Results (push) Has been cancelled
Test Repomix Action / Test Node.js 22 (push) Has been cancelled
Test Repomix Action / Test Node.js 24 (push) Has been cancelled
Test Repomix Action / Test Node.js 26 (push) Has been cancelled
116 lines
5.2 KiB
TypeScript
116 lines
5.2 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
import type { RepomixConfigMerged } from '../../../src/config/configSchema.js';
|
|
import type { RawFile } from '../../../src/core/file/fileTypes.js';
|
|
import type { SuspiciousFileResult } from '../../../src/core/security/securityCheck.js';
|
|
import { validateFileSafety } from '../../../src/core/security/validateFileSafety.js';
|
|
import { logger } from '../../../src/shared/logger.js';
|
|
import type { RepomixProgressCallback } from '../../../src/shared/types.js';
|
|
|
|
describe('validateFileSafety', () => {
|
|
it('should validate file safety and return safe files and paths', async () => {
|
|
const rawFiles: RawFile[] = [
|
|
{ path: 'file1.txt', content: 'content1' },
|
|
{ path: 'file2.txt', content: 'content2' },
|
|
{ path: 'file3.txt', content: 'content3' },
|
|
];
|
|
const safeRawFiles = [rawFiles[0], rawFiles[1]];
|
|
const config: RepomixConfigMerged = {
|
|
security: { enableSecurityCheck: true },
|
|
} as RepomixConfigMerged;
|
|
const progressCallback: RepomixProgressCallback = vi.fn();
|
|
const suspiciousFilesResults: SuspiciousFileResult[] = [
|
|
{ filePath: 'file2.txt', messages: ['something suspicious.'], type: 'file' },
|
|
];
|
|
const deps = {
|
|
runSecurityCheck: vi.fn().mockResolvedValue(suspiciousFilesResults),
|
|
filterOutUntrustedFiles: vi.fn().mockReturnValue(safeRawFiles),
|
|
};
|
|
|
|
const result = await validateFileSafety(rawFiles, progressCallback, config, undefined, undefined, deps);
|
|
|
|
expect(deps.runSecurityCheck).toHaveBeenCalledWith(rawFiles, progressCallback, undefined, undefined);
|
|
expect(deps.filterOutUntrustedFiles).toHaveBeenCalledWith(rawFiles, suspiciousFilesResults);
|
|
expect(result).toEqual({
|
|
safeRawFiles,
|
|
safeFilePaths: ['file1.txt', 'file2.txt'],
|
|
suspiciousFilesResults,
|
|
suspiciousGitDiffResults: [],
|
|
suspiciousGitLogResults: [],
|
|
});
|
|
});
|
|
|
|
describe('git content warnings', () => {
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
it('warns about each suspicious git diff/log entry with singular/plural form', async () => {
|
|
const warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {});
|
|
const config: RepomixConfigMerged = {
|
|
security: { enableSecurityCheck: true },
|
|
} as RepomixConfigMerged;
|
|
const progressCallback: RepomixProgressCallback = vi.fn();
|
|
|
|
const allResults: SuspiciousFileResult[] = [
|
|
{ filePath: 'work_tree', messages: ['leaked key'], type: 'gitDiff' },
|
|
{ filePath: 'staged', messages: ['leaked key', 'token'], type: 'gitDiff' },
|
|
{ filePath: 'commit_log', messages: ['secret', 'pw', 'token'], type: 'gitLog' },
|
|
];
|
|
const deps = {
|
|
runSecurityCheck: vi.fn().mockResolvedValue(allResults),
|
|
filterOutUntrustedFiles: vi.fn().mockReturnValue([]),
|
|
};
|
|
|
|
const result = await validateFileSafety([], progressCallback, config, undefined, undefined, deps);
|
|
|
|
expect(result.suspiciousGitDiffResults).toHaveLength(2);
|
|
expect(result.suspiciousGitLogResults).toHaveLength(1);
|
|
|
|
const warnings = warnSpy.mock.calls.map((c) => String(c[0]));
|
|
// Header lines for each section
|
|
expect(warnings).toContain('Security issues found in Git diffs, but they will still be included in the output');
|
|
expect(warnings).toContain('Security issues found in Git logs, but they will still be included in the output');
|
|
// Singular form for 1 message, plural for >1
|
|
expect(warnings).toContain(' - work_tree: 1 issue detected');
|
|
expect(warnings).toContain(' - staged: 2 issues detected');
|
|
expect(warnings).toContain(' - commit_log: 3 issues detected');
|
|
});
|
|
|
|
it('does not log a header when no suspicious git content is found', async () => {
|
|
const warnSpy = vi.spyOn(logger, 'warn').mockImplementation(() => {});
|
|
const config: RepomixConfigMerged = {
|
|
security: { enableSecurityCheck: true },
|
|
} as RepomixConfigMerged;
|
|
|
|
await validateFileSafety([], vi.fn(), config, undefined, undefined, {
|
|
runSecurityCheck: vi.fn().mockResolvedValue([]),
|
|
filterOutUntrustedFiles: vi.fn().mockReturnValue([]),
|
|
});
|
|
|
|
expect(warnSpy).not.toHaveBeenCalled();
|
|
});
|
|
});
|
|
|
|
it('skips runSecurityCheck entirely when enableSecurityCheck is false', async () => {
|
|
// Pin the negative path of the `if (config.security.enableSecurityCheck)` guard.
|
|
// Dropping the guard would still pass every other test in this file because
|
|
// they all enable the check; this one fails if the guard ever regresses.
|
|
const config: RepomixConfigMerged = {
|
|
security: { enableSecurityCheck: false },
|
|
} as RepomixConfigMerged;
|
|
const rawFiles: RawFile[] = [{ path: 'file1.txt', content: 'content' }];
|
|
const deps = {
|
|
runSecurityCheck: vi.fn(),
|
|
filterOutUntrustedFiles: vi.fn().mockReturnValue(rawFiles),
|
|
};
|
|
|
|
const result = await validateFileSafety(rawFiles, vi.fn(), config, undefined, undefined, deps);
|
|
|
|
expect(deps.runSecurityCheck).not.toHaveBeenCalled();
|
|
expect(result.suspiciousFilesResults).toEqual([]);
|
|
expect(result.suspiciousGitDiffResults).toEqual([]);
|
|
expect(result.suspiciousGitLogResults).toEqual([]);
|
|
expect(result.safeFilePaths).toEqual(['file1.txt']);
|
|
});
|
|
});
|