From 27c4221c481092142963de73448dc803f4314884 Mon Sep 17 00:00:00 2001 From: "hivecommons-hive[bot]" Date: Sun, 27 Sep 2026 04:04:21 -0400 Subject: [PATCH] test(cronJobs): cover the labelSync list failure and the sweep non-Error and absent-field branches labelSync: listLabelsForRepo rejecting surfaces as 'could not list the repository labels' and writes nothing. sweep: a step rejecting with a plain string is recorded under its name via String(e); a pull request listed without labels or requested_reviewers is treated as unlabelled with no reviewers, so ok-to-test makes no Actions call and blunderbuss still requests them. Closes #199 Signed-off-by: hivecommons-hive[bot] --- __tests__/cronJobTest/labelSync.test.ts | 15 +++++++++++++ __tests__/cronJobTest/sweep.test.ts | 28 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/__tests__/cronJobTest/labelSync.test.ts b/__tests__/cronJobTest/labelSync.test.ts index 2a3442a3..aeee821c 100644 --- a/__tests__/cronJobTest/labelSync.test.ts +++ b/__tests__/cronJobTest/labelSync.test.ts @@ -241,6 +241,21 @@ describe('label-sync job', () => { expect(lines.some(line => line.includes('would update') && line.includes('lgtm'))).toBe(true) }) + it('fails the run when the repository labels cannot be listed', async () => { + serveConfig() + const writes: Write[] = [] + server.use( + http.get(`${repo}/labels`, () => json({ message: 'boom' }, 500)), + http.post(`${repo}/labels`, async ({ request }) => { + writes.push({ method: 'POST', body: await request.json() }) + return json({}, 201) + }), + ) + + await expect(labelSync(dispatchContext())).rejects.toThrow('could not list the repository labels') + expect(writes).toEqual([]) + }) + it('fails the run when the configuration cannot be loaded', async () => { server.use( http.get(`${repo}/contents/.github%2Fprow.yaml`, utils.mockResponse(500, { message: 'boom' })), diff --git a/__tests__/cronJobTest/sweep.test.ts b/__tests__/cronJobTest/sweep.test.ts index 8def8443..85f9aea4 100644 --- a/__tests__/cronJobTest/sweep.test.ts +++ b/__tests__/cronJobTest/sweep.test.ts @@ -6,6 +6,7 @@ import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it, vi } import { handleCronJobs } from '../../src/cronJobs/handleCronJob' import { sweep, sweepConcurrency } from '../../src/cronJobs/sweep' +import * as requireMatchingLabel from '../../src/plugins/requireMatchingLabel' import { maxSweepLookbackMs, parseProwConfig, resolveSweepLookback } from '../../src/utils/config' import labelFileContents from '../fixtures/labels/labelFileContentsResp.json' import pullReqOpenedEvent from '../fixtures/pullReq/pullReqOpenedEvent.json' @@ -183,6 +184,13 @@ describe('sweep candidates', () => { await expect(tree.notCalled()).resolves.toBe('not called') }) + it('records a step that rejects with a non-Error value as its string form', async () => { + servePulls([{ number: 1 }]) + vi.spyOn(requireMatchingLabel, 'enforceRequiredLabels').mockRejectedValueOnce('plain string failure') + + await expect(sweep(context)).rejects.toThrow('sweep: 1 pull request(s) failed: #1 (require-matching-label: plain string failure)') + }) + it('fails when the list cannot be read', async () => { server.use(http.get(`${repo}/pulls`, () => json({ message: 'boom' }, 500))) @@ -382,6 +390,26 @@ describe('sweep on a repository with OWNERS files', () => { expect(reviewReads.filter((n, i) => reviewReads.indexOf(n) !== i)).toEqual([4]) }) + it('treats a pull request listed without labels or requested_reviewers as unlabelled with no reviewers', async () => { + serveOwners(['sdk/x.go']) + const full = pull({ number: 1, created: ago(60_000), updated: ago(60_000) }) + const { labels: _labels, requested_reviewers: _reviewers, ...bare } = full + const runs = new utils.ObserveRequest() + const reviewers = new utils.ObserveRequest() + server.use( + http.get(`${repo}/pulls`, () => json([bare])), + http.get(`${repo}/pulls/1`, () => json(full)), + http.get(`${repo}/issues/1`, utils.mockResponse(200, { labels: [{ name: 'area/sdk' }] })), + http.get(`${repo}/pulls/1/reviews`, utils.mockResponse(200, [])), + http.get(`${repo}/actions/runs`, utils.mockResponse(200, { total_count: 0, workflow_runs: [] }, runs)), + http.post(`${repo}/pulls/1/requested_reviewers`, utils.mockResponse(201, {}, reviewers)), + ) + + await expect(sweep(context)).resolves.toMatchObject({ candidates: [1], failures: [] }) + await expect(runs.notCalled()).resolves.toBe('not called') + await expect(reviewers.called()).resolves.toBe('called') + }) + it('a bound lgtm and approved on a clean pull request merges', async () => { serveOwners(['sdk/x.go']) servePulls([{ number: 1, created: ago(3 * hour), labels: ['lgtm', 'approved', 'area/sdk'], user: 'alice' }])