| 1 | import { parseNewThreadLink } from "@t3tools/shared/promptLinks"; |
| 2 | import { describe, expect, it } from "vite-plus/test"; |
| 3 | |
| 4 | import { |
| 5 | latestThreadEnvironmentIds, |
| 6 | linkedThreadDraftAction, |
| 7 | promptLinkNotice, |
| 8 | promptLinkScratchEnvironmentId, |
| 9 | promptLinkSearchFromParams, |
| 10 | } from "./prompt-link-model"; |
| 11 | |
| 12 | describe("promptLinkSearchFromParams", () => { |
| 13 | it("round-trips decoded route params into the shared parser", () => { |
| 14 | const search = promptLinkSearchFromParams({ |
| 15 | prompt: "Fix the bug & add tests = done?", |
| 16 | repo: ["pingdotgg/t3code", "ignored/second"], |
| 17 | provider: "codex", |
| 18 | screen: "NewTask", |
| 19 | }); |
| 20 | |
| 21 | expect(parseNewThreadLink(search ?? "")).toEqual({ |
| 22 | ok: true, |
| 23 | value: { |
| 24 | kind: "new", |
| 25 | prompt: { text: "Fix the bug & add tests = done?", hiddenCharacters: 0 }, |
| 26 | repository: { owner: "pingdotgg", name: "t3code" }, |
| 27 | provider: "codex", |
| 28 | model: null, |
| 29 | }, |
| 30 | }); |
| 31 | }); |
| 32 | |
| 33 | it("is null for routes without a prompt link", () => { |
| 34 | expect(promptLinkSearchFromParams({ incomingShareId: "share-1" })).toBeNull(); |
| 35 | expect(promptLinkSearchFromParams(undefined)).toBeNull(); |
| 36 | }); |
| 37 | }); |
| 38 | |
| 39 | describe("promptLinkNotice", () => { |
| 40 | it("replaces the plain notice with the hidden character warning", () => { |
| 41 | expect(promptLinkNotice({ hiddenCharacters: 0 })).toBe( |
| 42 | "This prompt came from a link. Read it before you send.", |
| 43 | ); |
| 44 | expect(promptLinkNotice({ hiddenCharacters: 2, modelUnavailable: true })).toBe( |
| 45 | "This prompt had hidden characters, it may be malicious. They were removed. Read it before you send.\n\nThe requested model is not available, so your default is used.", |
| 46 | ); |
| 47 | }); |
| 48 | }); |
| 49 | |
| 50 | describe("linkedThreadDraftAction", () => { |
| 51 | it("fills an empty composer and asks before replacing typed text", () => { |
| 52 | expect(linkedThreadDraftAction(" \n", "Do it")).toBe("fill"); |
| 53 | expect(linkedThreadDraftAction("Do it", "Do it")).toBe("keep"); |
| 54 | expect(linkedThreadDraftAction("My notes", "Do it")).toBe("ask"); |
| 55 | }); |
| 56 | }); |
| 57 | |
| 58 | describe("promptLinkScratchEnvironmentId", () => { |
| 59 | it("prefers the most recently active machine that offers threads without a project", () => { |
| 60 | expect(promptLinkScratchEnvironmentId(["a", "b", "c"], ["c", "b"])).toBe("b"); |
| 61 | expect(promptLinkScratchEnvironmentId(["a"], ["c"])).toBe("c"); |
| 62 | expect(promptLinkScratchEnvironmentId(["a"], [])).toBeNull(); |
| 63 | }); |
| 64 | }); |
| 65 | |
| 66 | describe("latestThreadEnvironmentIds", () => { |
| 67 | it("orders machines by their latest thread", () => { |
| 68 | expect( |
| 69 | latestThreadEnvironmentIds([ |
| 70 | { environmentId: "a", updatedAt: "2026-01-02T00:00:00.000Z" }, |
| 71 | { environmentId: "b", updatedAt: "2026-01-03T00:00:00.000Z" }, |
| 72 | { environmentId: "a", updatedAt: "2026-01-04T00:00:00.000Z" }, |
| 73 | ]), |
| 74 | ).toEqual(["a", "b"]); |
| 75 | }); |
| 76 | }); |