Skip to content

Commit e7dadca

Browse files
committed
Refactor comment handling logic into performAction for improved testability
1 parent f1419b8 commit e7dadca

2 files changed

Lines changed: 109 additions & 9 deletions

File tree

‎pr-checks/post-comment.test.ts‎

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import { describe, it } from "node:test";
1010
import { type ApiClient } from "./api-client";
1111
import {
1212
findExistingComment,
13+
type Options,
1314
parseOptions,
15+
performAction,
1416
resolveToken,
1517
} from "./post-comment";
1618

@@ -211,3 +213,87 @@ describe("findExistingComment", async () => {
211213
assert.equal(id, undefined);
212214
});
213215
});
216+
217+
/** A baseline set of `Options`, for use in `performAction` tests. */
218+
const baseOptions: Options = {
219+
body: "hello",
220+
marker: "<!-- marker -->",
221+
actionCondition: true,
222+
actionIfTrue: "insert",
223+
actionIfFalse: "delete",
224+
issueId: 42,
225+
repository: { owner: "owner", repo: "repo" },
226+
};
227+
228+
describe("performAction", async () => {
229+
await it("does nothing for 'none'", async () => {
230+
const { client, calls } = fakeClient([]);
231+
await performAction(client, "none", baseOptions);
232+
assert.deepEqual(calls, {
233+
createComment: [],
234+
updateComment: [],
235+
deleteComment: [],
236+
});
237+
});
238+
239+
await it("creates a new comment for 'insert', with the marker prepended", async () => {
240+
const { client, calls } = fakeClient([]);
241+
await performAction(client, "insert", baseOptions);
242+
assert.deepEqual(calls.createComment, [
243+
{
244+
owner: "owner",
245+
repo: "repo",
246+
issue_number: 42,
247+
body: "<!-- marker -->\nhello",
248+
},
249+
]);
250+
assert.deepEqual(calls.updateComment, []);
251+
assert.deepEqual(calls.deleteComment, []);
252+
});
253+
254+
await it("creates a new comment for 'upsert' when no existing comment is found", async () => {
255+
const { client, calls } = fakeClient([{ id: 1, body: "unrelated" }]);
256+
await performAction(client, "upsert", baseOptions);
257+
assert.deepEqual(calls.createComment, [
258+
{
259+
owner: "owner",
260+
repo: "repo",
261+
issue_number: 42,
262+
body: "<!-- marker -->\nhello",
263+
},
264+
]);
265+
assert.deepEqual(calls.updateComment, []);
266+
});
267+
268+
await it("updates the existing comment for 'upsert' when one is found", async () => {
269+
const { client, calls } = fakeClient([
270+
{ id: 7, body: "<!-- marker -->\nold" },
271+
]);
272+
await performAction(client, "upsert", baseOptions);
273+
assert.deepEqual(calls.updateComment, [
274+
{
275+
owner: "owner",
276+
repo: "repo",
277+
comment_id: 7,
278+
body: "<!-- marker -->\nhello",
279+
},
280+
]);
281+
assert.deepEqual(calls.createComment, []);
282+
});
283+
284+
await it("does nothing for 'delete' when no existing comment is found", async () => {
285+
const { client, calls } = fakeClient([{ id: 1, body: "unrelated" }]);
286+
await performAction(client, "delete", baseOptions);
287+
assert.deepEqual(calls.deleteComment, []);
288+
});
289+
290+
await it("deletes the existing comment for 'delete' when one is found", async () => {
291+
const { client, calls } = fakeClient([
292+
{ id: 9, body: "<!-- marker -->\nold" },
293+
]);
294+
await performAction(client, "delete", baseOptions);
295+
assert.deepEqual(calls.deleteComment, [
296+
{ owner: "owner", repo: "repo", comment_id: 9 },
297+
]);
298+
});
299+
});

‎pr-checks/post-comment.ts‎

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -172,16 +172,17 @@ export async function findExistingComment(
172172
return comments.find((comment) => comment.body?.startsWith(marker))?.id;
173173
}
174174

175-
async function main(): Promise<number> {
176-
const options = parseOptions();
177-
const action = options.actionCondition
178-
? options.actionIfTrue
179-
: options.actionIfFalse;
180-
console.info(`Resolved action: ${action}`);
181-
182-
const token = resolveToken(process.env);
175+
/**
176+
* Performs the resolved `action` against a (possibly pre-existing) marked comment, using
177+
* `client` to talk to the GitHub API. This is the core dispatch logic of this script, extracted
178+
* from `main` so it can be unit-tested with an injected (fake) `client`.
179+
*/
180+
export async function performAction(
181+
client: ApiClient,
182+
action: Action,
183+
options: Options,
184+
): Promise<void> {
183185
const { issueId, marker, repository } = options;
184-
const client = getApiClient(token);
185186
const body = `${marker}\n${options.body}`;
186187

187188
let existingCommentId: number | undefined;
@@ -235,6 +236,19 @@ async function main(): Promise<number> {
235236
}
236237
break;
237238
}
239+
}
240+
241+
async function main(): Promise<number> {
242+
const options = parseOptions();
243+
const action = options.actionCondition
244+
? options.actionIfTrue
245+
: options.actionIfFalse;
246+
console.info(`Resolved action: ${action}`);
247+
248+
const token = resolveToken(process.env);
249+
const client = getApiClient(token);
250+
251+
await performAction(client, action, options);
238252

239253
return 0;
240254
}

0 commit comments

Comments
 (0)