mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2026-11-04 16:22:22 +01:00
Both dialogs asked for the name and owner as separate fields, so adding something you were looking at on GitHub meant reading the URL and retyping it in pieces. Each dialog now has a GitHub URL field above an OR divider; filling it populates the fields below. Pasting a URL into the name field splits it as well, rather than dropping the whole URL into one box. Parsing handles what people actually have on the clipboard: browser URLs, clone URLs, SSH remotes, the owner/repo shorthand, a bare host, and deep links into a repo. It drops the .git suffix, tolerates trailing slashes, query strings and angle-bracket wrapping, and rejects reserved GitHub paths like /settings so they cannot be read as an account name. Claude-Session: https://claude.ai/code/session_01QRhZnpehnrVtnPRqJYDdVQ
102 lines
3.6 KiB
TypeScript
102 lines
3.6 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
import {
|
|
looksLikeUrl,
|
|
parseGitHubOwnerReference,
|
|
parseGitHubRepoReference,
|
|
} from "./github-url";
|
|
|
|
describe("parseGitHubRepoReference", () => {
|
|
it("parses the browser URL", () => {
|
|
expect(parseGitHubRepoReference("https://github.com/vercel/next.js")).toEqual({
|
|
owner: "vercel",
|
|
repo: "next.js",
|
|
});
|
|
});
|
|
|
|
it("parses clone and SSH remotes, dropping the .git suffix", () => {
|
|
expect(
|
|
parseGitHubRepoReference("https://github.com/vercel/next.js.git")
|
|
).toEqual({ owner: "vercel", repo: "next.js" });
|
|
expect(
|
|
parseGitHubRepoReference("git@github.com:vercel/next.js.git")
|
|
).toEqual({ owner: "vercel", repo: "next.js" });
|
|
expect(
|
|
parseGitHubRepoReference("ssh://git@github.com/vercel/next.js.git")
|
|
).toEqual({ owner: "vercel", repo: "next.js" });
|
|
});
|
|
|
|
it("ignores everything after the repo in a deep link", () => {
|
|
expect(
|
|
parseGitHubRepoReference(
|
|
"https://github.com/vercel/next.js/tree/canary/packages/next"
|
|
)
|
|
).toEqual({ owner: "vercel", repo: "next.js" });
|
|
expect(
|
|
parseGitHubRepoReference("https://github.com/vercel/next.js/issues/123")
|
|
).toEqual({ owner: "vercel", repo: "next.js" });
|
|
});
|
|
|
|
it("accepts a bare host and the owner/repo shorthand", () => {
|
|
expect(parseGitHubRepoReference("github.com/vercel/next.js")).toEqual({
|
|
owner: "vercel",
|
|
repo: "next.js",
|
|
});
|
|
expect(parseGitHubRepoReference("vercel/next.js")).toEqual({
|
|
owner: "vercel",
|
|
repo: "next.js",
|
|
});
|
|
});
|
|
|
|
it("tolerates wrapping, trailing slashes, and query strings", () => {
|
|
expect(
|
|
parseGitHubRepoReference(" <https://github.com/vercel/next.js/> ")
|
|
).toEqual({ owner: "vercel", repo: "next.js" });
|
|
expect(
|
|
parseGitHubRepoReference("https://github.com/vercel/next.js?tab=readme")
|
|
).toEqual({ owner: "vercel", repo: "next.js" });
|
|
});
|
|
|
|
it("rejects input that does not name a repository", () => {
|
|
expect(parseGitHubRepoReference("")).toBeNull();
|
|
expect(parseGitHubRepoReference("https://github.com/vercel")).toBeNull();
|
|
expect(parseGitHubRepoReference("https://github.com/orgs/vercel")).toBeNull();
|
|
expect(parseGitHubRepoReference("https://github.com/settings/tokens")).toBeNull();
|
|
expect(parseGitHubRepoReference("not a url at all")).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("parseGitHubOwnerReference", () => {
|
|
it("parses profile, org, and bare-name forms", () => {
|
|
expect(parseGitHubOwnerReference("https://github.com/microsoft")).toBe(
|
|
"microsoft"
|
|
);
|
|
expect(
|
|
parseGitHubOwnerReference("https://github.com/orgs/microsoft/repositories")
|
|
).toBe("microsoft");
|
|
expect(parseGitHubOwnerReference("microsoft")).toBe("microsoft");
|
|
expect(parseGitHubOwnerReference("github.com/microsoft/")).toBe("microsoft");
|
|
});
|
|
|
|
it("takes the owner from a repository URL", () => {
|
|
expect(parseGitHubOwnerReference("https://github.com/vercel/next.js")).toBe(
|
|
"vercel"
|
|
);
|
|
});
|
|
|
|
it("rejects reserved GitHub paths and empty input", () => {
|
|
expect(parseGitHubOwnerReference("https://github.com/settings")).toBeNull();
|
|
expect(parseGitHubOwnerReference("")).toBeNull();
|
|
expect(parseGitHubOwnerReference(" ")).toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("looksLikeUrl", () => {
|
|
it("separates pasted references from plain names", () => {
|
|
expect(looksLikeUrl("https://github.com/vercel/next.js")).toBe(true);
|
|
expect(looksLikeUrl("git@github.com:vercel/next.js.git")).toBe(true);
|
|
expect(looksLikeUrl("vercel/next.js")).toBe(true);
|
|
expect(looksLikeUrl("next.js")).toBe(false);
|
|
expect(looksLikeUrl("microsoft")).toBe(false);
|
|
});
|
|
});
|