Files
open-design/apps/daemon/tests/mcp-resolve-project.test.ts
Zakaria a46764fb1b
ci / Validate workspace (push) Has been cancelled
landing-page-ci / Validate landing page (push) Has been cancelled
landing-page-deploy / Deploy landing page (push) Has been cancelled
github-metrics / Generate repository metrics SVG (push) Has been cancelled
refresh-contributors-wall / Refresh contributors wall cache bust (push) Waiting to run
first-commit
2026-05-04 14:58:14 -04:00

89 lines
3.3 KiB
TypeScript

// @ts-nocheck
import http from 'node:http';
import express from 'express';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';
import { resolveProjectId, withActiveEcho } from '../src/mcp.js';
// Two projects whose names share the substring 'app' for ambiguity testing.
const PROJECTS = [
{ id: '11111111-1111-1111-1111-111111111111', name: 'My App' },
{ id: '22222222-2222-2222-2222-222222222222', name: 'Store App' },
{ id: '33333333-3333-3333-3333-333333333333', name: 'recaptr' },
];
describe('resolveProjectId', () => {
let server;
let baseUrl;
beforeAll(
() =>
new Promise((resolve) => {
const app = express();
app.get('/api/projects', (_req, res) => res.json({ projects: PROJECTS }));
const tmp = http.createServer();
tmp.listen(0, '127.0.0.1', () => {
const { port } = tmp.address();
baseUrl = `http://127.0.0.1:${port}`;
tmp.close(() => {
server = app.listen(port, '127.0.0.1', () => resolve());
});
});
}),
);
afterAll(() => new Promise((resolve) => server.close(resolve)));
it('UUID input returns source: uuid without fetching the project list', async () => {
const r = await resolveProjectId(baseUrl, '11111111-1111-1111-1111-111111111111');
expect(r.source).toBe('uuid');
expect(r.id).toBe('11111111-1111-1111-1111-111111111111');
});
it('exact name match returns source: exact', async () => {
const r = await resolveProjectId(baseUrl, 'My App');
expect(r.source).toBe('exact');
expect(r.id).toBe('11111111-1111-1111-1111-111111111111');
expect(r.name).toBe('My App');
});
it('slug match (my-app) returns source: slug', async () => {
const r = await resolveProjectId(baseUrl, 'my-app');
expect(r.source).toBe('slug');
expect(r.id).toBe('11111111-1111-1111-1111-111111111111');
});
it('single substring match returns source: substring', async () => {
const r = await resolveProjectId(baseUrl, 'recapt');
expect(r.source).toBe('substring');
expect(r.id).toBe('33333333-3333-3333-3333-333333333333');
expect(r.name).toBe('recaptr');
});
it('multiple substring matches throw an ambiguity error', async () => {
// 'My App' and 'Store App' both contain 'app'
await expect(resolveProjectId(baseUrl, 'app')).rejects.toThrow(/multiple projects match/);
});
});
describe('withActiveEcho resolvedProject stamping', () => {
it('uuid source: resolvedProject is not added', () => {
const result = withActiveEcho({ x: 1 }, null, { id: 'abc', name: 'Test', source: 'uuid' });
expect(result).not.toHaveProperty('resolvedProject');
});
it('exact source: resolvedProject is not added', () => {
const result = withActiveEcho({ x: 1 }, null, { id: 'abc', name: 'Test', source: 'exact' });
expect(result).not.toHaveProperty('resolvedProject');
});
it('slug source: resolvedProject is added with id and name', () => {
const result = withActiveEcho({ x: 1 }, null, { id: 'abc', name: 'Test', source: 'slug' });
expect(result.resolvedProject).toEqual({ id: 'abc', name: 'Test' });
});
it('substring source: resolvedProject is added with id and name', () => {
const result = withActiveEcho({ x: 1 }, null, { id: 'abc', name: 'Test', source: 'substring' });
expect(result.resolvedProject).toEqual({ id: 'abc', name: 'Test' });
});
});