Skip to content

Commit 47daf90

Browse files
RealDiligentRealDiligent
andauthored
test(scoring): cover pending-pr-scenarios' ghost-login and case-insensitive matching (#8528)
sameLogin's `value &&` short-circuit exists for PullRequestRecord.authorLogin being string | null | undefined (ghost/deleted GitHub accounts), and both helpers lowercase before comparing because GitHub treats owner/repo and logins case-insensitively while stored values are not guaranteed consistent. Every existing test passed a concrete, same-cased login, so neither behavior was pinned. Adds one case covering all four: null and undefined authorLogin are excluded, and records differing only in repo-name or login case still match. The mock returns a review keyed to the requested pull number, so the assertion reads exactly which records survived the filter. Closes #8329 Co-authored-by: RealDiligent <nft.gold.eth@gmail.com>
1 parent 92737d5 commit 47daf90

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

test/unit/pending-pr-scenarios.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,34 @@ describe("pending PR scenario detection", () => {
448448
).toBe("stale_likely_close");
449449
});
450450

451+
it("#8329: excludes ghost-account PRs and matches repo/login case-insensitively", async () => {
452+
const env = {} as Env;
453+
// Return a review keyed to whichever PR number is asked for, so the resulting reviews reveal exactly
454+
// which records survived sameRepoFullName + sameLogin.
455+
vi.spyOn(repositories, "listPullRequestReviews").mockImplementation(async (_env, _repo, pullNumber: number) => [
456+
approvedReview(pullNumber),
457+
]);
458+
vi.spyOn(repositories, "listCheckSummaries").mockResolvedValue([]);
459+
460+
const records = await loadContributorRepoOpenPrSignalRecords(env, "entrius/allways-ui", "miner-a", [
461+
// sameLogin's `value &&` short-circuit: a ghost/deleted account has no resolvable login and must be
462+
// excluded rather than throwing on .toLowerCase() or matching by accident.
463+
pr({ number: 80, authorLogin: null as unknown as string }),
464+
pr({ number: 81, authorLogin: undefined }),
465+
// Case-insensitive repo match: GitHub treats owner/repo case-insensitively, stored values may differ.
466+
pr({ number: 82, repoFullName: "Entrius/Allways-UI" }),
467+
// Case-insensitive login match.
468+
pr({ number: 83, authorLogin: "Miner-A" }),
469+
]);
470+
471+
const matched = records.pullRequestReviews.map((review) => review.pullNumber).sort((a, b) => a - b);
472+
expect(matched).toEqual([82, 83]);
473+
// Explicitly: neither ghost-account PR slipped through.
474+
expect(matched).not.toContain(80);
475+
expect(matched).not.toContain(81);
476+
vi.restoreAllMocks();
477+
});
478+
451479
it("loads cached reviews and checks for contributor open PRs", async () => {
452480
const env = {} as Env;
453481
vi.spyOn(repositories, "listPullRequestReviews").mockResolvedValue([approvedReview(70)]);

0 commit comments

Comments
 (0)