| ... | @@ -226,108 +226,6 @@ describe("shouldOpenPullRequestExternally", () => { | ... | @@ -226,108 +226,6 @@ describe("shouldOpenPullRequestExternally", () => { |
| 226 | }); | 226 | }); |
| 227 | }); | 227 | }); |
| 228 | | 228 | |
| 229 | describe("parseChangeRequestUrl", () => { | | |
| 230 | it("reads a GitHub pull request", () => { | | |
| 231 | expect(parseChangeRequestUrl("https://github.com/T3Tools/T3Code/pull/123")).toEqual({ | | |
| 232 | host: "github.com", | | |
| 233 | repository: "t3tools/t3code", | | |
| 234 | number: 123, | | |
| 235 | }); | | |
| 236 | }); | | |
| 237 | | | |
| 238 | it("reads a pull request on a GitHub Enterprise host", () => { | | |
| 239 | expect(parseChangeRequestUrl("https://github.acme.test/platform/api/pull/7")).toEqual({ | | |
| 240 | host: "github.acme.test", | | |
| 241 | repository: "platform/api", | | |
| 242 | number: 7, | | |
| 243 | }); | | |
| 244 | }); | | |
| 245 | | | |
| 246 | it("reads a GitLab merge request, nested groups and all", () => { | | |
| 247 | expect( | | |
| 248 | parseChangeRequestUrl("https://gitlab.com/t3tools/platform/t3code/-/merge_requests/42"), | | |
| 249 | ).toEqual({ | | |
| 250 | host: "gitlab.com", | | |
| 251 | repository: "t3tools/platform/t3code", | | |
| 252 | number: 42, | | |
| 253 | }); | | |
| 254 | }); | | |
| 255 | | | |
| 256 | it("reads a merge request on a self-hosted GitLab named nothing like GitLab", () => { | | |
| 257 | expect(parseChangeRequestUrl("https://code.acme.test/team/project/-/merge_requests/9")).toEqual( | | |
| 258 | { | | |
| 259 | host: "code.acme.test", | | |
| 260 | repository: "team/project", | | |
| 261 | number: 9, | | |
| 262 | }, | | |
| 263 | ); | | |
| 264 | }); | | |
| 265 | | | |
| 266 | it("reads a Bitbucket pull request", () => { | | |
| 267 | expect(parseChangeRequestUrl("https://bitbucket.org/workspace/repo/pull-requests/5")).toEqual({ | | |
| 268 | host: "bitbucket.org", | | |
| 269 | repository: "workspace/repo", | | |
| 270 | number: 5, | | |
| 271 | }); | | |
| 272 | }); | | |
| 273 | | | |
| 274 | it("reads both Azure DevOps URL forms, keeping `_git` in the repository path", () => { | | |
| 275 | expect( | | |
| 276 | parseChangeRequestUrl("https://dev.azure.com/acme/platform/_git/t3code/pullrequest/17"), | | |
| 277 | ).toEqual({ | | |
| 278 | host: "dev.azure.com", | | |
| 279 | repository: "acme/platform/_git/t3code", | | |
| 280 | number: 17, | | |
| 281 | }); | | |
| 282 | expect( | | |
| 283 | parseChangeRequestUrl("https://acme.visualstudio.com/platform/_git/t3code/pullrequest/17"), | | |
| 284 | ).toEqual({ | | |
| 285 | host: "acme.visualstudio.com", | | |
| 286 | repository: "platform/_git/t3code", | | |
| 287 | number: 17, | | |
| 288 | }); | | |
| 289 | }); | | |
| 290 | | | |
| 291 | it("survives trailing segments, a trailing slash and a query string", () => { | | |
| 292 | expect(parseChangeRequestUrl("https://github.com/t3tools/t3code/pull/123/files?w=1")).toEqual({ | | |
| 293 | host: "github.com", | | |
| 294 | repository: "t3tools/t3code", | | |
| 295 | number: 123, | | |
| 296 | }); | | |
| 297 | expect( | | |
| 298 | parseChangeRequestUrl("https://gitlab.com/team/project/-/merge_requests/42/diffs#note_1"), | | |
| 299 | ).toEqual({ host: "gitlab.com", repository: "team/project", number: 42 }); | | |
| 300 | expect( | | |
| 301 | parseChangeRequestUrl("https://bitbucket.org/team/repo/pull-requests/5/commits"), | | |
| 302 | ).toEqual({ host: "bitbucket.org", repository: "team/repo", number: 5 }); | | |
| 303 | expect(parseChangeRequestUrl("https://github.com/t3tools/t3code/pull/123/")).toEqual({ | | |
| 304 | host: "github.com", | | |
| 305 | repository: "t3tools/t3code", | | |
| 306 | number: 123, | | |
| 307 | }); | | |
| 308 | }); | | |
| 309 | | | |
| 310 | it("claims nothing it cannot be sure of, so the link goes to the browser", () => { | | |
| 311 | for (const link of [ | | |
| 312 | "https://github.com/t3tools/t3code/issues/123", | | |
| 313 | "https://github.com/t3tools/t3code/commit/0a1b2c3", | | |
| 314 | "https://github.com/t3tools/t3code", | | |
| 315 | "https://github.com/t3tools/t3code/pull/abc", | | |
| 316 | "https://gitlab.com/t3tools/t3code/-/snippets/12", | | |
| 317 | "https://gitlab.com/t3tools/t3code/-/issues/12", | | |
| 318 | // A path shape that means nothing off its own host. | | |
| 319 | "https://blog.example.test/2026/updates/pull/3", | | |
| 320 | // A lookalike is deliberately not fought here: `github.com.evil.test` reads as a GitHub | | |
| 321 | // Enterprise install and there is no way to tell it from one. It is `findProjectForChange | | |
| 322 | // Request` that refuses it, because no project in the workspace is checked out from it. | | |
| 323 | "javascript:alert(1)//github.com/t3tools/t3code/pull/1", | | |
| 324 | "not a url", | | |
| 325 | ]) { | | |
| 326 | expect(parseChangeRequestUrl(link), link).toBeNull(); | | |
| 327 | } | | |
| 328 | }); | | |
| 329 | }); | | |
| 330 | | | |
| 331 | describe("findProjectOnChangeRequestHost", () => { | 229 | describe("findProjectOnChangeRequestHost", () => { |
| 332 | const project = (id: string, identity: Record<string, unknown>) => | 230 | const project = (id: string, identity: Record<string, unknown>) => |
| 333 | ({ id, repositoryIdentity: identity }) as never; | 231 | ({ id, repositoryIdentity: identity }) as never; |