/ opencodehub / tests / integration / provider-webhook-routes.test.ts
swadhinbiswas test(integrations): add provider-specific webhook route coverage · 2/18/2026
60296a7
115 lines · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import { beforeEach, describe, expect, it, vi } from "vitest";

const { issueWebhookHandler, qualityWebhookHandler } = vi.hoisted(() => ({
  issueWebhookHandler: vi.fn(async () => true),
  qualityWebhookHandler: vi.fn(async () => true),
}));

vi.mock("@/lib/air-gapped", () => ({
  isAirGappedMode: () => false,
}));

vi.mock("@/lib/issue-trackers", () => ({
  ISSUE_PROVIDERS: {
    jira: { name: "Jira" },
    linear: { name: "Linear" },
    trello: { name: "Trello" },
    clickup: { name: "ClickUp" },
  },
  handleIssueTrackerWebhook: issueWebhookHandler,
}));

vi.mock("@/lib/code-quality", () => ({
  QUALITY_PROVIDERS: {
    codecov: { name: "Codecov" },
    coveralls: { name: "Coveralls" },
    sonarqube: { name: "SonarQube" },
    snyk: { name: "Snyk" },
  },
  handleQualityWebhook: qualityWebhookHandler,
}));

import { POST as issueWebhookPost } from "@/pages/api/repos/[owner]/[repo]/integrations/issue-trackers/[provider]/webhook";
import { POST as qualityWebhookPost } from "@/pages/api/repos/[owner]/[repo]/integrations/code-quality/webhooks/[provider]";

async function json(response: Response): Promise<any> {
  return response.json();
}

describe("provider webhook routes", () => {
  beforeEach(() => {
    issueWebhookHandler.mockClear();
    qualityWebhookHandler.mockClear();
  });

  it("accepts all supported issue tracker providers and forwards payload", async () => {
    for (const provider of ["jira", "linear", "trello", "clickup"]) {
      const response = await issueWebhookPost({
        params: { provider },
        url: new URL(`http://localhost/api/repos/acme/demo/integrations/issue-trackers/${provider}/webhook?secret=sec`),
        request: new Request(`http://localhost/api/repos/acme/demo/integrations/issue-trackers/${provider}/webhook?secret=sec`, {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify({ event: "update", provider }),
        }),
      } as any);

      const body = await json(response);
      expect(response.status).toBe(200);
      expect(body?.success).toBe(true);
      expect(issueWebhookHandler).toHaveBeenCalledWith(provider, "sec", { event: "update", provider });
    }
  });

  it("rejects unsupported issue tracker provider", async () => {
    const response = await issueWebhookPost({
      params: { provider: "unknown" },
      url: new URL("http://localhost/api/repos/acme/demo/integrations/issue-trackers/unknown/webhook?secret=sec"),
      request: new Request("http://localhost/api/repos/acme/demo/integrations/issue-trackers/unknown/webhook?secret=sec", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({}),
      }),
    } as any);

    const body = await json(response);
    expect(response.status).toBe(400);
    expect(body?.error?.code).toBe("BAD_REQUEST");
  });

  it("accepts all supported code quality providers and forwards payload", async () => {
    for (const provider of ["codecov", "coveralls", "sonarqube", "snyk"]) {
      const response = await qualityWebhookPost({
        params: { provider },
        url: new URL(`http://localhost/api/repos/acme/demo/integrations/code-quality/webhooks/${provider}?secret=sec`),
        request: new Request(`http://localhost/api/repos/acme/demo/integrations/code-quality/webhooks/${provider}?secret=sec`, {
          method: "POST",
          headers: { "content-type": "application/json" },
          body: JSON.stringify({ event: "report", provider }),
        }),
      } as any);

      const body = await json(response);
      expect(response.status).toBe(200);
      expect(body?.success).toBe(true);
      expect(qualityWebhookHandler).toHaveBeenCalledWith(provider, "sec", { event: "report", provider });
    }
  });

  it("rejects unsupported code quality provider", async () => {
    const response = await qualityWebhookPost({
      params: { provider: "unknown" },
      url: new URL("http://localhost/api/repos/acme/demo/integrations/code-quality/webhooks/unknown?secret=sec"),
      request: new Request("http://localhost/api/repos/acme/demo/integrations/code-quality/webhooks/unknown?secret=sec", {
        method: "POST",
        headers: { "content-type": "application/json" },
        body: JSON.stringify({}),
      }),
    } as any);

    const body = await json(response);
    expect(response.status).toBe(400);
    expect(body?.error?.code).toBe("BAD_REQUEST");
  });
});