| 1 | // Run: tsx src/__tests__/remote-topic-active.test.ts |
| 2 | |
| 3 | import { topicIsActive } from "../components/ProjectTree"; |
| 4 | import { mergeRemoteSessionsIntoTree } from "../components/ProjectTreeRemoteGroups"; |
| 5 | import type { Translator } from "../lib/i18n"; |
| 6 | import type { ProjectNode } from "../lib/types"; |
| 7 | |
| 8 | const remoteProject: ProjectNode = { |
| 9 | key: "project_remote_box_app", kind: "project", label: "app", |
| 10 | root: "remote-project:box:~/app", remote: { hostId: "box", workspace: "~/app" }, |
| 11 | }; |
| 12 | const remoteTopic = mergeRemoteSessionsIntoTree([remoteProject], { |
| 13 | "box\u0000~/app": [{ name: "s1", title: "First chat", turns: 1, path: "/remote/sessions/s1.jsonl" }], |
| 14 | }, ((key: string) => key) as Translator)[0]?.children?.[0]; |
| 15 | if (!remoteTopic) throw new Error("remote topic was not synthesized"); |
| 16 | |
| 17 | function eq(actual: unknown, expected: unknown, label: string) { |
| 18 | if (actual !== expected) throw new Error(`${label}: expected ${String(expected)}, got ${String(actual)}`); |
| 19 | process.stdout.write(` PASS ${label}\n`); |
| 20 | } |
| 21 | |
| 22 | eq(topicIsActive(remoteTopic, "project", "~/app", remoteTopic.topicId, remoteTopic.sessionPath), true, |
| 23 | "matching remote identity is active"); |
| 24 | eq(topicIsActive(remoteTopic, "project", "~/app", "other-host\u0000~/app\u0000s1", remoteTopic.sessionPath), false, |
| 25 | "the same absolute path on another host stays inactive"); |
| 26 | eq(topicIsActive(remoteTopic, "project", "~/app", "", remoteTopic.sessionPath), false, |
| 27 | "remote rows never use an unqualified path-only fallback"); |
| 28 |