Files
radicle-explorer/tests/unit/utils.test.ts
T
Rūdolfs Ošiņš 982a568538 Polish author and committer popover
Show the email alongside each name. Co-authors are read from the commit
message trailers and listed as their own section. The trigger avatars
now stack and fan apart on hover, and cover everyone credited on the
commit rather than just the author and committer. Timestamps now show
both committed and authored times in the tooltip.
2026-09-09 10:49:50 +02:00

83 lines
2.4 KiB
TypeScript

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/<script>", "http://example.com/%3Cscript%3E"],
])("accepts %p", (input, expected) => {
expect(safeHttpUrl(input)).toBe(expected);
});
test.each([
"javascript:alert(1)",
"\tjavascript:alert(1)",
"data:text/html,<script>alert(1)</script>",
"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 <a@x>\nCo-authored-by: Alice Lidell <alice@lidell.com>\nCo-authored-by: Bob <bob@example.com>",
),
).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 <bob@example.com>"),
).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 <bob@example.com>\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 <bob@example.com>\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: <bob@example.com>")).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 <y@z>",
),
).toEqual([]);
});
test("returns nothing when there are no trailers", () => {
expect(coAuthors("Subject\n\nJust a body.")).toEqual([]);
});
});