mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-10-30 00:31:03 +08:00
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.
83 lines
2.4 KiB
TypeScript
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([]);
|
|
});
|
|
});
|