import type { InboxItem } from "@rakazo/contracts"; import { describe, expect, it } from "vitest"; import { inboxItemKey, inboxRefreshSignal } from "./main-inbox"; const bot = { id: "bot-scout", name: "Scout", color: "#3B82F6" }; const base = { bot, target: { botId: bot.id }, createdAt: "2026-10-02T09:00:00.000Z" }; const ask = { kind: "ask", text: "Which city?", status: "pending" } as const; describe("inboxItemKey", () => { it("keys asks by message, takeovers by run, and unread threads by bot", () => { const items: InboxItem[] = [ { ...base, kind: "ask", runId: "run-1", messageId: "msg-1", ask }, { ...base, kind: "approval", runId: "run-2", messageId: "msg-2", ask }, { ...base, kind: "takeover", runId: "run-3", messageId: null, text: "" }, { ...base, kind: "unread", messageId: "msg-4", text: "hi" }, ]; expect(items.map(inboxItemKey)).toEqual([ "ask:msg-1", "ask:msg-2", "takeover:run-3", `unread:${bot.id}`, ]); }); }); describe("inboxRefreshSignal", () => { const idle = { id: bot.id, status: "idle", unread: false, preview: "done" }; it("stays the same while nothing the inbox shows has changed", () => { expect(inboxRefreshSignal([idle])).toBe(inboxRefreshSignal([{ ...idle }])); }); it("changes with run status, unread state, or a new message", () => { const signal = inboxRefreshSignal([idle]); expect(inboxRefreshSignal([{ ...idle, status: "waiting_input" }])).not.toBe(signal); expect(inboxRefreshSignal([{ ...idle, unread: true }])).not.toBe(signal); expect(inboxRefreshSignal([{ ...idle, preview: "Which city?" }])).not.toBe(signal); }); });