From 4869e00a00c5f05da65aff0c724144f2bf800ba1 Mon Sep 17 00:00:00 2001 From: shin-core <153108882+shin-core@users.noreply.github.com> Date: Sat, 25 Jul 2026 00:57:46 +0900 Subject: [PATCH] test(scoring): cover loadContributorRepoOpenPrSignalRecords's login/repo match branches loadContributorRepoOpenPrSignalRecords filters open PRs by sameLogin (which short-circuits a null/undefined authorLogin via Boolean(value && ...)) and sameRepoFullName (case-insensitive), but neither branch was directly covered. Add two tests extending the existing loader test: (1) PRs with authorLogin null and undefined are excluded (not matched or thrown on), asserting only the target login's PR is loaded; (2) a repoFullName differing from the query only in letter case still matches. No source change -- coverage for existing, correct logic. --- test/unit/pending-pr-scenarios.test.ts | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/unit/pending-pr-scenarios.test.ts b/test/unit/pending-pr-scenarios.test.ts index 7c0f16da0b..802c93cc89 100644 --- a/test/unit/pending-pr-scenarios.test.ts +++ b/test/unit/pending-pr-scenarios.test.ts @@ -461,4 +461,36 @@ describe("pending PR scenario detection", () => { expect(records.pullRequestChecks).toHaveLength(0); vi.restoreAllMocks(); }); + + it("excludes PRs whose authorLogin is null or undefined via sameLogin's short-circuit (#8329)", async () => { + const env = {} as Env; + // Only the target login's own open PR (#70) should be loaded; the null/undefined-author rows must be + // excluded by sameLogin (`Boolean(value && ...)`), not matched or thrown on. + const reviewsSpy = vi.spyOn(repositories, "listPullRequestReviews").mockResolvedValue([approvedReview(70)]); + vi.spyOn(repositories, "listCheckSummaries").mockResolvedValue([]); + const records = await loadContributorRepoOpenPrSignalRecords(env, "entrius/allways-ui", "miner-a", [ + pr({ number: 70 }), + pr({ number: 73, authorLogin: null }), + pr({ number: 74, authorLogin: undefined }), + ]); + // Reviews/checks are fetched per matched PR only, so exactly one PR (the target login's) was matched. + expect(records.pullRequestReviews).toHaveLength(1); + expect(reviewsSpy).toHaveBeenCalledTimes(1); + expect(reviewsSpy).toHaveBeenCalledWith(env, "entrius/allways-ui", 70); + vi.restoreAllMocks(); + }); + + it("matches a repoFullName that differs from the query only in letter case (#8329)", async () => { + const env = {} as Env; + // The PR record's repoFullName differs in case from the query argument; sameRepoFullName lowercases both, + // so the PR is still matched and its cached reviews loaded. + const reviewsSpy = vi.spyOn(repositories, "listPullRequestReviews").mockResolvedValue([approvedReview(70)]); + vi.spyOn(repositories, "listCheckSummaries").mockResolvedValue([]); + const records = await loadContributorRepoOpenPrSignalRecords(env, "entrius/allways-ui", "miner-a", [ + pr({ number: 70, repoFullName: "Entrius/Allways-UI" }), + ]); + expect(records.pullRequestReviews).toHaveLength(1); + expect(reviewsSpy).toHaveBeenCalledWith(env, "Entrius/Allways-UI", 70); + vi.restoreAllMocks(); + }); });