190 lines · 6.0 KB · TypeScript
RawDownload
import { ProjectId, type ThreadPullRequestLink, type VcsStatusResult } from "@t3tools/contracts";import { describe, expect, it } from "vite-plus/test"; import {  presentThreadLinkedPullRequests,  presentThreadPr,  resolveThreadPrSource,} from "./thread-pr-presentation"; const pullRequest: NonNullable<VcsStatusResult["pr"]> = {  number: 3774,  title: "Desktop-style pull request indicator",  url: "https://github.com/t3tools/t3code/pull/3774",  baseRef: "main",  headRef: "codex/desktop-style-pr-indicator",  state: "merged",}; describe("presentThreadPr", () => {  it("uses the compact pull request number label without a hash prefix", () => {    expect(presentThreadPr(pullRequest, undefined)).toMatchObject({      label: "3774",      accessibilityLabel: "#3774 pull request merged",      textClassName: "text-adaptive-violet-600-400",    });  });   it("uses merge-request terminology for GitLab", () => {    expect(      presentThreadPr(pullRequest, {        kind: "gitlab",        name: "GitLab",        baseUrl: "https://gitlab.com",      }),    ).toMatchObject({      label: "3774",      accessibilityLabel: "#3774 merge request merged",    });  });   it("uses gray for draft pull requests", () => {    expect(      presentThreadPr({ ...pullRequest, state: "open", isDraft: true }, undefined),    ).toMatchObject({      accessibilityLabel: "#3774 pull request draft",      textClassName: "text-foreground-muted",    });  });}); function linkedPr(  number: number,  overrides: Partial<ThreadPullRequestLink> = {},): ThreadPullRequestLink {  return {    host: "github.com",    repository: "t3tools/t3code",    number,    url: `https://github.com/t3tools/t3code/pull/${number}`,    source: "manual",    linkedAt: "2026-09-08T00:00:00.000Z",    stack: null,    snapshot: {      state: "open",      title: `Change ${number}`,      headBranch: `change-${number}`,      baseBranch: "main",      isDraft: false,      updatedAt: null,      syncedAt: "2026-09-08T00:00:00.000Z",    },    ...overrides,  };} describe("presentThreadLinkedPullRequests", () => {  it("renders unsynced links with neutral pending status", () => {    expect(presentThreadLinkedPullRequests([linkedPr(1, { snapshot: null })])).toMatchObject({      number: 1,      label: "1",      state: null,      textClassName: "text-foreground-muted",      accessibilityLabel: "#1 pull request status pending",    });  });   it("counts unrelated links without labelling them a stack", () => {    expect(presentThreadLinkedPullRequests([linkedPr(1), linkedPr(2)])).toMatchObject({      kind: "pull-request",      label: "+2",      others: 1,      textClassName: "text-foreground-muted",    });  });   it("uses the top of a derived stack even when its bottom was linked later", () => {    const bottom = linkedPr(1, { linkedAt: "2026-09-09T00:00:00.000Z" });    const top = linkedPr(2);    expect(      presentThreadLinkedPullRequests([        bottom,        {          ...top,          snapshot: { ...top.snapshot!, baseBranch: "change-1" },        },      ]),    ).toMatchObject({ kind: "stack", label: "2", number: 2, url: top.url });  });   it("hides dismissed stack members", () => {    expect(      presentThreadLinkedPullRequests([linkedPr(1, { source: "stack-dismissed" })]),    ).toBeNull();  });   it("retains merged state from the persisted snapshot", () => {    const link = linkedPr(1);    expect(      presentThreadLinkedPullRequests([        { ...link, snapshot: { ...link.snapshot!, state: "merged" } },      ]),    ).toMatchObject({ state: "merged", textClassName: "text-adaptive-violet-600-400" });  });}); describe("resolveThreadPrSource compatibility", () => {  const legacyRef = {    projectId: ProjectId.make("project"),    repository: "t3tools/t3code",    number: 1,    url: "https://github.com/t3tools/t3code/pull/1",  };  const branchRef = { ...legacyRef, number: 2, url: "https://github.com/t3tools/t3code/pull/2" };   it("polls the legacy reference when only the older linking capability exists", () => {    expect(      resolveThreadPrSource(        { pullRequests: [], linkedPullRequest: legacyRef, branchPullRequest: branchRef },        { threadPullRequestLinking: true },      ),    ).toEqual({ linkedPresentation: null, pullRequestRef: legacyRef });  });   it("keeps the legacy reference for a server without either capability", () => {    expect(resolveThreadPrSource({ pullRequests: [], linkedPullRequest: legacyRef }, {})).toEqual({      linkedPresentation: null,      pullRequestRef: legacyRef,    });  });   it("ignores stale snapshots after reconnecting to a server without array support", () => {    expect(      resolveThreadPrSource(        { pullRequests: [linkedPr(3)], linkedPullRequest: legacyRef },        { threadPullRequestLinking: true, threadPullRequests: false },      ),    ).toEqual({ linkedPresentation: null, pullRequestRef: legacyRef });  });   it("uses snapshots without polling when both capabilities are advertised", () => {    expect(      resolveThreadPrSource(        { pullRequests: [linkedPr(3)], linkedPullRequest: legacyRef, branchPullRequest: branchRef },        { threadPullRequestLinking: true, threadPullRequests: true },      ),    ).toMatchObject({ linkedPresentation: { number: 3 }, pullRequestRef: null });  });   it("does not revive a removed modern link from the compatibility reference", () => {    expect(      resolveThreadPrSource(        { pullRequests: [], linkedPullRequest: legacyRef, branchPullRequest: branchRef },        { threadPullRequests: true },      ),    ).toEqual({ linkedPresentation: null, pullRequestRef: branchRef });  });   it("does not poll when a modern link is waiting for its first snapshot", () => {    expect(      resolveThreadPrSource(        {          pullRequests: [linkedPr(3, { snapshot: null })],          linkedPullRequest: legacyRef,          branchPullRequest: branchRef,        },        { threadPullRequests: true },      ),    ).toMatchObject({ linkedPresentation: { number: 3, state: null }, pullRequestRef: null });  });});