Add synthetic dry-run sync regression test
This commit is contained in:
parent
6e7c092484
commit
6d323393a3
1 changed files with 84 additions and 0 deletions
|
|
@ -1,3 +1,5 @@
|
|||
import { readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import type { Issue } from "@paperclipai/shared";
|
||||
import { ATTACHMENT_NOTE } from "../src/constants.js";
|
||||
|
|
@ -76,6 +78,11 @@ function buildIssue(overrides: Partial<Issue> = {}): Issue {
|
|||
} as Issue;
|
||||
}
|
||||
|
||||
function readExampleIssue(name: string): Issue {
|
||||
const filePath = resolve(import.meta.dirname, "..", "examples", name);
|
||||
return JSON.parse(readFileSync(filePath, "utf8")) as Issue;
|
||||
}
|
||||
|
||||
describe("paperclip issue sync", () => {
|
||||
it("selects issues by the configured sync label", () => {
|
||||
const issue = buildIssue();
|
||||
|
|
@ -325,4 +332,81 @@ describe("paperclip issue sync", () => {
|
|||
expect(retryComplete).toHaveBeenCalledOnce();
|
||||
expect(retryQueueManualReview).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("reproduces the synthetic dry-run payload and reuses the stored mapping on retry", async () => {
|
||||
const issue = readExampleIssue("first-dry-run-paperclip-issue.json");
|
||||
const payload = buildForgejoIssuePayload(issue);
|
||||
const createdRemoteIssue = {
|
||||
id: 401,
|
||||
number: 77,
|
||||
url: "https://forgejo.example/acme/repo/issues/77",
|
||||
apiUrl: "https://forgejo.example/api/v1/repos/acme/repo/issues/77"
|
||||
};
|
||||
const createRemoteIssue = vi.fn(async () => createdRemoteIssue);
|
||||
const complete = vi.fn(async () => undefined);
|
||||
|
||||
expect(payload.title).toBe("[PRIA-DRY-1] Synthetic dry-run: reproduce outbound issue creation");
|
||||
expect(payload.body).toContain("A controlled dry-run payload for the first Forgejo sync rehearsal.");
|
||||
expect(payload.body).toContain(ATTACHMENT_NOTE);
|
||||
expect(payload.body).toContain("trace.log | text/plain | 2.0 KiB");
|
||||
expect(payload.body).toContain("<!-- paperclip-sync:company-dry-run:issue-dry-run-1 -->");
|
||||
|
||||
const firstResult = await syncIssueToForgejo(
|
||||
{
|
||||
config: { get: async () => ({ forgejoOwner: "acme", forgejoRepo: "repo" }) },
|
||||
activity: { log: vi.fn(async () => undefined) }
|
||||
} as never,
|
||||
issue,
|
||||
{
|
||||
reserve: async () => ({ kind: "reserved" as const }),
|
||||
createRemoteIssue,
|
||||
recordRemote: vi.fn(async () => undefined),
|
||||
complete,
|
||||
fail: vi.fn(async () => undefined),
|
||||
failAfterRemote: vi.fn(async () => undefined),
|
||||
queueManualReview: vi.fn(async () => undefined)
|
||||
}
|
||||
);
|
||||
|
||||
const retryResult = await syncIssueToForgejo(
|
||||
{
|
||||
config: { get: async () => ({ forgejoOwner: "acme", forgejoRepo: "repo" }) },
|
||||
activity: { log: vi.fn(async () => undefined) }
|
||||
} as never,
|
||||
issue,
|
||||
{
|
||||
reserve: async () => ({
|
||||
kind: "existing" as const,
|
||||
mapping: {
|
||||
companyId: "company-dry-run",
|
||||
paperclipIssueId: "issue-dry-run-1",
|
||||
repoOwner: "acme",
|
||||
repoName: "repo",
|
||||
dedupeKey: "paperclip-issue:company-dry-run:issue-dry-run-1",
|
||||
sourceTitle: payload.title,
|
||||
sourceBody: payload.body,
|
||||
attachmentMetadata: [],
|
||||
manualReviewRequired: false,
|
||||
reviewReasonCode: null,
|
||||
forgejoIssueId: createdRemoteIssue.id,
|
||||
forgejoIssueNumber: createdRemoteIssue.number,
|
||||
forgejoIssueUrl: createdRemoteIssue.url,
|
||||
forgejoApiUrl: createdRemoteIssue.apiUrl,
|
||||
syncStatus: "synced",
|
||||
lastError: null
|
||||
}
|
||||
}),
|
||||
createRemoteIssue,
|
||||
complete,
|
||||
fail: vi.fn(async () => undefined),
|
||||
failAfterRemote: vi.fn(async () => undefined),
|
||||
queueManualReview: vi.fn(async () => undefined)
|
||||
}
|
||||
);
|
||||
|
||||
expect(firstResult).toBe("created");
|
||||
expect(retryResult).toBe("existing");
|
||||
expect(createRemoteIssue).toHaveBeenCalledTimes(1);
|
||||
expect(complete).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue