agent-ecosystem/test/main/services/discovery/ProjectPathResolver.test.ts

88 lines
3.1 KiB
TypeScript

import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { afterEach, describe, expect, it } from 'vitest';
import { ProjectPathResolver } from '../../../../src/main/services/discovery/ProjectPathResolver';
function createSessionLine(cwd: string): string {
return JSON.stringify({
uuid: 'test-uuid',
type: 'user',
cwd,
message: { role: 'user', content: 'hello' },
timestamp: new Date().toISOString(),
});
}
describe('ProjectPathResolver', () => {
const tempDirs: string[] = [];
afterEach(() => {
for (const tempDir of tempDirs) {
fs.rmSync(tempDir, { recursive: true, force: true });
}
tempDirs.length = 0;
});
it('prefers absolute cwd hint', async () => {
const projectsDir = fs.mkdtempSync(path.join(os.tmpdir(), 'resolver-projects-'));
tempDirs.push(projectsDir);
const resolver = new ProjectPathResolver(projectsDir);
const resolved = await resolver.resolveProjectPath('-Users-test-proj', {
cwdHint: '/Users/test/proj',
});
expect(resolved).toBe('/Users/test/proj');
});
it('extracts cwd from session file when available', async () => {
const projectsDir = fs.mkdtempSync(path.join(os.tmpdir(), 'resolver-projects-'));
tempDirs.push(projectsDir);
const projectId = '-Users-test-my-repo';
const projectDir = path.join(projectsDir, projectId);
fs.mkdirSync(projectDir, { recursive: true });
const sessionPath = path.join(projectDir, 'session-1.jsonl');
fs.writeFileSync(sessionPath, `${createSessionLine('/Users/test/my-repo')}\n`, 'utf8');
const resolver = new ProjectPathResolver(projectsDir);
const resolved = await resolver.resolveProjectPath(projectId);
expect(resolved).toBe('/Users/test/my-repo');
});
it('falls back to decoded project ID when no cwd is available', async () => {
const projectsDir = fs.mkdtempSync(path.join(os.tmpdir(), 'resolver-projects-'));
tempDirs.push(projectsDir);
const resolver = new ProjectPathResolver(projectsDir);
const resolved = await resolver.resolveProjectPath('-C:-Users-test-my-repo');
expect(resolved).toBe('C:/Users/test/my/repo');
});
it('invalidates cached paths by project', async () => {
const projectsDir = fs.mkdtempSync(path.join(os.tmpdir(), 'resolver-projects-'));
tempDirs.push(projectsDir);
const projectId = '-Users-test-my-repo';
const projectDir = path.join(projectsDir, projectId);
fs.mkdirSync(projectDir, { recursive: true });
const sessionPath = path.join(projectDir, 'session-1.jsonl');
fs.writeFileSync(sessionPath, `${createSessionLine('/Users/test/my-repo-v1')}\n`, 'utf8');
const resolver = new ProjectPathResolver(projectsDir);
const firstResolved = await resolver.resolveProjectPath(projectId);
expect(firstResolved).toBe('/Users/test/my-repo-v1');
fs.writeFileSync(sessionPath, `${createSessionLine('/Users/test/my-repo-v2')}\n`, 'utf8');
resolver.invalidateProject(projectId);
const secondResolved = await resolver.resolveProjectPath(projectId);
expect(secondResolved).toBe('/Users/test/my-repo-v2');
});
});