import { describe, it, expect } from 'vitest'; import { globNeedsFilter, filterRestrictedMatches } from './glob-restricted-filter.mjs'; describe('globNeedsFilter', () => { it('returns true for ~/.claude/runtime wildcard patterns', () => { expect(globNeedsFilter('~/.claude/runtime/**/*.json')).toBe(true); expect(globNeedsFilter('~/.claude/runtime/**')).toBe(true); }); it('returns true for absolute .claude/runtime wildcard patterns', () => { expect(globNeedsFilter('C:/Users/Administrator/.claude/runtime/**/*.json')).toBe(true); }); it('returns false without ** wildcard even under runtime', () => { expect(globNeedsFilter('~/.claude/runtime/foo.json')).toBe(false); }); it('returns false for unrelated patterns', () => { expect(globNeedsFilter('app/**/*.php')).toBe(false); expect(globNeedsFilter('')).toBe(false); expect(globNeedsFilter(null)).toBe(false); }); }); describe('filterRestrictedMatches', () => { it('drops matches under a /restricted/ segment', () => { const matches = [ '/home/u/.claude/runtime/a.json', '/home/u/.claude/runtime/restricted/subagent-block-1.json', ]; const out = filterRestrictedMatches(matches); expect(out).toContain('/home/u/.claude/runtime/a.json'); expect(out).not.toContain('/home/u/.claude/runtime/restricted/subagent-block-1.json'); }); it('normalizes backslashes for the /restricted/ check', () => { const out = filterRestrictedMatches(['C:\\Users\\x\\.claude\\runtime\\restricted\\s.json']); expect(out).toEqual([]); }); it('drops matches whose inode is protected (injected predicate)', () => { const matches = ['/r/a.json', '/r/secret.json']; const isProtectedInode = (p) => p === '/r/secret.json'; const out = filterRestrictedMatches(matches, { isProtectedInode }); expect(out).toEqual(['/r/a.json']); }); it('default isProtectedInode stub keeps non-restricted matches', () => { expect(filterRestrictedMatches(['/r/a.json', '/r/b.json'])).toEqual(['/r/a.json', '/r/b.json']); }); it('returns [] for non-array input', () => { expect(filterRestrictedMatches(null)).toEqual([]); }); });