Skip to content

Commit 9f7878b

Browse files
authored
added test suite to formatter and config.ts file (#51)
1 parent 11a22fb commit 9f7878b

1 file changed

Lines changed: 151 additions & 6 deletions

File tree

src/github/formatters.test.ts

Lines changed: 151 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,157 @@
11
import { describe, expect, it } from "vitest";
2-
import { link } from "./formatters.js";
2+
import {
3+
formatDeploymentStatusEvent,
4+
formatIssueEvent,
5+
formatMergeConflictEvent,
6+
formatPullRequestEvent,
7+
formatWorkflowRunEvent,
8+
} from "./formatters.js";
39

4-
describe("link", () => {
5-
it("escapes URLs to prevent attribute breakout", () => {
6-
const maliciousUrl = 'https://example.com/test" onclick="alert(1)';
10+
type IssueEvent = Parameters<typeof formatIssueEvent>[0];
11+
type PullRequestEvent = Parameters<typeof formatPullRequestEvent>[0];
12+
type WorkflowRunEvent = Parameters<typeof formatWorkflowRunEvent>[0];
13+
type DeploymentStatusEvent = Parameters<typeof formatDeploymentStatusEvent>[0];
714

8-
expect(link(maliciousUrl, "Click Here")).toBe(
9-
'<a href="https://example.com/test&quot; onclick=&quot;alert(1)">Click Here</a>',
15+
const repository = {
16+
html_url: "https://github.com/txio/repo",
17+
full_name: "txio/repo",
18+
};
19+
20+
function issueEvent(action: "opened" | "closed" | "reopened"): IssueEvent {
21+
return {
22+
payload: {
23+
action,
24+
repository,
25+
issue: {
26+
html_url: "https://github.com/txio/repo/issues/7",
27+
number: 7,
28+
title: "Fix <alerts>",
29+
user: { login: "octo&cat" },
30+
},
31+
},
32+
} as IssueEvent;
33+
}
34+
35+
function pullRequestEvent(
36+
action: "opened" | "closed" | "reopened",
37+
merged = false,
38+
): PullRequestEvent {
39+
return {
40+
payload: {
41+
action,
42+
repository,
43+
pull_request: {
44+
html_url: "https://github.com/txio/repo/pull/8",
45+
number: 8,
46+
title: "Ship <feature>",
47+
merged,
48+
user: { login: "octo&cat" },
49+
},
50+
},
51+
} as PullRequestEvent;
52+
}
53+
54+
function workflowRunEvent(status: string, conclusion: string | null): WorkflowRunEvent {
55+
return {
56+
payload: {
57+
repository,
58+
workflow_run: {
59+
status,
60+
conclusion,
61+
html_url: "https://github.com/txio/repo/actions/runs/9",
62+
name: "Checks <all>",
63+
head_branch: "feature/a&b",
64+
},
65+
},
66+
} as WorkflowRunEvent;
67+
}
68+
69+
function deploymentStatusEvent(state: string, logUrl = ""): DeploymentStatusEvent {
70+
return {
71+
payload: {
72+
repository,
73+
deployment: { environment: "preview <west>" },
74+
deployment_status: { state, log_url: logUrl },
75+
},
76+
} as DeploymentStatusEvent;
77+
}
78+
79+
describe("formatIssueEvent", () => {
80+
it.each([
81+
["opened", "🆕"],
82+
["closed", "✅"],
83+
["reopened", "🔁"],
84+
] as const)("formats an %s issue", (action, icon) => {
85+
expect(formatIssueEvent(issueEvent(action))).toBe(
86+
`${icon} Issue ${action} in <a href="https://github.com/txio/repo">txio/repo</a>\n` +
87+
`<a href="https://github.com/txio/repo/issues/7">#7 Fix &lt;alerts&gt;</a>\n` +
88+
"by octo&amp;cat",
89+
);
90+
});
91+
});
92+
93+
describe("formatPullRequestEvent", () => {
94+
it.each([
95+
["opened", false, "🆕", "opened"],
96+
["reopened", false, "🔁", "reopened"],
97+
["closed", false, "❌", "closed"],
98+
["closed", true, "🎉", "merged"],
99+
] as const)("formats a %s pull request (merged: %s)", (action, merged, icon, label) => {
100+
expect(formatPullRequestEvent(pullRequestEvent(action, merged))).toBe(
101+
`${icon} Pull request ${label} in <a href="https://github.com/txio/repo">txio/repo</a>\n` +
102+
`<a href="https://github.com/txio/repo/pull/8">#8 Ship &lt;feature&gt;</a>\n` +
103+
"by octo&amp;cat",
104+
);
105+
});
106+
});
107+
108+
describe("formatMergeConflictEvent", () => {
109+
it("formats a merge conflict", () => {
110+
expect(
111+
formatMergeConflictEvent(
112+
{ html_url: "https://github.com/txio/repo/pull/8", number: 8, title: "Ship <feature>" },
113+
repository,
114+
),
115+
).toBe(
116+
`⚠️ Merge conflict on <a href="https://github.com/txio/repo">txio/repo</a>\n` +
117+
`<a href="https://github.com/txio/repo/pull/8">#8 Ship &lt;feature&gt;</a> can't be merged — needs to be updated with the base branch.`,
118+
);
119+
});
120+
});
121+
122+
describe("formatWorkflowRunEvent", () => {
123+
it.each([
124+
["success", "✅"],
125+
["failure", "❌"],
126+
["cancelled", "⚪"],
127+
] as const)("formats a completed %s run", (conclusion, icon) => {
128+
expect(formatWorkflowRunEvent(workflowRunEvent("completed", conclusion))).toBe(
129+
`${icon} CI ${conclusion} for <a href="https://github.com/txio/repo">txio/repo</a>\n` +
130+
`<a href="https://github.com/txio/repo/actions/runs/9">Checks &lt;all&gt;</a> on feature/a&amp;b`,
131+
);
132+
});
133+
134+
it("returns null for a non-completed run", () => {
135+
expect(formatWorkflowRunEvent(workflowRunEvent("in_progress", null))).toBeNull();
136+
});
137+
});
138+
139+
describe("formatDeploymentStatusEvent", () => {
140+
it.each([
141+
["success", "🚀"],
142+
["failure", "❌"],
143+
["error", "❌"],
144+
["pending", "⏳"],
145+
] as const)("formats a %s deployment", (state, icon) => {
146+
expect(formatDeploymentStatusEvent(deploymentStatusEvent(state, "https://deploy.test/log"))).toBe(
147+
`${icon} Deploy ${state} — preview &lt;west&gt; (<a href="https://github.com/txio/repo">txio/repo</a>)\n` +
148+
`<a href="https://deploy.test/log">logs</a>`,
149+
);
150+
});
151+
152+
it("omits the logs link when no log URL is provided", () => {
153+
expect(formatDeploymentStatusEvent(deploymentStatusEvent("pending"))).toBe(
154+
`⏳ Deploy pending — preview &lt;west&gt; (<a href="https://github.com/txio/repo">txio/repo</a>)\n`,
10155
);
11156
});
12157
});

0 commit comments

Comments
 (0)