test: cover PR merge race fallback

This commit is contained in:
Berlin Luk
2026-05-11 11:53:18 +08:00
parent 356e959114
commit 9643341d9d

View File

@@ -576,6 +576,125 @@ describe("processPullRequestMergeTask", () => {
);
});
it("rethrows the original merge error when refresh does not confirm merged", async () => {
const task: MockTask = {
id: "FN-9105",
title: "test",
description: "desc",
column: "in-review",
prInfo: {
number: 125,
url: "https://github.com/x/y/pull/125",
status: "open",
headBranch: "fusion/fn-9105",
baseBranch: "main",
},
};
const store = makeStore(task);
const mergeError = new Error("Pull request is not mergeable");
const openPr = {
number: 125,
url: "https://github.com/x/y/pull/125",
status: "open" as const,
headBranch: "fusion/fn-9105",
baseBranch: "main",
};
const github = {
findPrForBranch: vi.fn(),
createPr: vi.fn(),
getPrMergeStatus: vi
.fn()
.mockResolvedValueOnce({
prInfo: openPr,
reviewDecision: "APPROVED",
checks: [],
mergeReady: true,
blockingReasons: [],
})
.mockResolvedValueOnce({
prInfo: openPr,
reviewDecision: "APPROVED",
checks: [],
mergeReady: true,
blockingReasons: [],
}),
mergePr: vi.fn(async () => {
throw mergeError;
}),
};
await expect(
processPullRequestMergeTask(
store as never,
"/repo",
task.id,
github as never,
() => undefined,
),
).rejects.toThrow(mergeError.message);
expect(github.mergePr).toHaveBeenCalledWith({ number: 125, method: "squash" });
expect(github.getPrMergeStatus).toHaveBeenCalledTimes(2);
expect(store.updatePrInfo).not.toHaveBeenCalledWith("FN-9105", expect.objectContaining({ status: "merged" }));
expect(store.moveTask).not.toHaveBeenCalled();
});
it("rethrows the original merge error when the post-failure refresh also fails", async () => {
const task: MockTask = {
id: "FN-9106",
title: "test",
description: "desc",
column: "in-review",
prInfo: {
number: 126,
url: "https://github.com/x/y/pull/126",
status: "open",
headBranch: "fusion/fn-9106",
baseBranch: "main",
},
};
const store = makeStore(task);
const mergeError = new Error("merge command failed");
const openPr = {
number: 126,
url: "https://github.com/x/y/pull/126",
status: "open" as const,
headBranch: "fusion/fn-9106",
baseBranch: "main",
};
const github = {
findPrForBranch: vi.fn(),
createPr: vi.fn(),
getPrMergeStatus: vi
.fn()
.mockResolvedValueOnce({
prInfo: openPr,
reviewDecision: "APPROVED",
checks: [],
mergeReady: true,
blockingReasons: [],
})
.mockRejectedValueOnce(new Error("status refresh failed")),
mergePr: vi.fn(async () => {
throw mergeError;
}),
};
await expect(
processPullRequestMergeTask(
store as never,
"/repo",
task.id,
github as never,
() => undefined,
),
).rejects.toThrow(mergeError.message);
expect(github.mergePr).toHaveBeenCalledWith({ number: 126, method: "squash" });
expect(github.getPrMergeStatus).toHaveBeenCalledTimes(2);
expect(store.moveTask).not.toHaveBeenCalled();
});
it("preserves PR number/url through create, refresh, and merge completion", async () => {
const task: MockTask = {
id: "FN-9103",