test(FN-4434): complete Step 3 — cover recovery audit emission
Fusion-Task-Id: FN-4434 Fusion-Task-Lineage: 547a5663-114c-49c8-bd0c-dddfb280c4ef
This commit is contained in:
@@ -75,6 +75,7 @@ function createStore(tasks: TaskMap, settings: Partial<Settings> = {}): TaskStor
|
||||
updateSettings: vi.fn(async () => mergedSettings),
|
||||
mergeTask: vi.fn(async () => undefined),
|
||||
getRootDir: vi.fn(() => ""),
|
||||
recordRunAuditEvent: vi.fn(async () => undefined),
|
||||
}) as unknown as TaskStore & EventEmitter;
|
||||
|
||||
return store;
|
||||
@@ -126,6 +127,14 @@ describeIfGit("SelfHealingManager recoverAlreadyMergedReviewTasks (real git)", (
|
||||
expect(task.mergeDetails?.mergeConfirmed).toBe(true);
|
||||
expect(existsSync(worktreePath)).toBe(false);
|
||||
expect(git(repo, "git worktree list")).not.toContain(worktreePath);
|
||||
expect((store as any).recordRunAuditEvent).toHaveBeenCalledTimes(1);
|
||||
expect((store as any).recordRunAuditEvent).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
domain: "database",
|
||||
mutationType: "task:auto-recover-already-merged",
|
||||
target: "FN-TEST-1",
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it(
|
||||
|
||||
@@ -3719,6 +3719,115 @@ describe("SelfHealingManager", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("recoverAlreadyMergedReviewTasks — run-audit emission", () => {
|
||||
it("emits task:auto-recover-already-merged when recovery succeeds", async () => {
|
||||
const recordRunAuditEvent = vi.fn().mockResolvedValue(undefined);
|
||||
const storeWithAudit = createMockStore({
|
||||
getSettings: vi.fn().mockResolvedValue({ globalPause: false, enginePaused: false }),
|
||||
listTasks: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "FN-audit",
|
||||
column: "in-review",
|
||||
paused: false,
|
||||
status: "failed",
|
||||
mergeRetries: 4,
|
||||
mergeDetails: undefined,
|
||||
baseBranch: "main",
|
||||
branch: "fusion/fn-audit",
|
||||
steps: [],
|
||||
log: [],
|
||||
},
|
||||
]),
|
||||
recordRunAuditEvent,
|
||||
});
|
||||
const managerWithRecovery = new SelfHealingManager(storeWithAudit, { rootDir: "/tmp/test-project" });
|
||||
vi.spyOn(managerWithRecovery as any, "findAlreadyMergedTaskCommit").mockResolvedValue({ sha: "abc1234def5678", strategy: "trailer" });
|
||||
|
||||
const recovered = await managerWithRecovery.recoverAlreadyMergedReviewTasks();
|
||||
|
||||
expect(recovered).toBe(1);
|
||||
expect(recordRunAuditEvent).toHaveBeenCalledTimes(1);
|
||||
expect(recordRunAuditEvent).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
domain: "database",
|
||||
mutationType: "task:auto-recover-already-merged",
|
||||
target: "FN-audit",
|
||||
metadata: expect.objectContaining({
|
||||
mergeSha: "abc1234def5678",
|
||||
mergeStrategy: "trailer",
|
||||
baseBranch: "main",
|
||||
mergeRetries: 4,
|
||||
}),
|
||||
}),
|
||||
);
|
||||
|
||||
managerWithRecovery.stop();
|
||||
});
|
||||
|
||||
it("does not emit when no landed commit is detected", async () => {
|
||||
const recordRunAuditEvent = vi.fn().mockResolvedValue(undefined);
|
||||
const storeWithAudit = createMockStore({
|
||||
getSettings: vi.fn().mockResolvedValue({ globalPause: false, enginePaused: false }),
|
||||
listTasks: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "FN-no-hit",
|
||||
column: "in-review",
|
||||
paused: false,
|
||||
status: "failed",
|
||||
mergeRetries: 3,
|
||||
mergeDetails: undefined,
|
||||
baseBranch: "main",
|
||||
branch: "fusion/fn-no-hit",
|
||||
steps: [],
|
||||
log: [],
|
||||
},
|
||||
]),
|
||||
recordRunAuditEvent,
|
||||
});
|
||||
const managerWithRecovery = new SelfHealingManager(storeWithAudit, { rootDir: "/tmp/test-project" });
|
||||
vi.spyOn(managerWithRecovery as any, "findAlreadyMergedTaskCommit").mockResolvedValue(null);
|
||||
|
||||
const recovered = await managerWithRecovery.recoverAlreadyMergedReviewTasks();
|
||||
|
||||
expect(recovered).toBe(0);
|
||||
expect(recordRunAuditEvent).not.toHaveBeenCalled();
|
||||
|
||||
managerWithRecovery.stop();
|
||||
});
|
||||
|
||||
it("continues recovery when run-audit persistence throws", async () => {
|
||||
const recordRunAuditEvent = vi.fn().mockRejectedValueOnce(new Error("audit write failed"));
|
||||
const storeWithAudit = createMockStore({
|
||||
getSettings: vi.fn().mockResolvedValue({ globalPause: false, enginePaused: false }),
|
||||
listTasks: vi.fn().mockResolvedValue([
|
||||
{
|
||||
id: "FN-audit-throw",
|
||||
column: "in-review",
|
||||
paused: false,
|
||||
status: "failed",
|
||||
mergeRetries: 5,
|
||||
mergeDetails: undefined,
|
||||
baseBranch: "main",
|
||||
branch: "fusion/fn-audit-throw",
|
||||
steps: [],
|
||||
log: [],
|
||||
},
|
||||
]),
|
||||
recordRunAuditEvent,
|
||||
});
|
||||
const managerWithRecovery = new SelfHealingManager(storeWithAudit, { rootDir: "/tmp/test-project" });
|
||||
vi.spyOn(managerWithRecovery as any, "findAlreadyMergedTaskCommit").mockResolvedValue({ sha: "def5678abc1234", strategy: "trailer" });
|
||||
|
||||
const recovered = await managerWithRecovery.recoverAlreadyMergedReviewTasks();
|
||||
|
||||
expect(recovered).toBe(1);
|
||||
expect(storeWithAudit.moveTask).toHaveBeenCalledWith("FN-audit-throw", "done");
|
||||
expect(recordRunAuditEvent).toHaveBeenCalledTimes(1);
|
||||
|
||||
managerWithRecovery.stop();
|
||||
});
|
||||
});
|
||||
|
||||
describe("recoverReviewTasksWithFailedPreMergeSteps", () => {
|
||||
const baseTask = {
|
||||
id: "FN-1572",
|
||||
|
||||
Reference in New Issue
Block a user