Skip to content

Commit 30ca386

Browse files
committed
test: defineRoute
1 parent eeddd1c commit 30ca386

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed

src/core/definer.test.ts

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
/* eslint-disable no-console */
2+
import { afterEach, describe, expect, it, jest } from "@jest/globals";
3+
import z from "zod";
4+
import defineRoute from "./definer";
5+
6+
describe("defineRoute", () => {
7+
const mockAction = jest.fn() as jest.Mock<() => Promise<Response>>;
8+
const mockRequest = {
9+
url: "https://example.com/test",
10+
json: jest.fn() as jest.Mock<() => Promise<unknown>>,
11+
formData: jest.fn(),
12+
};
13+
14+
afterEach(() => {
15+
jest.clearAllMocks();
16+
});
17+
18+
it("should handle a route without pathParams and body for GET method", async () => {
19+
const route = defineRoute({
20+
operationId: "getExample",
21+
method: "GET",
22+
summary: "Get Example",
23+
description: "Fetches example data",
24+
tags: ["example"],
25+
action: mockAction,
26+
responses: {
27+
200: { description: "OK" },
28+
},
29+
});
30+
31+
mockAction.mockResolvedValue(new Response("Success"));
32+
33+
const nextJsRouteHandler = route.GET;
34+
const response = await nextJsRouteHandler(mockRequest as unknown as Request, {});
35+
36+
expect(mockAction).toHaveBeenCalledWith({
37+
pathParams: null,
38+
queryParams: null,
39+
body: null,
40+
});
41+
42+
expect(response).toBeInstanceOf(Response);
43+
expect(response.status).toBe(200);
44+
});
45+
46+
it("should handle a POST route with pathParams and body", async () => {
47+
const pathSchema = z.object({ id: z.string() });
48+
const bodySchema = z.object({ name: z.string() });
49+
50+
mockRequest.json.mockResolvedValue({ name: "Test" });
51+
52+
const route = defineRoute({
53+
operationId: "postExample",
54+
method: "POST",
55+
summary: "Create Example",
56+
description: "Creates example data",
57+
tags: ["example"],
58+
pathParams: pathSchema,
59+
requestBody: bodySchema,
60+
action: mockAction,
61+
responses: {
62+
201: { description: "Created" },
63+
},
64+
});
65+
66+
mockAction.mockResolvedValue(new Response("Created", { status: 201 }));
67+
68+
const nextJsRouteHandler = route.POST;
69+
const response = await nextJsRouteHandler(mockRequest as unknown as Request, { params: { id: "123" } });
70+
71+
expect(mockAction).toHaveBeenCalledWith({
72+
pathParams: { id: "123" },
73+
queryParams: null,
74+
body: { name: "Test" },
75+
});
76+
77+
expect(response).toBeInstanceOf(Response);
78+
expect(response.status).toBe(201);
79+
});
80+
81+
it("should return 400 on bad request (invalid body)", async () => {
82+
const originalLog = console.log;
83+
console.log = jest.fn(); // Mock console.log to verify error logging
84+
85+
const bodySchema = z.object({ name: z.string() });
86+
87+
mockRequest.json.mockResolvedValue({});
88+
89+
const route = defineRoute({
90+
operationId: "postExample",
91+
method: "POST",
92+
summary: "Create Example",
93+
description: "Creates example data",
94+
tags: ["example"],
95+
requestBody: bodySchema,
96+
action: mockAction,
97+
responses: {
98+
201: { description: "Created" },
99+
},
100+
});
101+
102+
const nextJsRouteHandler = route.POST;
103+
const response = await nextJsRouteHandler(mockRequest as unknown as Request, {});
104+
105+
expect(response).toBeInstanceOf(Response);
106+
expect(response.status).toBe(400);
107+
108+
expect(console.log).toHaveBeenCalled();
109+
console.log = originalLog; // Restore original console.log
110+
});
111+
112+
it("should return 500 on internal server error", async () => {
113+
const route = defineRoute({
114+
operationId: "getExample",
115+
method: "GET",
116+
summary: "Get Example",
117+
description: "Fetches example data",
118+
tags: ["example"],
119+
action: () => {
120+
throw new Error("Internal Error");
121+
},
122+
responses: {
123+
200: { description: "OK" },
124+
},
125+
});
126+
127+
const nextJsRouteHandler = route.GET;
128+
const response = await nextJsRouteHandler(mockRequest as unknown as Request, {});
129+
130+
expect(response).toBeInstanceOf(Response);
131+
expect(response.status).toBe(500);
132+
});
133+
134+
it("should return 404 when pathParams are missing", async () => {
135+
const originalLog = console.log;
136+
console.log = jest.fn();
137+
138+
const pathSchema = z.object({ id: z.string() });
139+
140+
const route = defineRoute({
141+
operationId: "getExample",
142+
method: "GET",
143+
summary: "Get Example",
144+
description: "Fetches example data",
145+
tags: ["example"],
146+
pathParams: pathSchema,
147+
action: mockAction,
148+
responses: {
149+
200: { description: "OK" },
150+
},
151+
});
152+
153+
const invalidParams = {} as unknown as z.infer<typeof pathSchema>;
154+
const nextJsRouteHandler = route.GET;
155+
const response = await nextJsRouteHandler(mockRequest as unknown as Request, { params: invalidParams });
156+
157+
expect(response).toBeInstanceOf(Response);
158+
expect(response.status).toBe(404);
159+
expect(console.log).toHaveBeenCalled();
160+
console.log = originalLog; // Restore original console.log
161+
});
162+
163+
it("should add 400 Bad Request response if queryParams or requestBody exists", () => {
164+
const queryParams = z.object({ search: z.string() });
165+
166+
const route = defineRoute({
167+
operationId: "getExample",
168+
method: "GET",
169+
summary: "Get Example",
170+
description: "Fetches example data",
171+
tags: ["example"],
172+
queryParams,
173+
action: mockAction,
174+
responses: {
175+
200: { description: "OK" },
176+
},
177+
});
178+
179+
const nextJsRouteHandler = route.GET;
180+
181+
expect(nextJsRouteHandler.apiData).not.toBeUndefined();
182+
if (!nextJsRouteHandler.apiData) throw new Error("TEST ERROR");
183+
expect(nextJsRouteHandler.apiData.responses).not.toBeUndefined();
184+
if (!nextJsRouteHandler.apiData.responses) throw new Error("TEST ERROR");
185+
expect(nextJsRouteHandler.apiData.responses["400"]).toEqual({
186+
description: "Bad Request",
187+
});
188+
});
189+
190+
it("should log a message when unnecessary pathParams are provided in non-production environments", async () => {
191+
const originalLog = console.log;
192+
console.log = jest.fn(); // Mock console.log
193+
194+
const route = defineRoute({
195+
operationId: "getExample",
196+
method: "GET",
197+
summary: "Get Example",
198+
description: "Fetches example data",
199+
tags: ["example"],
200+
pathParams: z.object({ id: z.string() }),
201+
action: mockAction,
202+
responses: {
203+
200: { description: "OK" },
204+
},
205+
});
206+
207+
const nextJsRouteHandler = route.GET;
208+
209+
await nextJsRouteHandler(mockRequest as unknown as Request, {});
210+
211+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("You tried to add pathParams to a route"));
212+
213+
console.log = originalLog;
214+
});
215+
});

0 commit comments

Comments
 (0)