From a80803359d8c125f70676311260ff350c3f8b363 Mon Sep 17 00:00:00 2001 From: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com> Date: Sun, 1 Nov 2026 07:18:43 -0500 Subject: [PATCH] test(app): pin that a PROW_JOBS value with a trailing newline runs its jobs and fails no repository The App passes PROW_JOBS through settingsFromEnv untrimmed, and a Helm block scalar ends in a newline, so handleCronJobs sees an empty token after the split. Nothing asserted that the filter dropping it is what keeps the 'please provide a list of ... jobs' arm from failing every repository: the Actions-side cases go through core.getInput, which trims first. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: quality <280983584+hivecommons-hive[bot]@users.noreply.github.com> --- __tests__/adapters/app/cron.test.ts | 37 +++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/__tests__/adapters/app/cron.test.ts b/__tests__/adapters/app/cron.test.ts index 4ced6bbb..5400cdbe 100644 --- a/__tests__/adapters/app/cron.test.ts +++ b/__tests__/adapters/app/cron.test.ts @@ -8,6 +8,7 @@ import { afterAll, afterEach, beforeAll, describe, expect, it, vi } from 'vitest import { appInstallationLister, runScheduledJobs } from '../../../src/adapters/app/cron' import { appTokenSource } from '../../../src/adapters/app/platform' import { asyncLocalScope } from '../../../src/adapters/app/scope' +import { handleCronJobs } from '../../../src/cronJobs/handleCronJob' import { globalPlatformScope, installPlatformScope, platform } from '../../../src/platform' import * as utils from '../../testUtils' import { recordingSink, settings, staticTokens } from './testApp' @@ -141,6 +142,42 @@ describe('runScheduledJobs', () => { }) }) +describe('runScheduledJobs dispatching handleCronJobs', () => { + const server = setupServer() + utils.failTestOnUnhandledRequests(server) + beforeAll(() => { + installPlatformScope(asyncLocalScope()) + server.listen(utils.failOnUnhandledRequest) + }) + afterEach(() => server.resetHandlers()) + afterAll(() => { + server.close() + installPlatformScope(globalPlatformScope) + }) + + // the App hands PROW_JOBS over as the environment carries it (settingsFromEnv does not trim, unlike + // core.getInput on Actions), and a ConfigMap block scalar ends in a newline; the empty token that + // splitting such a value leaves behind must not reach the "no jobs" arm and fail every repository + it('runs the jobs named by a PROW_JOBS value carrying a trailing newline, failing no repository', async () => { + const { lines, sink } = recordingSink() + server.use( + ...utils.noOrgOrRepoConfigExcept(), + http.get(`${utils.api}/repos/Codertocat/Hello-World/pulls`, utils.mockResponse(200, [])), + ) + + const report = await runScheduledJobs({ + settings: { ...settings, inputs: { jobs: 'lgtm\n' } }, + tokens: staticTokens(), + installations: listing({ installationId: 7, repository: repo('Codertocat', 'Hello-World') }), + sink, + dispatch: context => handleCronJobs(context), + }) + + expect(report).toEqual({ repositories: 1, failed: [] }) + expect(lines.filter(line => line.level === 'error')).toEqual([]) + }) +}) + describe('appInstallationLister', () => { const server = setupServer() utils.failTestOnUnhandledRequests(server)