File
Blob: tests/worker/webhooks/public/gitea.test.ts
| 1 | import { describe, expect, it } from "vitest"; |
| 2 | |
| 3 | import { readProjectDoRows } from "../../../helpers/runtime"; |
| 4 | import { registerWorkerRuntimeHooks } from "../../../helpers/worker-hooks"; |
| 5 | |
| 6 | import { createOwnedProjectContext, getWebhooks, postPublicWebhook, putWebhook, signGiteaPayload } from "../helpers"; |
| 7 | import { AFTER_SHA, BEFORE_SHA } from "../public-helpers"; |
| 8 | |
| 9 | describe("webhook public routes", () => { |
| 10 | registerWorkerRuntimeHooks(); |
| 11 | |
| 12 | describe("Gitea deliveries", () => { |
| 13 | it("accepts canonical Gitea repo URL variants with .git, trailing slash, public port, and path prefix", async () => { |
| 14 | const context = await createOwnedProjectContext({ |
| 15 | user: { |
| 16 | email: "webhook-public-gitea@example.com", |
| 17 | slug: "webhook-public-gitea", |
| 18 | }, |
| 19 | project: { |
| 20 | projectSlug: "gitea-public-project", |
| 21 | repoUrl: "https://gitea.example.com:8443/git/example/gitea-public-project", |
| 22 | }, |
| 23 | }); |
| 24 | |
| 25 | await putWebhook(context.sessionId, context.project.id, "gitea", { |
| 26 | enabled: true, |
| 27 | config: { |
| 28 | instanceUrl: "https://gitea.example.com:8443/git", |
| 29 | }, |
| 30 | secret: "gitea-secret", |
| 31 | }); |
| 32 | |
| 33 | const body = JSON.stringify({ |
| 34 | ref: "refs/heads/main", |
| 35 | before: BEFORE_SHA, |
| 36 | after: AFTER_SHA, |
| 37 | repository: { |
| 38 | clone_url: `${context.project.repoUrl}.git/`, |
| 39 | default_branch: context.project.defaultBranch, |
| 40 | }, |
| 41 | }); |
| 42 | |
| 43 | const accepted = await postPublicWebhook("gitea", context.project, body, { |
| 44 | "content-type": "application/json; charset=utf-8", |
| 45 | "x-gitea-event": "push", |
| 46 | "x-gitea-delivery": "gitea-delivery-accepted", |
| 47 | "x-gitea-signature": await signGiteaPayload("gitea-secret", body), |
| 48 | }); |
| 49 | expect(accepted.status).toBe(202); |
| 50 | |
| 51 | const rows = await readProjectDoRows(context.project.id); |
| 52 | expect(rows.runs).toHaveLength(1); |
| 53 | expect(rows.runs[0]?.provider).toBe("gitea"); |
| 54 | expect(rows.runs[0]?.deliveryId).toBe("gitea-delivery-accepted"); |
| 55 | expect(rows.runs[0]?.branch).toBe("main"); |
| 56 | expect(rows.runs[0]?.commitSha).toBe(AFTER_SHA); |
| 57 | expect(rows.webhookDeliveries).toHaveLength(1); |
| 58 | expect(rows.webhookDeliveries[0]?.repoUrl).toBe(context.project.repoUrl); |
| 59 | }); |
| 60 | |
| 61 | it("records Gitea non-push events as ignored_event", async () => { |
| 62 | const context = await createOwnedProjectContext({ |
| 63 | user: { |
| 64 | email: "webhook-public-gitea-events@example.com", |
| 65 | slug: "webhook-public-gitea-events", |
| 66 | }, |
| 67 | project: { |
| 68 | projectSlug: "gitea-events-project", |
| 69 | repoUrl: "https://gitea.example.com/example/gitea-events-project", |
| 70 | }, |
| 71 | }); |
| 72 | |
| 73 | await putWebhook(context.sessionId, context.project.id, "gitea", { |
| 74 | enabled: true, |
| 75 | config: { |
| 76 | instanceUrl: "https://gitea.example.com", |
| 77 | }, |
| 78 | secret: "gitea-events-secret", |
| 79 | }); |
| 80 | |
| 81 | const createBody = JSON.stringify({ |
| 82 | ref: "v1.0.0", |
| 83 | ref_type: "tag", |
| 84 | repository: { |
| 85 | full_name: "example/gitea-events-project", |
| 86 | clone_url: "https://gitea.example.com/example/gitea-events-project.git", |
| 87 | }, |
| 88 | }); |
| 89 | const createResponse = await postPublicWebhook("gitea", context.project, createBody, { |
| 90 | "content-type": "application/json; charset=utf-8", |
| 91 | "x-gitea-event": "create", |
| 92 | "x-gitea-delivery": "gitea-create-delivery", |
| 93 | "x-gitea-signature": await signGiteaPayload("gitea-events-secret", createBody), |
| 94 | }); |
| 95 | expect(createResponse.status).toBe(200); |
| 96 | |
| 97 | const pullRequestBody = JSON.stringify({ |
| 98 | action: "opened", |
| 99 | number: 1, |
| 100 | repository: { |
| 101 | full_name: "example/gitea-events-project", |
| 102 | clone_url: "https://gitea.example.com/example/gitea-events-project.git", |
| 103 | }, |
| 104 | }); |
| 105 | const pullRequestResponse = await postPublicWebhook("gitea", context.project, pullRequestBody, { |
| 106 | "content-type": "application/json; charset=utf-8", |
| 107 | "x-gitea-event": "pull_request", |
| 108 | "x-gitea-delivery": "gitea-pull-request-delivery", |
| 109 | "x-gitea-signature": await signGiteaPayload("gitea-events-secret", pullRequestBody), |
| 110 | }); |
| 111 | expect(pullRequestResponse.status).toBe(200); |
| 112 | |
| 113 | const rows = await readProjectDoRows(context.project.id); |
| 114 | expect(rows.runs).toHaveLength(0); |
| 115 | expect(rows.webhookDeliveries).toHaveLength(2); |
| 116 | expect(rows.webhookDeliveries.every((row) => row.outcome === "ignored_event")).toBe(true); |
| 117 | expect(rows.webhookDeliveries.find((row) => row.deliveryId === "gitea-create-delivery")?.ref).toBe("v1.0.0"); |
| 118 | |
| 119 | const listed = await getWebhooks(context.sessionId, context.project.id); |
| 120 | expect(listed.status).toBe(200); |
| 121 | expect( |
| 122 | listed.body?.webhooks[0]?.recentDeliveries.find((delivery) => delivery.deliveryId === "gitea-create-delivery") |
| 123 | ?.ref, |
| 124 | ).toBe("v1.0.0"); |
| 125 | }); |
| 126 | }); |
| 127 | }); |