Files
connectai/tests/paths.test.ts
T

85 lines
2.5 KiB
TypeScript

/**
* Unit tests for the centralized path resolver.
*/
import * as os from 'os';
import * as path from 'path';
import {
expandTilde,
resolvePathInput,
isInside,
} from '../src/lib/paths';
describe('expandTilde', () => {
test('expands "~" to home', () => {
expect(expandTilde('~')).toBe(os.homedir());
});
test('expands "~/foo" to home/foo', () => {
expect(expandTilde('~/foo')).toBe(path.join(os.homedir(), 'foo'));
});
test('leaves absolute paths untouched', () => {
expect(expandTilde('/tmp/x')).toBe('/tmp/x');
});
test('returns empty for blank input', () => {
expect(expandTilde('')).toBe('');
expect(expandTilde(' ')).toBe('');
});
});
describe('resolvePathInput', () => {
test('accepts absolute paths', () => {
expect(resolvePathInput('/tmp/abc')).toBe(path.normalize('/tmp/abc'));
});
test('accepts ~/-prefixed paths after expansion', () => {
expect(resolvePathInput('~/notes')).toBe(path.normalize(path.join(os.homedir(), 'notes')));
});
test('rejects relative paths to prevent surprises', () => {
expect(resolvePathInput('relative/dir')).toBe('');
expect(resolvePathInput('./local')).toBe('');
});
test('returns empty on blank / undefined', () => {
expect(resolvePathInput('')).toBe('');
expect(resolvePathInput(undefined as any)).toBe('');
});
});
describe('isInside', () => {
test('a path is inside itself', () => {
expect(isInside('/tmp/a', '/tmp/a')).toBe(true);
});
test('detects direct descendants', () => {
expect(isInside('/tmp/a', '/tmp/a/b')).toBe(true);
});
test('detects deep descendants', () => {
expect(isInside('/tmp/a', '/tmp/a/b/c/d.txt')).toBe(true);
});
test('rejects siblings', () => {
expect(isInside('/tmp/a', '/tmp/b')).toBe(false);
});
test('rejects path-traversal escapes', () => {
// Even though string-prefix would say "/tmp/a/../b" starts with "/tmp/a/",
// path.resolve normalizes the dotdot back to the parent → not inside.
expect(isInside('/tmp/a', '/tmp/a/../b')).toBe(false);
});
test('rejects siblings whose name shares a prefix', () => {
// "/tmp/agents-evil" must not be considered inside "/tmp/agents".
expect(isInside('/tmp/agents', '/tmp/agents-evil')).toBe(false);
});
test('returns false on empty inputs', () => {
expect(isInside('', '/tmp/a')).toBe(false);
expect(isInside('/tmp/a', '')).toBe(false);
});
});