-
Notifications
You must be signed in to change notification settings - Fork 19
/
Copy pathsaleor-async-webhook.test.ts
116 lines (96 loc) · 3.89 KB
/
saleor-async-webhook.test.ts
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
116
import { afterEach, describe, expect, it, vi } from "vitest";
import { FormatWebhookErrorResult } from "@/handlers/shared";
import { SaleorWebhookValidator } from "@/handlers/shared/saleor-webhook-validator";
import { MockAPL } from "@/test-utils/mock-apl";
import { AsyncWebhookEventType } from "@/types";
import { SaleorAsyncWebhook } from "./saleor-async-webhook";
import { WebApiWebhookHandler, WebhookConfig } from "./saleor-webhook";
const webhookPath = "api/webhooks/product-updated";
const baseUrl = "http://example.com";
describe("Web API SaleorAsyncWebhook", () => {
const mockAPL = new MockAPL();
const validConfig: WebhookConfig<AsyncWebhookEventType> = {
apl: mockAPL,
event: "PRODUCT_UPDATED",
webhookPath,
query: "subscription { event { ... on ProductUpdated { product { id }}}}",
} as const;
afterEach(() => {
vi.restoreAllMocks();
});
describe("createHandler", () => {
it("validates request before passing it to provided handler function with context", async () => {
vi.spyOn(SaleorWebhookValidator.prototype, "validateRequest").mockResolvedValue({
result: "ok",
context: {
baseUrl: "example.com",
event: "product_updated",
payload: { data: "test_payload" },
schemaVersion: [3, 20],
authData: {
saleorApiUrl: mockAPL.workingSaleorApiUrl,
token: mockAPL.mockToken,
jwks: mockAPL.mockJwks,
appId: mockAPL.mockAppId,
},
},
});
const handler = vi
.fn<WebApiWebhookHandler>()
.mockImplementation(() => new Response("OK", { status: 200 }));
const webhook = new SaleorAsyncWebhook(validConfig);
const request = new Request(`${baseUrl}/webhook`);
const wrappedHandler = webhook.createHandler(handler);
const response = await wrappedHandler(request);
expect(response.status).toBe(200);
expect(handler).toBeCalledTimes(1);
expect(handler).toHaveBeenCalledWith(
request,
expect.objectContaining({
payload: { data: "test_payload" },
authData: expect.objectContaining({
saleorApiUrl: mockAPL.workingSaleorApiUrl,
}),
}),
);
});
it("prevents handler execution when validation fails and returns error", async () => {
vi.spyOn(SaleorWebhookValidator.prototype, "validateRequest").mockResolvedValue({
result: "failure",
error: new Error("Test error"),
});
const webhook = new SaleorAsyncWebhook(validConfig);
const handler = vi.fn();
const request = new Request(`${baseUrl}/webhook`);
const wrappedHandler = webhook.createHandler(handler);
const response = await wrappedHandler(request);
expect(response.status).toBe(500);
await expect(response.text()).resolves.toBe("Unexpected error while handling request");
expect(handler).not.toHaveBeenCalled();
});
it("should allow overriding error responses using formatErrorResponse", async () => {
vi.spyOn(SaleorWebhookValidator.prototype, "validateRequest").mockResolvedValue({
result: "failure",
error: new Error("Test error"),
});
const mockFormatErrorResponse = vi.fn().mockResolvedValue({
body: "Custom error",
code: 418,
} as FormatWebhookErrorResult);
const webhook = new SaleorAsyncWebhook({
...validConfig,
formatErrorResponse: mockFormatErrorResponse,
});
const request = new Request(`${baseUrl}/webhook`, {
method: "POST",
headers: { "saleor-event": "invalid_event" },
});
const handler = vi.fn();
const wrappedHandler = webhook.createHandler(handler);
const response = await wrappedHandler(request);
expect(response.status).toBe(418);
await expect(response.text()).resolves.toBe("Custom error");
expect(handler).not.toHaveBeenCalled();
});
});
});