mirror of
https://github.com/giancarloerra/socraticode.git
synced 2026-07-03 14:05:21 +02:00
108 lines
3.2 KiB
TypeScript
108 lines
3.2 KiB
TypeScript
// SPDX-License-Identifier: AGPL-3.0-only
|
|
// Copyright (C) 2026 Giancarlo Erra - Altaire Limited
|
|
|
|
import path from "node:path";
|
|
import { afterAll, afterEach, beforeAll, describe, expect, it } from "vitest";
|
|
import { ensureQdrantReady } from "../../src/services/docker.js";
|
|
import { indexProject } from "../../src/services/indexer.js";
|
|
import { ensureOllamaReady } from "../../src/services/ollama.js";
|
|
import {
|
|
getWatchedProjects,
|
|
isWatching,
|
|
startWatching,
|
|
stopAllWatchers,
|
|
stopWatching,
|
|
} from "../../src/services/watcher.js";
|
|
import {
|
|
createFixtureProject,
|
|
type FixtureProject,
|
|
isDockerAvailable,
|
|
} from "../helpers/fixtures.js";
|
|
import { cleanupTestCollections, waitForOllama, waitForQdrant } from "../helpers/setup.js";
|
|
|
|
const dockerAvailable = isDockerAvailable();
|
|
|
|
describe.skipIf(!dockerAvailable)("watcher service", () => {
|
|
let fixture: FixtureProject;
|
|
|
|
beforeAll(async () => {
|
|
await ensureQdrantReady();
|
|
await ensureOllamaReady();
|
|
await waitForQdrant();
|
|
await waitForOllama();
|
|
|
|
fixture = createFixtureProject("watcher-test");
|
|
|
|
// Index the project first so the watcher has a collection to update
|
|
await indexProject(fixture.root);
|
|
}, 180_000);
|
|
|
|
afterAll(async () => {
|
|
await stopAllWatchers();
|
|
fixture.cleanup();
|
|
await cleanupTestCollections(fixture.root);
|
|
});
|
|
|
|
afterEach(async () => {
|
|
// Stop watchers between tests
|
|
if (isWatching(fixture.root)) {
|
|
await stopWatching(fixture.root);
|
|
}
|
|
});
|
|
|
|
describe("startWatching / stopWatching", () => {
|
|
it("starts watching a project", async () => {
|
|
await startWatching(fixture.root);
|
|
expect(isWatching(fixture.root)).toBe(true);
|
|
});
|
|
|
|
it("includes the project in watched list", async () => {
|
|
await startWatching(fixture.root);
|
|
const watched = getWatchedProjects();
|
|
expect(watched).toContain(path.resolve(fixture.root));
|
|
});
|
|
|
|
it("stops watching a project", async () => {
|
|
await startWatching(fixture.root);
|
|
expect(isWatching(fixture.root)).toBe(true);
|
|
|
|
await stopWatching(fixture.root);
|
|
expect(isWatching(fixture.root)).toBe(false);
|
|
});
|
|
|
|
it("does not error when stopping a non-watched project", async () => {
|
|
await expect(stopWatching("/nonexistent/path")).resolves.not.toThrow();
|
|
});
|
|
|
|
it("is idempotent — starting twice does not error", async () => {
|
|
await startWatching(fixture.root);
|
|
await startWatching(fixture.root);
|
|
expect(isWatching(fixture.root)).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("stopAllWatchers", () => {
|
|
it("stops all active watchers", async () => {
|
|
await startWatching(fixture.root);
|
|
expect(getWatchedProjects().length).toBeGreaterThan(0);
|
|
|
|
await stopAllWatchers();
|
|
expect(getWatchedProjects()).toHaveLength(0);
|
|
});
|
|
});
|
|
|
|
describe("getWatchedProjects", () => {
|
|
it("returns empty list when nothing is watched", async () => {
|
|
await stopAllWatchers();
|
|
expect(getWatchedProjects()).toHaveLength(0);
|
|
});
|
|
|
|
it("returns all watched projects", async () => {
|
|
await startWatching(fixture.root);
|
|
const projects = getWatchedProjects();
|
|
expect(projects.length).toBe(1);
|
|
expect(projects[0]).toBe(path.resolve(fixture.root));
|
|
});
|
|
});
|
|
});
|