- Created skills/ directory - Moved 272 skills to skills/ subfolder - Kept agents/ at root level - Kept installation scripts and docs at root level Repository structure: - skills/ - All 272 skills from skills.sh - agents/ - Agent definitions - *.sh, *.ps1 - Installation scripts - README.md, etc. - Documentation Co-Authored-By: Claude <noreply@anthropic.com>
106 lines
3.3 KiB
TypeScript
106 lines
3.3 KiB
TypeScript
import { describe, expect, test } from 'bun:test';
|
|
import { formatBlockedMessage } from '../src/core/format.ts';
|
|
|
|
describe('formatBlockedMessage', () => {
|
|
test('includes reason in output', () => {
|
|
const result = formatBlockedMessage({ reason: 'test reason' });
|
|
expect(result).toContain('BLOCKED by Safety Net');
|
|
expect(result).toContain('Reason: test reason');
|
|
});
|
|
|
|
test('includes command when provided', () => {
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
command: 'rm -rf /',
|
|
});
|
|
expect(result).toContain('Command: rm -rf /');
|
|
});
|
|
|
|
test('includes segment when provided', () => {
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
segment: 'git reset --hard',
|
|
});
|
|
expect(result).toContain('Segment: git reset --hard');
|
|
});
|
|
|
|
test('includes both command and segment when different', () => {
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
command: 'full command here',
|
|
segment: 'git reset --hard',
|
|
});
|
|
expect(result).toContain('Command: full command here');
|
|
expect(result).toContain('Segment: git reset --hard');
|
|
});
|
|
|
|
test('does not duplicate segment when same as command', () => {
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
command: 'git reset --hard',
|
|
segment: 'git reset --hard',
|
|
});
|
|
expect(result).toContain('Command: git reset --hard');
|
|
const segmentMatches = result.match(/Segment:/g);
|
|
expect(segmentMatches).toBeNull();
|
|
});
|
|
|
|
test('truncates long commands with maxLen', () => {
|
|
const longCommand = 'a'.repeat(300);
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
command: longCommand,
|
|
maxLen: 50,
|
|
});
|
|
expect(result).toContain('...');
|
|
expect(result.length).toBeLessThan(longCommand.length + 100);
|
|
});
|
|
|
|
test('uses default maxLen of 200', () => {
|
|
const longCommand = 'a'.repeat(300);
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
command: longCommand,
|
|
});
|
|
expect(result).toContain('...');
|
|
});
|
|
|
|
test('does not truncate short commands', () => {
|
|
const shortCommand = 'rm -rf /';
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
command: shortCommand,
|
|
});
|
|
expect(result).toContain(`Command: ${shortCommand}`);
|
|
expect(result).not.toContain('...');
|
|
});
|
|
|
|
test('includes footer about asking user', () => {
|
|
const result = formatBlockedMessage({ reason: 'test reason' });
|
|
expect(result).toContain('ask the user');
|
|
});
|
|
|
|
test('applies redact function to command', () => {
|
|
const redactFn = (text: string) => text.replace(/secret/g, '***');
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
command: 'rm -rf /secret/path',
|
|
redact: redactFn,
|
|
});
|
|
expect(result).toContain('Command: rm -rf /***/path');
|
|
expect(result).not.toContain('secret');
|
|
});
|
|
|
|
test('applies redact function to segment', () => {
|
|
const redactFn = (text: string) => text.replace(/password/g, '***');
|
|
const result = formatBlockedMessage({
|
|
reason: 'test reason',
|
|
command: 'full command',
|
|
segment: 'echo password',
|
|
redact: redactFn,
|
|
});
|
|
expect(result).toContain('Segment: echo ***');
|
|
expect(result).not.toContain('password');
|
|
});
|
|
});
|