Files
ccs/tests/unit/utils/prompt-injection-strategy.test.ts
T

127 lines
3.8 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, it } from 'bun:test';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import {
buildInlineSteeringArg,
buildFileSteeringArg,
buildSteeringArg,
detectPromptInjectionMode,
getManagedPromptFilePath,
hasManagedPromptFileArg,
PROMPT_FLAG_INLINE,
PROMPT_FLAG_FILE,
} from '../../../src/utils/prompt-injection-strategy';
let originalCcsHome: string | undefined;
let tempHome: string;
beforeEach(() => {
originalCcsHome = process.env.CCS_HOME;
tempHome = fs.mkdtempSync(path.join(os.tmpdir(), 'ccs-prompt-strategy-'));
process.env.CCS_HOME = tempHome;
});
afterEach(() => {
if (originalCcsHome === undefined) {
delete process.env.CCS_HOME;
} else {
process.env.CCS_HOME = originalCcsHome;
}
fs.rmSync(tempHome, { recursive: true, force: true });
});
describe('detectPromptInjectionMode', () => {
it('returns inline when no prompt flags present', () => {
expect(detectPromptInjectionMode(['-p', 'hello'])).toBe('inline');
});
it('returns inline when only --append-system-prompt is present', () => {
expect(detectPromptInjectionMode(['--append-system-prompt', 'test'])).toBe('inline');
});
it('returns inline when --append-system-prompt equals form is present', () => {
expect(detectPromptInjectionMode(['--append-system-prompt=test'])).toBe('inline');
});
it('returns file when --append-system-prompt-file is present', () => {
expect(detectPromptInjectionMode(['--append-system-prompt-file', '/tmp/p.txt'])).toBe('file');
});
it('returns file when --append-system-prompt-file equals form is present', () => {
expect(detectPromptInjectionMode(['--append-system-prompt-file=/tmp/p.txt'])).toBe('file');
});
it('returns file even when --append-system-prompt is also present', () => {
expect(
detectPromptInjectionMode([
'--append-system-prompt',
'inline-text',
'--append-system-prompt-file',
'/tmp/p.txt',
])
).toBe('file');
});
});
describe('buildInlineSteeringArg', () => {
it('returns inline flag and prompt text', () => {
expect(buildInlineSteeringArg({promptContent: 'hello world'})).toEqual(['--append-system-prompt', 'hello world']);
});
});
describe('buildFileSteeringArg', () => {
it('returns file flag and writes the prompt into the isolated CCS home', () => {
const result = buildFileSteeringArg({
promptFileName: 'ccs-test-prompt.txt',
promptContent: 'hello world',
});
expect(result[0]).toBe('--append-system-prompt-file');
expect(result[1]).toBe(path.join(tempHome, '.ccs', 'prompts', 'ccs-test-prompt.txt'));
expect(fs.readFileSync(result[1], 'utf8')).toBe('hello world');
});
});
describe('hasManagedPromptFileArg', () => {
it('returns true for the exact CCS-managed prompt path', () => {
expect(
hasManagedPromptFileArg({
args: [PROMPT_FLAG_FILE, getManagedPromptFilePath('ccs-test')],
promptName: 'ccs-test',
})
).toBe(true);
});
it('returns false for unrelated user files that only contain the prompt name', () => {
expect(
hasManagedPromptFileArg({
args: [PROMPT_FLAG_FILE, '/tmp/user-ccs-test-notes.txt'],
promptName: 'ccs-test',
})
).toBe(false);
});
});
describe('buildSteeringArg', () => {
it('delegates to inline in inline mode', () => {
expect(
buildSteeringArg({
args: [PROMPT_FLAG_INLINE],
promptName: 'ignored.txt',
promptContent: 'hello',
})
).toEqual(['--append-system-prompt', 'hello']);
});
it('delegates to file in file mode', () => {
const result = buildSteeringArg({
args: [PROMPT_FLAG_FILE],
promptName: 'ccs-test',
promptContent: 'hello',
});
expect(result[0]).toBe('--append-system-prompt-file');
expect(result[1]).toBe(getManagedPromptFilePath('ccs-test'));
});
});