import { describe, expect, test } from "vitest";
import { coAuthors, safeHttpUrl } from "@app/lib/utils";
describe("safeHttpUrl", () => {
test.each([
["http://example.com/", "http://example.com/"],
["https://example.com/path?a=1&b=2", "https://example.com/path?a=1&b=2"],
["HTTP://EXAMPLE.com/Path", "http://example.com/Path"],
["http://example.com/",
"vbscript:msgbox(1)",
"file:///etc/passwd",
"//example.com",
"/relative/path",
"relative",
"",
"not a url",
])("rejects %p", input => {
expect(safeHttpUrl(input)).toBeUndefined();
});
});
describe("coAuthors", () => {
test("reads trailers from the final paragraph", () => {
expect(
coAuthors(
"Fix the thing\n\nSome body text.\n\nSigned-off-by: A \nCo-authored-by: Alice Lidell \nCo-authored-by: Bob ",
),
).toEqual([
{ name: "Alice Lidell", email: "alice@lidell.com" },
{ name: "Bob", email: "bob@example.com" },
]);
});
test("is case-insensitive", () => {
expect(
coAuthors("Subject\n\nCO-AUTHORED-BY: Bob "),
).toEqual([{ name: "Bob", email: "bob@example.com" }]);
});
test("ignores a trailer that is not in the last paragraph", () => {
expect(
coAuthors(
"Subject\n\nCo-authored-by: Bob \n\nThat line was quoted, not a trailer.",
),
).toEqual([]);
});
test("keeps the last paragraph rule for CRLF messages", () => {
expect(
coAuthors(
"Subject\r\n\r\nCo-authored-by: Bob \r\n\r\nThat line was quoted, not a trailer.\r\n",
),
).toEqual([]);
});
test("reads a trailer that carries no name", () => {
expect(coAuthors("Subject\n\nCo-authored-by: ")).toEqual([
{ name: "", email: "bob@example.com" },
]);
});
test("ignores malformed lines", () => {
expect(
coAuthors(
"Subject\n\nCo-authored-by: Bob\nCo-authored-by:\nNot-a-trailer: x ",
),
).toEqual([]);
});
test("returns nothing when there are no trailers", () => {
expect(coAuthors("Subject\n\nJust a body.")).toEqual([]);
});
});