Skip to content

Commit a5b6a29

Browse files
committed
Adds additional tests
1 parent c4fbd5b commit a5b6a29

2 files changed

Lines changed: 186 additions & 0 deletions

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { describe, it, expect, vi } from "vitest";
2+
3+
// Mock generateIssueBody so we can inspect what screenshotRepo is passed
4+
vi.mock("../src/generateIssueBody.js", () => ({
5+
generateIssueBody: vi.fn(
6+
(_finding, screenshotRepo: string) =>
7+
`body with screenshotRepo=${screenshotRepo}`,
8+
),
9+
}));
10+
11+
import { openIssue } from "../src/openIssue.ts";
12+
import { generateIssueBody } from "../src/generateIssueBody.ts";
13+
14+
const baseFinding = {
15+
scannerType: "axe",
16+
ruleId: "color-contrast",
17+
url: "https://example.com/page",
18+
html: "<span>Low contrast</span>",
19+
problemShort: "elements must meet minimum color contrast ratio thresholds",
20+
problemUrl:
21+
"https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=playwright",
22+
solutionShort:
23+
"ensure the contrast between foreground and background colors meets WCAG thresholds",
24+
};
25+
26+
function mockOctokit() {
27+
return {
28+
request: vi.fn().mockResolvedValue({ data: { id: 1, html_url: "https://github.com/org/repo/issues/1" } }),
29+
} as any;
30+
}
31+
32+
describe("openIssue", () => {
33+
it("passes screenshotRepo to generateIssueBody when provided", async () => {
34+
const octokit = mockOctokit();
35+
await openIssue(octokit, "org/filing-repo", baseFinding, "org/workflow-repo");
36+
37+
expect(generateIssueBody).toHaveBeenCalledWith(baseFinding, "org/workflow-repo");
38+
});
39+
40+
it("falls back to repoWithOwner when screenshotRepo is not provided", async () => {
41+
const octokit = mockOctokit();
42+
await openIssue(octokit, "org/filing-repo", baseFinding);
43+
44+
expect(generateIssueBody).toHaveBeenCalledWith(baseFinding, "org/filing-repo");
45+
});
46+
47+
it("posts to the correct filing repo, not the screenshot repo", async () => {
48+
const octokit = mockOctokit();
49+
await openIssue(octokit, "org/filing-repo", baseFinding, "org/workflow-repo");
50+
51+
expect(octokit.request).toHaveBeenCalledWith(
52+
"POST /repos/org/filing-repo/issues",
53+
expect.objectContaining({
54+
owner: "org",
55+
repo: "filing-repo",
56+
}),
57+
);
58+
});
59+
60+
it("includes the correct labels based on the finding", async () => {
61+
const octokit = mockOctokit();
62+
await openIssue(octokit, "org/repo", baseFinding);
63+
64+
expect(octokit.request).toHaveBeenCalledWith(
65+
expect.any(String),
66+
expect.objectContaining({
67+
labels: ["axe rule: color-contrast", "axe-scanning-issue"],
68+
}),
69+
);
70+
});
71+
72+
it("truncates long titles with ellipsis", async () => {
73+
const octokit = mockOctokit();
74+
const longFinding = {
75+
...baseFinding,
76+
problemShort: "a".repeat(300),
77+
};
78+
await openIssue(octokit, "org/repo", longFinding);
79+
80+
const callArgs = octokit.request.mock.calls[0][1];
81+
expect(callArgs.title.length).toBeLessThanOrEqual(256);
82+
expect(callArgs.title).toMatch(/$/);
83+
});
84+
});
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { describe, it, expect, vi, beforeEach } from "vitest";
2+
3+
// Mock generateIssueBody so we can inspect what screenshotRepo is passed
4+
vi.mock("../src/generateIssueBody.js", () => ({
5+
generateIssueBody: vi.fn(
6+
(_finding, screenshotRepo: string) =>
7+
`body with screenshotRepo=${screenshotRepo}`,
8+
),
9+
}));
10+
11+
import { reopenIssue } from "../src/reopenIssue.ts";
12+
import { generateIssueBody } from "../src/generateIssueBody.ts";
13+
import { Issue } from "../src/Issue.ts";
14+
15+
const baseFinding = {
16+
scannerType: "axe",
17+
ruleId: "color-contrast",
18+
url: "https://example.com/page",
19+
html: "<span>Low contrast</span>",
20+
problemShort: "elements must meet minimum color contrast ratio thresholds",
21+
problemUrl:
22+
"https://dequeuniversity.com/rules/axe/4.10/color-contrast?application=playwright",
23+
solutionShort:
24+
"ensure the contrast between foreground and background colors meets WCAG thresholds",
25+
};
26+
27+
const testIssue = new Issue({
28+
id: 42,
29+
nodeId: "MDU6SXNzdWU0Mg==",
30+
url: "https://github.com/org/filing-repo/issues/7",
31+
title: "Accessibility issue: test",
32+
state: "closed",
33+
});
34+
35+
function mockOctokit() {
36+
return {
37+
request: vi.fn().mockResolvedValue({ data: { id: 42, html_url: "https://github.com/org/filing-repo/issues/7" } }),
38+
} as any;
39+
}
40+
41+
describe("reopenIssue", () => {
42+
beforeEach(() => {
43+
vi.clearAllMocks();
44+
});
45+
46+
it("passes screenshotRepo to generateIssueBody when provided", async () => {
47+
const octokit = mockOctokit();
48+
await reopenIssue(octokit, testIssue, baseFinding, "org/filing-repo", "org/workflow-repo");
49+
50+
expect(generateIssueBody).toHaveBeenCalledWith(baseFinding, "org/workflow-repo");
51+
});
52+
53+
it("falls back to repoWithOwner when screenshotRepo is not provided", async () => {
54+
const octokit = mockOctokit();
55+
await reopenIssue(octokit, testIssue, baseFinding, "org/filing-repo");
56+
57+
expect(generateIssueBody).toHaveBeenCalledWith(baseFinding, "org/filing-repo");
58+
});
59+
60+
it("does not generate a body when finding is not provided", async () => {
61+
const octokit = mockOctokit();
62+
await reopenIssue(octokit, testIssue);
63+
64+
expect(generateIssueBody).not.toHaveBeenCalled();
65+
expect(octokit.request).toHaveBeenCalledWith(
66+
expect.any(String),
67+
expect.not.objectContaining({ body: expect.anything() }),
68+
);
69+
});
70+
71+
it("does not generate a body when repoWithOwner is not provided", async () => {
72+
const octokit = mockOctokit();
73+
await reopenIssue(octokit, testIssue, baseFinding);
74+
75+
expect(generateIssueBody).not.toHaveBeenCalled();
76+
});
77+
78+
it("sends PATCH to the correct issue URL with state open", async () => {
79+
const octokit = mockOctokit();
80+
await reopenIssue(octokit, testIssue, baseFinding, "org/filing-repo", "org/workflow-repo");
81+
82+
expect(octokit.request).toHaveBeenCalledWith(
83+
"PATCH /repos/org/filing-repo/issues/7",
84+
expect.objectContaining({
85+
state: "open",
86+
issue_number: 7,
87+
}),
88+
);
89+
});
90+
91+
it("includes generated body when finding and repoWithOwner are provided", async () => {
92+
const octokit = mockOctokit();
93+
await reopenIssue(octokit, testIssue, baseFinding, "org/filing-repo", "org/workflow-repo");
94+
95+
expect(octokit.request).toHaveBeenCalledWith(
96+
expect.any(String),
97+
expect.objectContaining({
98+
body: "body with screenshotRepo=org/workflow-repo",
99+
}),
100+
);
101+
});
102+
});

0 commit comments

Comments
 (0)