Skip to content

Commit f97f018

Browse files
snomiaoampcode-com
andcommitted
test(gh-design): add filterReviewers unit tests
Extract reviewer filtering into a testable pure function and add tests covering: self-authored PRs, already-requested reviewers, empty reviewer lists, and undefined alreadyRequested. Amp-Thread-ID: https://ampcode.com/threads/T-019ddde1-db08-71ca-809d-fd7e51b68842 Co-authored-by: Amp <amp@ampcode.com>
1 parent d5a2921 commit f97f018

2 files changed

Lines changed: 59 additions & 3 deletions

File tree

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { describe, expect, it } from "bun:test";
2+
import { filterReviewers } from "./gh-design";
3+
4+
describe("filterReviewers", () => {
5+
const REVIEWERS = ["PabloWiedemann", "AliceDev"];
6+
7+
it("excludes the PR author from both lists", () => {
8+
const result = filterReviewers(REVIEWERS, "PabloWiedemann");
9+
expect(result.requestReviewers).toEqual(["AliceDev"]);
10+
expect(result.newReviewers).toEqual(["AliceDev"]);
11+
});
12+
13+
it("returns all reviewers when author is not in the list", () => {
14+
const result = filterReviewers(REVIEWERS, "SomeoneElse");
15+
expect(result.requestReviewers).toEqual(["PabloWiedemann", "AliceDev"]);
16+
expect(result.newReviewers).toEqual(["PabloWiedemann", "AliceDev"]);
17+
});
18+
19+
it("excludes already-requested reviewers from newReviewers only", () => {
20+
const result = filterReviewers(REVIEWERS, "SomeoneElse", ["PabloWiedemann"]);
21+
expect(result.requestReviewers).toEqual(["PabloWiedemann", "AliceDev"]);
22+
expect(result.newReviewers).toEqual(["AliceDev"]);
23+
});
24+
25+
it("returns empty newReviewers when all are already requested", () => {
26+
const result = filterReviewers(REVIEWERS, "SomeoneElse", ["PabloWiedemann", "AliceDev"]);
27+
expect(result.requestReviewers).toEqual(["PabloWiedemann", "AliceDev"]);
28+
expect(result.newReviewers).toEqual([]);
29+
});
30+
31+
it("returns empty lists when author is the only reviewer", () => {
32+
const result = filterReviewers(["PabloWiedemann"], "PabloWiedemann");
33+
expect(result.requestReviewers).toEqual([]);
34+
expect(result.newReviewers).toEqual([]);
35+
});
36+
37+
it("handles undefined alreadyRequested as no-one requested yet", () => {
38+
const result = filterReviewers(REVIEWERS, "SomeoneElse", undefined);
39+
expect(result.newReviewers).toEqual(["PabloWiedemann", "AliceDev"]);
40+
});
41+
});

app/tasks/gh-design/gh-design.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,20 @@ type GithubDesignTask = {
9595
lastDoneAt?: Date | null; // last time this item was processed successfuly
9696
};
9797

98+
/**
99+
* Filter the reviewer list for a PR: excludes the PR author and
100+
* anyone who has already been requested.
101+
*/
102+
export function filterReviewers(
103+
allReviewers: string[],
104+
prAuthor: string,
105+
alreadyRequested?: string[],
106+
): { requestReviewers: string[]; newReviewers: string[] } {
107+
const requestReviewers = allReviewers.filter((e) => e !== prAuthor);
108+
const newReviewers = requestReviewers.filter((e) => !alreadyRequested?.includes(e));
109+
return { requestReviewers, newReviewers };
110+
}
111+
98112
// task states
99113
const COLLECTION_NAME = "GithubDesignTask";
100114
export const GithubDesignTaskMeta = TaskMetaCollection(COLLECTION_NAME, githubDesignTaskMetaSchema);
@@ -258,9 +272,10 @@ export async function runGithubDesignTask() {
258272
task.type === "pull_request" &&
259273
REQUEST_REVIEWERS.some((e) => !task.reviewers?.includes(e))
260274
) {
261-
const requestReviewers = REQUEST_REVIEWERS.filter((e) => e !== task.user);
262-
const newReviewers = requestReviewers.filter(
263-
(e) => !task.reviewers?.includes(e),
275+
const { requestReviewers, newReviewers } = filterReviewers(
276+
REQUEST_REVIEWERS,
277+
task.user,
278+
task.reviewers,
264279
);
265280
tlog(`Requesting reviewers: ${newReviewers.join(", ") || "(none)"}`);
266281
if (!dryRun) {

0 commit comments

Comments
 (0)