145 lines
5.4 KiB
TypeScript
145 lines
5.4 KiB
TypeScript
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
|
|
// Mock node:fs
|
|
vi.mock("node:fs", () => ({
|
|
existsSync: vi.fn(() => false),
|
|
readFileSync: vi.fn(() => ""),
|
|
readdirSync: vi.fn(() => []),
|
|
statSync: vi.fn(() => ({ mtimeMs: Date.now() })),
|
|
}));
|
|
|
|
// Mock node:os
|
|
vi.mock("node:os", () => ({
|
|
homedir: vi.fn(() => "/home/testuser"),
|
|
}));
|
|
|
|
describe("Sessions, Memories & Skills API", () => {
|
|
beforeEach(() => {
|
|
vi.resetModules();
|
|
vi.mock("node:fs", () => ({
|
|
existsSync: vi.fn(() => false),
|
|
readFileSync: vi.fn(() => ""),
|
|
readdirSync: vi.fn(() => []),
|
|
statSync: vi.fn(() => ({ mtimeMs: Date.now() })),
|
|
}));
|
|
vi.mock("node:os", () => ({
|
|
homedir: vi.fn(() => "/home/testuser"),
|
|
}));
|
|
});
|
|
|
|
afterEach(() => {
|
|
vi.restoreAllMocks();
|
|
});
|
|
|
|
// ─── GET /api/sessions ──────────────────────────────────────────
|
|
|
|
describe("GET /api/sessions", () => {
|
|
it("returns empty agents and sessions when no dir exists", async () => {
|
|
const { GET } = await import("./route.js");
|
|
const res = await GET();
|
|
const json = await res.json();
|
|
expect(json.agents).toEqual([]);
|
|
expect(json.sessions).toEqual([]);
|
|
});
|
|
|
|
it("returns sessions from agent directories", async () => {
|
|
const { existsSync: mockExists, readFileSync: mockReadFile, readdirSync: mockReaddir } = await import("node:fs");
|
|
vi.mocked(mockExists).mockReturnValue(true);
|
|
vi.mocked(mockReaddir).mockImplementation((dir) => {
|
|
const s = String(dir);
|
|
if (s.endsWith("agents")) {return ["main" as never];}
|
|
if (s.endsWith("sessions")) {return ["sessions.json" as never];}
|
|
return [];
|
|
});
|
|
const sessionsData = {
|
|
"s1": { label: "Chat 1", displayName: "Chat 1", channel: "webchat", updatedAt: Date.now() },
|
|
};
|
|
vi.mocked(mockReadFile).mockReturnValue(JSON.stringify(sessionsData) as never);
|
|
|
|
const { GET } = await import("./route.js");
|
|
const res = await GET();
|
|
const json = await res.json();
|
|
expect(json.sessions.length).toBeGreaterThanOrEqual(0);
|
|
});
|
|
});
|
|
|
|
// ─── GET /api/sessions/[sessionId] ──────────────────────────────
|
|
|
|
describe("GET /api/sessions/[sessionId]", () => {
|
|
it("returns 404 when session not found", async () => {
|
|
const { GET } = await import("./[sessionId]/route.js");
|
|
const res = await GET(
|
|
new Request("http://localhost"),
|
|
{ params: Promise.resolve({ sessionId: "nonexistent" }) },
|
|
);
|
|
expect(res.status).toBe(404);
|
|
});
|
|
|
|
it("returns 404 for non-existent session ID", async () => {
|
|
const { GET } = await import("./[sessionId]/route.js");
|
|
const res = await GET(
|
|
new Request("http://localhost"),
|
|
{ params: Promise.resolve({ sessionId: "missing-id" }) },
|
|
);
|
|
expect(res.status).toBe(404);
|
|
});
|
|
});
|
|
|
|
// ─── GET /api/memories ──────────────────────────────────────────
|
|
|
|
describe("GET /api/memories", () => {
|
|
it("returns null mainMemory when no memory file exists", async () => {
|
|
const { existsSync: mockExists } = await import("node:fs");
|
|
vi.mocked(mockExists).mockReturnValue(false);
|
|
|
|
const { GET } = await import("../memories/route.js");
|
|
const res = await GET();
|
|
const json = await res.json();
|
|
expect(json.mainMemory).toBeNull();
|
|
});
|
|
|
|
it("returns memory content when file exists", async () => {
|
|
const { existsSync: mockExists, readFileSync: mockReadFile, readdirSync: mockReaddir } = await import("node:fs");
|
|
vi.mocked(mockExists).mockImplementation((p) => {
|
|
const s = String(p);
|
|
if (s.endsWith("MEMORY.md") || s.endsWith("memory.md")) {return true;}
|
|
return false;
|
|
});
|
|
vi.mocked(mockReadFile).mockReturnValue("# My memories\n\n- Remember X" as never);
|
|
vi.mocked(mockReaddir).mockReturnValue([]);
|
|
|
|
const { GET } = await import("../memories/route.js");
|
|
const res = await GET();
|
|
const json = await res.json();
|
|
expect(json.mainMemory).toContain("memories");
|
|
});
|
|
});
|
|
|
|
// ─── GET /api/skills ────────────────────────────────────────────
|
|
|
|
describe("GET /api/skills", () => {
|
|
it("returns empty skills when no skills directories exist", async () => {
|
|
const { GET } = await import("../skills/route.js");
|
|
const res = await GET();
|
|
const json = await res.json();
|
|
expect(json.skills).toEqual([]);
|
|
});
|
|
|
|
it("returns skills from directory", async () => {
|
|
const { existsSync: mockExists, readFileSync: mockReadFile, readdirSync: mockReaddir } = await import("node:fs");
|
|
vi.mocked(mockExists).mockReturnValue(true);
|
|
vi.mocked(mockReaddir).mockImplementation((dir) => {
|
|
const s = String(dir);
|
|
if (s.endsWith("skills")) {return ["my-skill" as never];}
|
|
return [];
|
|
});
|
|
vi.mocked(mockReadFile).mockReturnValue("---\nname: My Skill\n---\n# Skill content" as never);
|
|
|
|
const { GET } = await import("../skills/route.js");
|
|
const res = await GET();
|
|
const json = await res.json();
|
|
expect(json.skills.length).toBeGreaterThanOrEqual(0);
|
|
});
|
|
});
|
|
});
|