CodeIssuesDiscussionsWikiPull RequestsProjectsCommitsActionsReleasesContributorsPulse● GatesSecuritySettingsDeploymentsPipelineInsightsAgents✨ Explain✨ Ask AI✨ Workspace✨ Spec✨ Tests▓ Debt Map✨ NL Search🏛 Archaeology
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | /**
* Tests for src/lib/pr-workflow-sync.ts — the fix for `on: pull_request`
* workflow triggers being silently dead. Before this, `enqueueRun()` was
* never called with `event: "pull_request"` anywhere in the codebase, so a
* workflow declaring `on: pull_request` was parsed, stored in the
* `workflows` table (by push-workflow-sync.ts), and never actually run.
*
* Both the workflow lookup and enqueueRun are passed in via the injectable
* `deps` param (same DI rationale as codeowners.test.ts's
* requiredOwnersApproved tests) — no mock.module() on ../db or
* ../lib/workflow-runner, both of which are imported by dozens of unrelated
* test files and would leak a global mock across the whole `bun test` run.
*/
import { beforeEach, describe, expect, it } from "bun:test";
import { enqueuePullRequestWorkflows } from "../lib/pr-workflow-sync";
let _workflowRows: Array<{ id: string; onEvents: string }> = [];
let _selectShouldThrow = false;
let _enqueueCalls: any[] = [];
let _enqueueShouldThrow = false;
const fakeDeps = {
loadWorkflows: async (_repositoryId: string) => {
if (_selectShouldThrow) throw new Error("db boom");
return _workflowRows;
},
enqueueRun: async (opts: any) => {
if (_enqueueShouldThrow) throw new Error("enqueue boom");
_enqueueCalls.push(opts);
return "run-id-1";
},
} as any;
beforeEach(() => {
_workflowRows = [];
_selectShouldThrow = false;
_enqueueCalls = [];
_enqueueShouldThrow = false;
});
function baseOpts(overrides: Partial<Parameters<typeof enqueuePullRequestWorkflows>[0]> = {}) {
return {
repositoryId: "repo-1",
headBranch: "feature/foo",
headSha: "b".repeat(40),
triggeredBy: "user-1",
...overrides,
};
}
describe("enqueuePullRequestWorkflows", () => {
it("returns zero enqueued when the repo has no workflows", async () => {
_workflowRows = [];
const result = await enqueuePullRequestWorkflows(baseOpts(), fakeDeps);
expect(result).toEqual({ enqueued: 0, errors: [] });
expect(_enqueueCalls).toHaveLength(0);
});
it("enqueues a workflow whose on: includes pull_request", async () => {
_workflowRows = [{ id: "wf-1", onEvents: JSON.stringify(["pull_request"]) }];
const result = await enqueuePullRequestWorkflows(baseOpts(), fakeDeps);
expect(result.enqueued).toBe(1);
expect(result.errors).toEqual([]);
expect(_enqueueCalls[0]).toMatchObject({
workflowId: "wf-1",
repositoryId: "repo-1",
event: "pull_request",
ref: "feature/foo",
commitSha: "b".repeat(40),
triggeredBy: "user-1",
});
});
it("does NOT enqueue a workflow with only an on:push trigger", async () => {
_workflowRows = [{ id: "wf-2", onEvents: JSON.stringify(["push"]) }];
const result = await enqueuePullRequestWorkflows(baseOpts(), fakeDeps);
expect(result.enqueued).toBe(0);
expect(_enqueueCalls).toHaveLength(0);
});
it("enqueues only the matching workflow out of several", async () => {
_workflowRows = [
{ id: "wf-push", onEvents: JSON.stringify(["push"]) },
{ id: "wf-pr", onEvents: JSON.stringify(["push", "pull_request"]) },
{ id: "wf-dispatch", onEvents: JSON.stringify(["workflow_dispatch"]) },
];
const result = await enqueuePullRequestWorkflows(baseOpts(), fakeDeps);
expect(result.enqueued).toBe(1);
expect(_enqueueCalls[0].workflowId).toBe("wf-pr");
});
it("records a per-row error but keeps going when onEvents is malformed JSON", async () => {
_workflowRows = [
{ id: "wf-broken", onEvents: "not json" },
{ id: "wf-good", onEvents: JSON.stringify(["pull_request"]) },
];
const result = await enqueuePullRequestWorkflows(baseOpts(), fakeDeps);
expect(result.enqueued).toBe(1);
expect(_enqueueCalls[0].workflowId).toBe("wf-good");
expect(result.errors.some((e) => e.includes("wf-broken"))).toBe(true);
});
it("records an error but does not throw when enqueueRun fails", async () => {
_workflowRows = [{ id: "wf-1", onEvents: JSON.stringify(["pull_request"]) }];
_enqueueShouldThrow = true;
const result = await enqueuePullRequestWorkflows(baseOpts(), fakeDeps);
expect(result.enqueued).toBe(0);
expect(result.errors.length).toBe(1);
expect(result.errors[0]).toContain("enqueue");
});
it("returns a query error but does not throw when the DB select fails", async () => {
_selectShouldThrow = true;
const result = await enqueuePullRequestWorkflows(baseOpts(), fakeDeps);
expect(result.enqueued).toBe(0);
expect(result.errors.length).toBe(1);
expect(result.errors[0]).toContain("query");
});
});
|