import { describe, it, expect } from "vitest"; import type { ParsedMessage, MessageCategory } from "../../src/shared/types.js"; import { ALL_CATEGORIES, DEFAULT_HIDDEN_CATEGORIES } from "../../src/shared/types.js"; // Replicate the filter logic to test it in isolation function filterMessages( messages: ParsedMessage[], enabledCategories: Set, redactedUuids: Set = new Set() ): ParsedMessage[] { return messages.filter( (m) => enabledCategories.has(m.category) && !redactedUuids.has(m.uuid) ); } function makeMsg(uuid: string, category: MessageCategory): ParsedMessage { return { uuid, category, content: `Content for ${uuid}`, rawIndex: 0 }; } describe("filters", () => { const messages: ParsedMessage[] = [ makeMsg("1", "user_message"), makeMsg("2", "assistant_text"), makeMsg("3", "thinking"), makeMsg("4", "tool_call"), makeMsg("5", "tool_result"), makeMsg("6", "system_message"), makeMsg("7", "hook_progress"), makeMsg("8", "file_snapshot"), makeMsg("9", "summary"), ]; it("correctly includes messages by enabled category", () => { const enabled = new Set(["user_message", "assistant_text"]); const filtered = filterMessages(messages, enabled); expect(filtered).toHaveLength(2); expect(filtered.map((m) => m.category)).toEqual([ "user_message", "assistant_text", ]); }); it("correctly excludes messages by disabled category", () => { const enabled = new Set(ALL_CATEGORIES); enabled.delete("thinking"); const filtered = filterMessages(messages, enabled); expect(filtered).toHaveLength(8); expect(filtered.find((m) => m.category === "thinking")).toBeUndefined(); }); it("default filter state has thinking and hooks disabled", () => { const defaultEnabled = new Set(ALL_CATEGORIES); for (const cat of DEFAULT_HIDDEN_CATEGORIES) { defaultEnabled.delete(cat); } const filtered = filterMessages(messages, defaultEnabled); expect(filtered.find((m) => m.category === "thinking")).toBeUndefined(); expect(filtered.find((m) => m.category === "hook_progress")).toBeUndefined(); expect(filtered).toHaveLength(7); }); it("all-off filter returns empty array", () => { const filtered = filterMessages(messages, new Set()); expect(filtered).toEqual([]); }); it("all-on filter returns all messages", () => { const filtered = filterMessages(messages, new Set(ALL_CATEGORIES)); expect(filtered).toHaveLength(9); }); it("excludes redacted messages", () => { const enabled = new Set(ALL_CATEGORIES); const redacted = new Set(["1", "3"]); const filtered = filterMessages(messages, enabled, redacted); expect(filtered).toHaveLength(7); expect(filtered.find((m) => m.uuid === "1")).toBeUndefined(); expect(filtered.find((m) => m.uuid === "3")).toBeUndefined(); }); it("getMatchCount returns count of messages matching search query", () => { const lowerQuery = "content for 1"; const count = messages.filter((m) => m.content.toLowerCase().includes(lowerQuery) ).length; expect(count).toBe(1); }); it("getMatchCount returns 0 for empty query", () => { const lowerQuery = ""; const count = lowerQuery ? messages.filter((m) => m.content.toLowerCase().includes(lowerQuery)).length : 0; expect(count).toBe(0); }); it("conversation preset includes only user and assistant messages", () => { const preset: MessageCategory[] = ["user_message", "assistant_text"]; const enabled = new Set(preset); const filtered = filterMessages(messages, enabled); expect(filtered).toHaveLength(2); expect(filtered.every((m) => m.category === "user_message" || m.category === "assistant_text")).toBe(true); }); it("debug preset includes only tool calls and results", () => { const preset: MessageCategory[] = ["tool_call", "tool_result"]; const enabled = new Set(preset); const filtered = filterMessages(messages, enabled); expect(filtered).toHaveLength(2); expect(filtered.every((m) => m.category === "tool_call" || m.category === "tool_result")).toBe(true); }); it("category counts are computed correctly", () => { const counts: Record = {}; for (const cat of ALL_CATEGORIES) { counts[cat] = 0; } for (const msg of messages) { counts[msg.category]++; } expect(counts["user_message"]).toBe(1); expect(counts["assistant_text"]).toBe(1); expect(counts["thinking"]).toBe(1); expect(Object.values(counts).reduce((a, b) => a + b, 0)).toBe(9); }); it("category counts exclude redacted messages", () => { const redacted = new Set(["1", "2"]); const counts: Record = {}; for (const cat of ALL_CATEGORIES) { counts[cat] = 0; } for (const msg of messages) { if (!redacted.has(msg.uuid)) { counts[msg.category]++; } } expect(counts["user_message"]).toBe(0); expect(counts["assistant_text"]).toBe(0); expect(Object.values(counts).reduce((a, b) => a + b, 0)).toBe(7); }); });