From b403d5fbe055a5691709fb0ca29798a1be2336f9 Mon Sep 17 00:00:00 2001 From: sudorest Date: Sun, 29 Mar 2026 09:20:56 +0000 Subject: [PATCH] test: cover PR/MR platform helpers --- packages/review-editor/App.tsx | 15 ++- packages/shared/pr-provider.test.ts | 143 ++++++++++++++++++++++++++++ 2 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 packages/shared/pr-provider.test.ts diff --git a/packages/review-editor/App.tsx b/packages/review-editor/App.tsx index 9fcb3049..9204d76a 100644 --- a/packages/review-editor/App.tsx +++ b/packages/review-editor/App.tsx @@ -129,7 +129,18 @@ const ReviewApp: React.FC = () => { const [platformUser, setPlatformUser] = useState(null); const [platformCommentDialog, setPlatformCommentDialog] = useState<{ action: 'approve' | 'comment' } | null>(null); const [platformGeneralComment, setPlatformGeneralComment] = useState(''); - const [platformOpenPR, setPlatformOpenPR] = useState(() => storage.getItem('plannotator-github-open-pr') !== 'false'); + const [platformOpenPR, setPlatformOpenPR] = useState(() => { + const platformSetting = storage.getItem('plannotator-platform-open-pr'); + if (platformSetting !== null) return platformSetting !== 'false'; + + const legacyGitHubSetting = storage.getItem('plannotator-github-open-pr'); + if (legacyGitHubSetting !== null) { + storage.setItem('plannotator-platform-open-pr', legacyGitHubSetting); + return legacyGitHubSetting !== 'false'; + } + + return true; + }); // Derived: Platform mode is active when destination is platform AND we have PR/MR metadata const platformMode = reviewDestination === 'platform' && !!prMetadata; @@ -1600,7 +1611,7 @@ const ReviewApp: React.FC = () => { checked={platformOpenPR} onChange={e => { setPlatformOpenPR(e.target.checked); - storage.setItem('plannotator-github-open-pr', String(e.target.checked)); + storage.setItem('plannotator-platform-open-pr', String(e.target.checked)); }} className="rounded border-border" /> diff --git a/packages/shared/pr-provider.test.ts b/packages/shared/pr-provider.test.ts new file mode 100644 index 00000000..6a6832fc --- /dev/null +++ b/packages/shared/pr-provider.test.ts @@ -0,0 +1,143 @@ +import { describe, expect, test } from "bun:test"; +import { + getCliInstallUrl, + getCliName, + getDisplayRepo, + getMRLabel, + getMRNumberLabel, + getPlatformLabel, + parsePRUrl, + prRefFromMetadata, + type PRMetadata, +} from "./pr-provider"; + +describe("pr-provider platform helpers", () => { + test("parses GitHub PR URLs including nested suffixes", () => { + const ref = parsePRUrl("https://github.com/backnotprop/plannotator/pull/364/files"); + + expect(ref).toEqual({ + platform: "github", + owner: "backnotprop", + repo: "plannotator", + number: 364, + }); + }); + + test("parses GitLab.com MR URLs", () => { + const ref = parsePRUrl("https://gitlab.com/group/project/-/merge_requests/42/diffs"); + + expect(ref).toEqual({ + platform: "gitlab", + host: "gitlab.com", + projectPath: "group/project", + iid: 42, + }); + }); + + test("parses self-hosted GitLab MR URLs with nested groups", () => { + const ref = parsePRUrl("https://gitlab.example.com/group/subgroup/project/-/merge_requests/7"); + + expect(ref).toEqual({ + platform: "gitlab", + host: "gitlab.example.com", + projectPath: "group/subgroup/project", + iid: 7, + }); + }); + + test("returns null for unsupported URLs", () => { + expect(parsePRUrl("https://example.com/not-a-pr/123")).toBeNull(); + expect(parsePRUrl("")).toBeNull(); + }); + + test("formats platform-aware labels for GitHub and GitLab", () => { + const githubMeta: PRMetadata = { + platform: "github", + owner: "backnotprop", + repo: "plannotator", + number: 364, + title: "GitHub PR", + author: "backnotprop", + baseBranch: "main", + headBranch: "feature/github", + baseSha: "base", + headSha: "head", + url: "https://github.com/backnotprop/plannotator/pull/364", + }; + + const gitlabMeta: PRMetadata = { + platform: "gitlab", + host: "gitlab.example.com", + projectPath: "group/project", + iid: 42, + title: "GitLab MR", + author: "alice", + baseBranch: "main", + headBranch: "feature/gitlab", + baseSha: "base", + headSha: "head", + url: "https://gitlab.example.com/group/project/-/merge_requests/42", + }; + + expect(getPlatformLabel(githubMeta)).toBe("GitHub"); + expect(getMRLabel(githubMeta)).toBe("PR"); + expect(getMRNumberLabel(githubMeta)).toBe("#364"); + expect(getDisplayRepo(githubMeta)).toBe("backnotprop/plannotator"); + + expect(getPlatformLabel(gitlabMeta)).toBe("GitLab"); + expect(getMRLabel(gitlabMeta)).toBe("MR"); + expect(getMRNumberLabel(gitlabMeta)).toBe("!42"); + expect(getDisplayRepo(gitlabMeta)).toBe("group/project"); + }); + + test("reconstructs refs and CLI metadata for each platform", () => { + const githubMeta: PRMetadata = { + platform: "github", + owner: "backnotprop", + repo: "plannotator", + number: 1, + title: "GitHub PR", + author: "backnotprop", + baseBranch: "main", + headBranch: "feature/github", + baseSha: "base", + headSha: "head", + url: "https://github.com/backnotprop/plannotator/pull/1", + }; + + const gitlabMeta: PRMetadata = { + platform: "gitlab", + host: "gitlab.example.com", + projectPath: "group/project", + iid: 2, + title: "GitLab MR", + author: "alice", + baseBranch: "main", + headBranch: "feature/gitlab", + baseSha: "base", + headSha: "head", + url: "https://gitlab.example.com/group/project/-/merge_requests/2", + }; + + const githubRef = prRefFromMetadata(githubMeta); + const gitlabRef = prRefFromMetadata(gitlabMeta); + + expect(githubRef).toEqual({ + platform: "github", + owner: "backnotprop", + repo: "plannotator", + number: 1, + }); + expect(gitlabRef).toEqual({ + platform: "gitlab", + host: "gitlab.example.com", + projectPath: "group/project", + iid: 2, + }); + + expect(getCliName(githubRef)).toBe("gh"); + expect(getCliInstallUrl(githubRef)).toBe("https://cli.github.com"); + expect(getCliName(gitlabRef)).toBe("glab"); + expect(getCliInstallUrl(gitlabRef)).toBe("https://gitlab.com/gitlab-org/cli"); + }); +});