import { getReadmeFromGitRepo } from "../getGit";
function mockFetch(responses: Record<string, string>) {
return jest.fn(async (url: string) => {
if (url in responses) {
return {
ok: true,
text: async () => responses[url],
} as Response;
}
return {
ok: false,
text: async () => "",
} as Response;
});
}
describe("getReadmeFromGitRepo", () => {
afterEach(() => {
jest.restoreAllMocks();
});
it("throws on invalid repository URLs", async () => {
await expect(getReadmeFromGitRepo("https://github.com/owner")).rejects.toThrow(
"Invalid repository URL: https://github.com/owner"
);
});
it("returns README content from the first successful URL", async () => {
const url = "https://raw.githubusercontent.com/acme/project/main/README.md";
const fetchMock = mockFetch({ [url]: "README content" });
jest.spyOn(globalThis, "fetch").mockImplementation(fetchMock as typeof fetch);
const result = await getReadmeFromGitRepo("https://github.com/acme/project");
expect(result).toBe("README content");
expect(fetchMock).toHaveBeenCalledWith(url);
});
it("handles GitLab raw README URLs", async () => {
const url = "https://gitlab.com/acme/project/-/raw/main/README.md";
const fetchMock = mockFetch({ [url]: "GitLab README" });
jest.spyOn(globalThis, "fetch").mockImplementation(fetchMock as typeof fetch);
const result = await getReadmeFromGitRepo("https://gitlab.com/acme/project");
expect(result).toBe("GitLab README");
expect(fetchMock).toHaveBeenCalledWith(url);
});
it("handles Bitbucket raw README URLs", async () => {
const url = "https://bitbucket.org/acme/project/raw/main/README.md";
const fetchMock = mockFetch({ [url]: "Bitbucket README" });
jest.spyOn(globalThis, "fetch").mockImplementation(fetchMock as typeof fetch);
const result = await getReadmeFromGitRepo("https://bitbucket.org/acme/project");
expect(result).toBe("Bitbucket README");
expect(fetchMock).toHaveBeenCalledWith(url);
});
it("handles unknown providers with fallback raw URLs", async () => {
const url = "https://example.com/acme/project/-/raw/main/README.md";
const fetchMock = mockFetch({ [url]: "Unknown README" });
jest.spyOn(globalThis, "fetch").mockImplementation(fetchMock as typeof fetch);
const result = await getReadmeFromGitRepo("https://example.com/acme/project");
expect(result).toBe("Unknown README");
expect(fetchMock).toHaveBeenCalledWith(url);
});
it("tries multiple branches and filenames before succeeding", async () => {
const url = "https://raw.githubusercontent.com/acme/project/master/README.rst";
const fetchMock = mockFetch({ [url]: "RST content" });
jest.spyOn(globalThis, "fetch").mockImplementation(fetchMock as typeof fetch);
const result = await getReadmeFromGitRepo("https://github.com/acme/project");
expect(result).toBe("RST content");
expect(fetchMock).toHaveBeenCalled();
});
it("keeps trying when a fetch call fails", async () => {
const url = "https://raw.githubusercontent.com/acme/project/main/README.md";
const fetchMock = jest
.fn()
.mockRejectedValueOnce(new Error("network down"))
.mockResolvedValueOnce({
ok: true,
text: async () => "Recovered README",
} as Response);
jest.spyOn(globalThis, "fetch").mockImplementation(fetchMock as typeof fetch);
const result = await getReadmeFromGitRepo("https://github.com/acme/project");
expect(result).toBe("Recovered README");
});
it("throws when no README can be found", async () => {
const fetchMock = mockFetch({});
jest.spyOn(globalThis, "fetch").mockImplementation(fetchMock as typeof fetch);
await expect(
getReadmeFromGitRepo("https://github.com/acme/project")
).rejects.toThrow("Could not find README in repository: https://github.com/acme/project");
});
});