generated from nhcarrigan/template
test: add comprehensive sessions store coverage (escapeHtml, generateHtmlExport, all exports)
This commit is contained in:
@@ -0,0 +1,515 @@
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
||||
import { get } from "svelte/store";
|
||||
import { sessionsStore } from "$lib/stores/sessions";
|
||||
import { setMockInvokeResult } from "../../../vitest.setup";
|
||||
import type { SavedSession } from "$lib/stores/sessions";
|
||||
|
||||
vi.mock("@tauri-apps/plugin-dialog", () => ({
|
||||
save: vi.fn(),
|
||||
open: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@tauri-apps/plugin-fs", () => ({
|
||||
writeTextFile: vi.fn().mockResolvedValue(undefined),
|
||||
readTextFile: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock("@tauri-apps/plugin-opener", () => ({
|
||||
openPath: vi.fn().mockResolvedValue(undefined),
|
||||
}));
|
||||
|
||||
const makeSavedSession = (overrides: Partial<SavedSession> = {}): SavedSession => ({
|
||||
id: "session-1",
|
||||
name: "Test Session",
|
||||
created_at: "2026-03-03T10:00:00.000Z",
|
||||
last_activity_at: "2026-03-03T11:00:00.000Z",
|
||||
working_directory: "/home/naomi/code",
|
||||
message_count: 2,
|
||||
preview: "Hello world",
|
||||
messages: [
|
||||
{ id: "msg-1", type: "user", content: "Hello world", timestamp: "2026-03-03T10:00:00.000Z" },
|
||||
{ id: "msg-2", type: "assistant", content: "Hi there!", timestamp: "2026-03-03T10:01:00.000Z" },
|
||||
],
|
||||
...overrides,
|
||||
});
|
||||
|
||||
const makeConversation = () => ({
|
||||
id: "conv-1",
|
||||
name: "Test Conversation",
|
||||
workingDirectory: "/home/naomi/code",
|
||||
createdAt: new Date("2026-03-03T10:00:00.000Z"),
|
||||
lastActivityAt: new Date("2026-03-03T11:00:00.000Z"),
|
||||
terminalLines: [
|
||||
{
|
||||
id: "line-1",
|
||||
type: "user",
|
||||
content: "Hello",
|
||||
timestamp: new Date("2026-03-03T10:00:00.000Z"),
|
||||
toolName: undefined,
|
||||
},
|
||||
{
|
||||
id: "line-2",
|
||||
type: "assistant",
|
||||
content: "Hi",
|
||||
timestamp: new Date("2026-03-03T10:01:00.000Z"),
|
||||
toolName: undefined,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
describe("sessionsStore - loadSessions", () => {
|
||||
it("loads sessions from backend and updates the store", async () => {
|
||||
const sessionList = [{ id: "session-1", name: "Test", message_count: 1, preview: "..." }];
|
||||
setMockInvokeResult("list_sessions", sessionList);
|
||||
await sessionsStore.loadSessions();
|
||||
expect(get(sessionsStore.sessions)).toEqual(sessionList);
|
||||
});
|
||||
|
||||
it("handles errors gracefully", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("list_sessions", new Error("Backend error"));
|
||||
await sessionsStore.loadSessions();
|
||||
expect(spy).toHaveBeenCalledWith("Failed to load sessions:", expect.any(Error));
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it("sets isLoading to false after completion", async () => {
|
||||
setMockInvokeResult("list_sessions", []);
|
||||
await sessionsStore.loadSessions();
|
||||
expect(get(sessionsStore.isLoading)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - loadSession", () => {
|
||||
it("returns session data on success", async () => {
|
||||
const session = makeSavedSession();
|
||||
setMockInvokeResult("load_session", session);
|
||||
const result = await sessionsStore.loadSession("session-1");
|
||||
expect(result).toEqual(session);
|
||||
});
|
||||
|
||||
it("returns null on error", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", new Error("Not found"));
|
||||
const result = await sessionsStore.loadSession("session-1");
|
||||
expect(result).toBeNull();
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - deleteSession", () => {
|
||||
it("deletes session and reloads the session list", async () => {
|
||||
setMockInvokeResult("delete_session", undefined);
|
||||
setMockInvokeResult("list_sessions", []);
|
||||
await sessionsStore.deleteSession("session-1");
|
||||
expect(get(sessionsStore.sessions)).toEqual([]);
|
||||
});
|
||||
|
||||
it("handles errors gracefully", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("delete_session", new Error("Failed"));
|
||||
await sessionsStore.deleteSession("session-1");
|
||||
expect(spy).toHaveBeenCalledWith("Failed to delete session:", expect.any(Error));
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - searchSessions", () => {
|
||||
it("calls loadSessions when query is empty", async () => {
|
||||
setMockInvokeResult("list_sessions", []);
|
||||
await sessionsStore.searchSessions("");
|
||||
expect(get(sessionsStore.sessions)).toEqual([]);
|
||||
});
|
||||
|
||||
it("calls loadSessions when query is whitespace-only", async () => {
|
||||
setMockInvokeResult("list_sessions", []);
|
||||
await sessionsStore.searchSessions(" ");
|
||||
expect(get(sessionsStore.sessions)).toEqual([]);
|
||||
});
|
||||
|
||||
it("searches with the given query", async () => {
|
||||
const results = [{ id: "session-1", name: "Test", message_count: 1, preview: "..." }];
|
||||
setMockInvokeResult("search_sessions", results);
|
||||
await sessionsStore.searchSessions("test");
|
||||
expect(get(sessionsStore.sessions)).toEqual(results);
|
||||
});
|
||||
|
||||
it("updates searchQuery store", async () => {
|
||||
setMockInvokeResult("search_sessions", []);
|
||||
await sessionsStore.searchSessions("hello");
|
||||
expect(get(sessionsStore.searchQuery)).toBe("hello");
|
||||
await sessionsStore.searchSessions("");
|
||||
});
|
||||
|
||||
it("handles search errors gracefully", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("search_sessions", new Error("Search failed"));
|
||||
await sessionsStore.searchSessions("error-query");
|
||||
expect(spy).toHaveBeenCalledWith("Failed to search sessions:", expect.any(Error));
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - clearAllSessions", () => {
|
||||
it("clears all sessions", async () => {
|
||||
setMockInvokeResult("clear_all_sessions", undefined);
|
||||
await sessionsStore.clearAllSessions();
|
||||
expect(get(sessionsStore.sessions)).toEqual([]);
|
||||
});
|
||||
|
||||
it("handles errors gracefully", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("clear_all_sessions", new Error("Failed"));
|
||||
await sessionsStore.clearAllSessions();
|
||||
expect(spy).toHaveBeenCalledWith("Failed to clear sessions:", expect.any(Error));
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - saveConversation", () => {
|
||||
it("saves conversation to backend", async () => {
|
||||
setMockInvokeResult("save_session", undefined);
|
||||
setMockInvokeResult("list_sessions", []);
|
||||
await sessionsStore.saveConversation(makeConversation() as never);
|
||||
});
|
||||
|
||||
it("handles save errors gracefully", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("save_session", new Error("Save failed"));
|
||||
await sessionsStore.saveConversation(makeConversation() as never);
|
||||
expect(spy).toHaveBeenCalledWith("Failed to save session:", expect.any(Error));
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it("handles empty conversation", async () => {
|
||||
setMockInvokeResult("save_session", undefined);
|
||||
setMockInvokeResult("list_sessions", []);
|
||||
const conv = { ...makeConversation(), terminalLines: [] };
|
||||
await sessionsStore.saveConversation(conv as never);
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - scheduleAutoSave and cancelAutoSave", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("schedules an auto-save after the debounce delay", async () => {
|
||||
setMockInvokeResult("save_session", undefined);
|
||||
setMockInvokeResult("list_sessions", []);
|
||||
sessionsStore.scheduleAutoSave(makeConversation() as never);
|
||||
await vi.advanceTimersByTimeAsync(2001);
|
||||
});
|
||||
|
||||
it("does not auto-save empty conversations", async () => {
|
||||
const conv = { ...makeConversation(), terminalLines: [] };
|
||||
sessionsStore.scheduleAutoSave(conv as never);
|
||||
await vi.advanceTimersByTimeAsync(3000);
|
||||
});
|
||||
|
||||
it("cancels a pending auto-save", () => {
|
||||
const conv = makeConversation();
|
||||
sessionsStore.scheduleAutoSave(conv as never);
|
||||
sessionsStore.cancelAutoSave(conv.id);
|
||||
});
|
||||
|
||||
it("handles cancel when no auto-save is pending", () => {
|
||||
sessionsStore.cancelAutoSave("non-existent-id");
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - exportSessionAsJson", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("returns true on successful export", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue("/output/session.json");
|
||||
expect(await sessionsStore.exportSessionAsJson("session-1")).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when session not found", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", null);
|
||||
expect(await sessionsStore.exportSessionAsJson("session-1")).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it("returns false when user cancels save dialog", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue(null);
|
||||
expect(await sessionsStore.exportSessionAsJson("session-1")).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false on error", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", new Error("Load failed"));
|
||||
expect(await sessionsStore.exportSessionAsJson("session-1")).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - exportSessionAsMarkdown", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("generates markdown with all message types", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
const session = makeSavedSession({
|
||||
messages: [
|
||||
{ id: "1", type: "user", content: "User message", timestamp: "2026-03-03T10:00:00Z" },
|
||||
{
|
||||
id: "2",
|
||||
type: "assistant",
|
||||
content: "Assistant reply",
|
||||
timestamp: "2026-03-03T10:01:00Z",
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
type: "tool_use",
|
||||
content: "Tool input",
|
||||
timestamp: "2026-03-03T10:02:00Z",
|
||||
tool_name: "bash",
|
||||
},
|
||||
{ id: "4", type: "tool_result", content: "Tool output", timestamp: "2026-03-03T10:03:00Z" },
|
||||
{ id: "5", type: "system", content: "System event", timestamp: "2026-03-03T10:04:00Z" },
|
||||
{ id: "6", type: "error", content: "Error message", timestamp: "2026-03-03T10:05:00Z" },
|
||||
],
|
||||
});
|
||||
setMockInvokeResult("load_session", session);
|
||||
vi.mocked(save).mockResolvedValue("/output/session.md");
|
||||
expect(await sessionsStore.exportSessionAsMarkdown("session-1")).toBe(true);
|
||||
const content = vi.mocked(writeTextFile).mock.calls[0][1] as string;
|
||||
expect(content).toContain("User message");
|
||||
expect(content).toContain("Assistant reply");
|
||||
expect(content).toContain("Tool: bash");
|
||||
expect(content).toContain("Tool input");
|
||||
expect(content).toContain("Tool output");
|
||||
expect(content).toContain("System event");
|
||||
expect(content).toContain("Error message");
|
||||
});
|
||||
|
||||
it("returns false when session not found", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", null);
|
||||
expect(await sessionsStore.exportSessionAsMarkdown("session-1")).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it("returns false when user cancels dialog", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue(null);
|
||||
expect(await sessionsStore.exportSessionAsMarkdown("session-1")).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false on error", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", new Error("Load failed"));
|
||||
expect(await sessionsStore.exportSessionAsMarkdown("session-1")).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - exportSessionAsHtml (tests escapeHtml + generateHtmlExport)", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("generates HTML and returns true on success", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue("/output/session.html");
|
||||
expect(await sessionsStore.exportSessionAsHtml("session-1")).toBe(true);
|
||||
const content = vi.mocked(writeTextFile).mock.calls[0][1] as string;
|
||||
expect(content).toContain("<!DOCTYPE html>");
|
||||
expect(content).toContain("Test Session");
|
||||
});
|
||||
|
||||
it("escapes HTML characters in session name", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
setMockInvokeResult("load_session", makeSavedSession({ name: "<Test & 'Session'>" }));
|
||||
vi.mocked(save).mockResolvedValue("/output/session.html");
|
||||
await sessionsStore.exportSessionAsHtml("session-1");
|
||||
const content = vi.mocked(writeTextFile).mock.calls[0][1] as string;
|
||||
expect(content).toContain("<Test & 'Session'>");
|
||||
expect(content).not.toContain("<Test & 'Session'>");
|
||||
});
|
||||
|
||||
it("escapes HTML characters in message content", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
setMockInvokeResult(
|
||||
"load_session",
|
||||
makeSavedSession({
|
||||
messages: [
|
||||
{
|
||||
id: "1",
|
||||
type: "user",
|
||||
content: '<script>alert("xss")</script>',
|
||||
timestamp: "2026-03-03T10:00:00Z",
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
vi.mocked(save).mockResolvedValue("/output/session.html");
|
||||
await sessionsStore.exportSessionAsHtml("session-1");
|
||||
const content = vi.mocked(writeTextFile).mock.calls[0][1] as string;
|
||||
expect(content).toContain("<script>alert("xss")</script>");
|
||||
expect(content).not.toContain("<script>");
|
||||
});
|
||||
|
||||
it("escapes HTML in tool names", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
setMockInvokeResult(
|
||||
"load_session",
|
||||
makeSavedSession({
|
||||
messages: [
|
||||
{
|
||||
id: "1",
|
||||
type: "tool_use",
|
||||
content: "input",
|
||||
timestamp: "2026-03-03T10:00:00Z",
|
||||
tool_name: "<dangerous>",
|
||||
},
|
||||
],
|
||||
})
|
||||
);
|
||||
vi.mocked(save).mockResolvedValue("/output/session.html");
|
||||
await sessionsStore.exportSessionAsHtml("session-1");
|
||||
const content = vi.mocked(writeTextFile).mock.calls[0][1] as string;
|
||||
expect(content).toContain("<dangerous>");
|
||||
expect(content).not.toContain("<dangerous>");
|
||||
});
|
||||
|
||||
it("excludes metadata when includeMetadata is false", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue("/output/session.html");
|
||||
await sessionsStore.exportSessionAsHtml("session-1", false);
|
||||
const content = vi.mocked(writeTextFile).mock.calls[0][1] as string;
|
||||
expect(content).not.toContain('class="metadata"');
|
||||
});
|
||||
|
||||
it("returns false when session not found", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", null);
|
||||
expect(await sessionsStore.exportSessionAsHtml("session-1")).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it("returns false when user cancels dialog", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue(null);
|
||||
expect(await sessionsStore.exportSessionAsHtml("session-1")).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false on error", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", new Error("Load failed"));
|
||||
expect(await sessionsStore.exportSessionAsHtml("session-1")).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - exportSessionAsPdf (tests generatePrintableHtml)", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("generates printable HTML and opens it in the browser", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { openPath } = await import("@tauri-apps/plugin-opener");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue("/output/session-print.html");
|
||||
expect(await sessionsStore.exportSessionAsPdf("session-1")).toBe(true);
|
||||
expect(openPath).toHaveBeenCalledWith("/output/session-print.html");
|
||||
const content = vi.mocked(writeTextFile).mock.calls[0][1] as string;
|
||||
expect(content).toContain("<!DOCTYPE html>");
|
||||
});
|
||||
|
||||
it("excludes metadata when includeMetadata is false", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
const { writeTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue("/output/session-print.html");
|
||||
await sessionsStore.exportSessionAsPdf("session-1", false);
|
||||
expect(vi.mocked(writeTextFile).mock.calls[0][1]).toBeDefined();
|
||||
});
|
||||
|
||||
it("returns false when session not found", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", null);
|
||||
expect(await sessionsStore.exportSessionAsPdf("session-1")).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it("returns false when user cancels dialog", async () => {
|
||||
const { save } = await import("@tauri-apps/plugin-dialog");
|
||||
setMockInvokeResult("load_session", makeSavedSession());
|
||||
vi.mocked(save).mockResolvedValue(null);
|
||||
expect(await sessionsStore.exportSessionAsPdf("session-1")).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false on error", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
setMockInvokeResult("load_session", new Error("Load failed"));
|
||||
expect(await sessionsStore.exportSessionAsPdf("session-1")).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
||||
describe("sessionsStore - importSession", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("imports session from JSON file and returns true", async () => {
|
||||
const { open } = await import("@tauri-apps/plugin-dialog");
|
||||
const { readTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
vi.mocked(open).mockResolvedValue("/input/session.json");
|
||||
vi.mocked(readTextFile).mockResolvedValue(JSON.stringify({ session: makeSavedSession() }));
|
||||
setMockInvokeResult("save_session", undefined);
|
||||
setMockInvokeResult("list_sessions", []);
|
||||
expect(await sessionsStore.importSession()).toBe(true);
|
||||
});
|
||||
|
||||
it("returns false when user cancels file dialog", async () => {
|
||||
const { open } = await import("@tauri-apps/plugin-dialog");
|
||||
vi.mocked(open).mockResolvedValue(null);
|
||||
expect(await sessionsStore.importSession()).toBe(false);
|
||||
});
|
||||
|
||||
it("returns false when file has invalid format", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
const { open } = await import("@tauri-apps/plugin-dialog");
|
||||
const { readTextFile } = await import("@tauri-apps/plugin-fs");
|
||||
vi.mocked(open).mockResolvedValue("/input/bad.json");
|
||||
vi.mocked(readTextFile).mockResolvedValue(JSON.stringify({ not_a_session: true }));
|
||||
expect(await sessionsStore.importSession()).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
|
||||
it("returns false on error", async () => {
|
||||
const spy = vi.spyOn(console, "error").mockImplementation(() => {});
|
||||
const { open } = await import("@tauri-apps/plugin-dialog");
|
||||
vi.mocked(open).mockRejectedValue(new Error("Dialog failed"));
|
||||
expect(await sessionsStore.importSession()).toBe(false);
|
||||
spy.mockRestore();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user