1import { EnvironmentId, ThreadId } from "@t3tools/contracts";
2import { describe, expect, it } from "vite-plus/test";
3
4import { matchComposerThreadItems } from "./composerThreadItems.ts";
5
6const env = EnvironmentId.make("env-1");
7const otherEnv = EnvironmentId.make("env-2");
8const shell = (
9 id: string,
10 title: string,
11 overrides: Partial<Parameters<typeof matchComposerThreadItems>[0]["shells"][number]> = {},
12) => ({
13 environmentId: env,
14 id: ThreadId.make(id),
15 title,
16 updatedAt: "2026-01-01T00:00:00.000Z",
17 archivedAt: null,
18 ...overrides,
19});
20
21describe("matchComposerThreadItems", () => {
22 it("offers nothing for a bare @ so the picker stays a file picker", () => {
23 expect(
24 matchComposerThreadItems({
25 shells: [shell("t1", "Fix login")],
26 environmentId: env,
27 excludeThreadId: null,
28 query: " ",
29 }),
30 ).toEqual([]);
31 });
32
33 it("matches titles within the environment, newest first, skipping self and archived", () => {
34 const items = matchComposerThreadItems({
35 shells: [
36 shell("old", "Login flow", { updatedAt: "2026-01-01T00:00:00.000Z" }),
37 shell("new", "Login redesign", { updatedAt: "2026-02-01T00:00:00.000Z" }),
38 shell("self", "Login self"),
39 shell("gone", "Login archived", { archivedAt: "2026-01-02T00:00:00.000Z" }),
40 shell("foreign", "Login elsewhere", { environmentId: otherEnv }),
41 shell("nope", "Unrelated"),
42 ],
43 environmentId: env,
44 excludeThreadId: ThreadId.make("self"),
45 query: "LOGIN",
46 });
47 expect(items.map((item) => item.thread.threadId)).toEqual(["new", "old"]);
48 expect(items[0]).toMatchObject({ type: "thread", label: "Login redesign" });
49 });
50});