test(integrations): add provider-specific webhook route coverage
swadhinbiswas committed 8 months ago
60296a7
1 parent 3337d43
commit 60296a7
1 file changed
+114 -0
Showing 1 changed file+114-0
▼tests/integration/provider-webhook-routes.test.ts
+114-0
| @@ -0,0 +1,114 @@ | ||
1 | +import { beforeEach, describe, expect, it, vi } from "vitest"; | |
2 | + | |
3 | +const { issueWebhookHandler, qualityWebhookHandler } = vi.hoisted(() => ({ | |
4 | + issueWebhookHandler: vi.fn(async () => true), | |
5 | + qualityWebhookHandler: vi.fn(async () => true), | |
6 | +})); | |
7 | + | |
8 | +vi.mock("@/lib/air-gapped", () => ({ | |
9 | + isAirGappedMode: () => false, | |
10 | +})); | |
11 | + | |
12 | +vi.mock("@/lib/issue-trackers", () => ({ | |
13 | + ISSUE_PROVIDERS: { | |
14 | + jira: { name: "Jira" }, | |
15 | + linear: { name: "Linear" }, | |
16 | + trello: { name: "Trello" }, | |
17 | + clickup: { name: "ClickUp" }, | |
18 | + }, | |
19 | + handleIssueTrackerWebhook: issueWebhookHandler, | |
20 | +})); | |
21 | + | |
22 | +vi.mock("@/lib/code-quality", () => ({ | |
23 | + QUALITY_PROVIDERS: { | |
24 | + codecov: { name: "Codecov" }, | |
25 | + coveralls: { name: "Coveralls" }, | |
26 | + sonarqube: { name: "SonarQube" }, | |
27 | + snyk: { name: "Snyk" }, | |
28 | + }, | |
29 | + handleQualityWebhook: qualityWebhookHandler, | |
30 | +})); | |
31 | + | |
32 | +import { POST as issueWebhookPost } from "@/pages/api/repos/[owner]/[repo]/integrations/issue-trackers/[provider]/webhook"; | |
33 | +import { POST as qualityWebhookPost } from "@/pages/api/repos/[owner]/[repo]/integrations/code-quality/webhooks/[provider]"; | |
34 | + | |
35 | +async function json(response: Response): Promise<any> { | |
36 | + return response.json(); | |
37 | +} | |
38 | + | |
39 | +describe("provider webhook routes", () => { | |
40 | + beforeEach(() => { | |
41 | + issueWebhookHandler.mockClear(); | |
42 | + qualityWebhookHandler.mockClear(); | |
43 | + }); | |
44 | + | |
45 | + it("accepts all supported issue tracker providers and forwards payload", async () => { | |
46 | + for (const provider of ["jira", "linear", "trello", "clickup"]) { | |
47 | + const response = await issueWebhookPost({ | |
48 | + params: { provider }, | |
49 | + url: new URL(`http://localhost/api/repos/acme/demo/integrations/issue-trackers/${provider}/webhook?secret=sec`), | |
50 | + request: new Request(`http://localhost/api/repos/acme/demo/integrations/issue-trackers/${provider}/webhook?secret=sec`, { | |
51 | + method: "POST", | |
52 | + headers: { "content-type": "application/json" }, | |
53 | + body: JSON.stringify({ event: "update", provider }), | |
54 | + }), | |
55 | + } as any); | |
56 | + | |
57 | + const body = await json(response); | |
58 | + expect(response.status).toBe(200); | |
59 | + expect(body?.success).toBe(true); | |
60 | + expect(issueWebhookHandler).toHaveBeenCalledWith(provider, "sec", { event: "update", provider }); | |
61 | + } | |
62 | + }); | |
63 | + | |
64 | + it("rejects unsupported issue tracker provider", async () => { | |
65 | + const response = await issueWebhookPost({ | |
66 | + params: { provider: "unknown" }, | |
67 | + url: new URL("http://localhost/api/repos/acme/demo/integrations/issue-trackers/unknown/webhook?secret=sec"), | |
68 | + request: new Request("http://localhost/api/repos/acme/demo/integrations/issue-trackers/unknown/webhook?secret=sec", { | |
69 | + method: "POST", | |
70 | + headers: { "content-type": "application/json" }, | |
71 | + body: JSON.stringify({}), | |
72 | + }), | |
73 | + } as any); | |
74 | + | |
75 | + const body = await json(response); | |
76 | + expect(response.status).toBe(400); | |
77 | + expect(body?.error?.code).toBe("BAD_REQUEST"); | |
78 | + }); | |
79 | + | |
80 | + it("accepts all supported code quality providers and forwards payload", async () => { | |
81 | + for (const provider of ["codecov", "coveralls", "sonarqube", "snyk"]) { | |
82 | + const response = await qualityWebhookPost({ | |
83 | + params: { provider }, | |
84 | + url: new URL(`http://localhost/api/repos/acme/demo/integrations/code-quality/webhooks/${provider}?secret=sec`), | |
85 | + request: new Request(`http://localhost/api/repos/acme/demo/integrations/code-quality/webhooks/${provider}?secret=sec`, { | |
86 | + method: "POST", | |
87 | + headers: { "content-type": "application/json" }, | |
88 | + body: JSON.stringify({ event: "report", provider }), | |
89 | + }), | |
90 | + } as any); | |
91 | + | |
92 | + const body = await json(response); | |
93 | + expect(response.status).toBe(200); | |
94 | + expect(body?.success).toBe(true); | |
95 | + expect(qualityWebhookHandler).toHaveBeenCalledWith(provider, "sec", { event: "report", provider }); | |
96 | + } | |
97 | + }); | |
98 | + | |
99 | + it("rejects unsupported code quality provider", async () => { | |
100 | + const response = await qualityWebhookPost({ | |
101 | + params: { provider: "unknown" }, | |
102 | + url: new URL("http://localhost/api/repos/acme/demo/integrations/code-quality/webhooks/unknown?secret=sec"), | |
103 | + request: new Request("http://localhost/api/repos/acme/demo/integrations/code-quality/webhooks/unknown?secret=sec", { | |
104 | + method: "POST", | |
105 | + headers: { "content-type": "application/json" }, | |
106 | + body: JSON.stringify({}), | |
107 | + }), | |
108 | + } as any); | |
109 | + | |
110 | + const body = await json(response); | |
111 | + expect(response.status).toBe(400); | |
112 | + expect(body?.error?.code).toBe("BAD_REQUEST"); | |
113 | + }); | |
114 | +}); | |
0 | 115 | |