openclaw/apps/web/app/api/sessions/sessions.test.ts
2026-02-16 01:01:12 -08:00

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);
});
});
});