moving
Some checks failed
Installer Smoke / installer-smoke (push) Has been cancelled

This commit is contained in:
Oleg Maslov
2026-09-02 10:10:29 +02:00
commit 0c3e2ead3b
3841 changed files with 970576 additions and 0 deletions

View File

@@ -0,0 +1,112 @@
/**
* AI-OS Phase 0 — integration test for the tool-detection route.
*
* Boots a real local server (with the same fixture pattern used by
* cross-platform.test.ts) and hits GET /api/tools/detect end-to-end.
*
* The detector itself is exhaustively unit-tested with injected deps
* in `packages/agent/tests/tool-detection.test.ts`. This test verifies
* that:
* 1. The route is wired into the local server.
* 2. The response envelope shape matches the shared contract.
* 3. Every SUPPORTED_TOOLS id appears in the response.
*
* We deliberately do NOT assert on specific tool installation state
* — that depends on the host machine running the tests and would
* make the suite non-hermetic. We also do not assert on auth
* rejection: the local sidecar is loopback-bound and intentionally
* permits read-only in-process calls; tool detection reports only
* what's already on the user's own machine and is not sensitive.
*/
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import fs from 'node:fs';
import path from 'node:path';
import os from 'node:os';
import type { FastifyInstance } from 'fastify';
import { MindDB, FrameStore, SessionStore } from '@waggle/core';
import { SUPPORTED_TOOLS } from '@waggle/shared';
import { buildLocalServer } from '../src/local/index.js';
import { injectWithAuth } from './test-utils.js';
function createTmpDir(prefix: string): string {
return fs.mkdtempSync(path.join(os.tmpdir(), `waggle-tools-${prefix}-`));
}
function cleanupDir(dir: string): void {
try {
fs.rmSync(dir, { recursive: true, force: true });
} catch {
/* best-effort */
}
}
describe('GET /api/tools/detect', () => {
let server: FastifyInstance;
let tmpDir: string;
beforeAll(async () => {
tmpDir = createTmpDir('routes');
const personalPath = path.join(tmpDir, 'personal.mind');
const mind = new MindDB(personalPath);
const sessions = new SessionStore(mind);
const frames = new FrameStore(mind);
const s = sessions.create('tools-routes-test');
frames.createIFrame(s.gop_id, 'tools-routes-test seed frame', 'normal');
mind.close();
server = await buildLocalServer({ dataDir: tmpDir });
await server.ready();
});
afterAll(async () => {
if (server) await server.close();
if (tmpDir) cleanupDir(tmpDir);
});
it('returns 200 with a stable envelope shape', async () => {
const res = await injectWithAuth(server, {
method: 'GET',
url: '/api/tools/detect',
});
expect(res.statusCode).toBe(200);
const body = res.json();
expect(body).toHaveProperty('platform');
expect(body).toHaveProperty('detectedAt');
expect(body).toHaveProperty('tools');
expect(Array.isArray(body.tools)).toBe(true);
});
it('covers every supported tool id in the envelope', async () => {
const res = await injectWithAuth(server, {
method: 'GET',
url: '/api/tools/detect',
});
expect(res.statusCode).toBe(200);
const body = res.json();
const ids = body.tools.map((t: { id: string }) => t.id);
for (const id of SUPPORTED_TOOLS) {
expect(ids).toContain(id);
}
});
it('each tool entry has the expected fields', async () => {
const res = await injectWithAuth(server, {
method: 'GET',
url: '/api/tools/detect',
});
const body = res.json();
for (const t of body.tools) {
expect(t).toHaveProperty('id');
expect(t).toHaveProperty('displayName');
expect(t).toHaveProperty('installed');
expect(t).toHaveProperty('installedPath');
expect(t).toHaveProperty('version');
expect(t).toHaveProperty('hooksInstalled');
expect(t).toHaveProperty('hookPointerPath');
expect(typeof t.installed).toBe('boolean');
expect(typeof t.hooksInstalled).toBe('boolean');
}
});
});