Skip to content

Commit 001b24b

Browse files
committed
feat: update name and slug request and tests.
1 parent 40e1bef commit 001b24b

File tree

8 files changed

+338
-21
lines changed

8 files changed

+338
-21
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
import { POST } from "@/app/api/account/route";
2+
import { NextRequest, NextResponse } from "next/server";
3+
import { getServerSession } from "next-auth";
4+
import { prisma } from "@/lib/prisma";
5+
6+
// Mock dependencies
7+
jest.mock("next-auth", () => ({
8+
getServerSession: jest.fn(),
9+
}));
10+
11+
jest.mock("@/lib/prisma", () => ({
12+
prisma: {
13+
user: {
14+
findUnique: jest.fn(),
15+
update: jest.fn(),
16+
},
17+
},
18+
}));
19+
20+
jest.mock("@/lib/auth", () => ({
21+
authOptions: {},
22+
}));
23+
24+
// Create a mock NextRequest
25+
const createMockNextRequest = (body: any): NextRequest => {
26+
const bodyString = JSON.stringify(body);
27+
28+
return new Request("https://example.com", {
29+
method: "POST",
30+
body: bodyString,
31+
headers: {
32+
"Content-Type": "application/json",
33+
},
34+
}) as unknown as NextRequest;
35+
};
36+
37+
describe("User Profile Update Endpoint", () => {
38+
// Mock session data
39+
const mockSession = {
40+
user: {
41+
id: "user123",
42+
43+
},
44+
};
45+
46+
beforeEach(() => {
47+
// Clear all mocks before each test
48+
jest.clearAllMocks();
49+
});
50+
51+
it("should successfully update user profile when all validations pass", async () => {
52+
// Setup mocks
53+
(getServerSession as jest.Mock).mockResolvedValue(mockSession);
54+
(prisma.user.findUnique as jest.Mock).mockResolvedValue(null);
55+
(prisma.user.update as jest.Mock).mockResolvedValue({
56+
id: "user123",
57+
name: "New Name",
58+
slug: "new-slug",
59+
});
60+
61+
// Create mock request
62+
const mockRequest = createMockNextRequest({
63+
name: "New Name",
64+
slug: "new-slug",
65+
});
66+
67+
// Call the endpoint
68+
const response = await POST(mockRequest);
69+
const responseBody = await response.json();
70+
71+
// Assertions
72+
expect(response.status).toBe(200);
73+
expect(responseBody.data).toEqual({
74+
id: "user123",
75+
name: "New Name",
76+
slug: "new-slug",
77+
});
78+
expect(prisma.user.update).toHaveBeenCalledWith({
79+
where: { id: "user123" },
80+
data: { name: "New Name", slug: "new-slug" },
81+
});
82+
});
83+
84+
it("should return 401 if no session exists", async () => {
85+
// Setup mocks
86+
(getServerSession as jest.Mock).mockResolvedValue(null);
87+
88+
// Create mock request
89+
const mockRequest = createMockNextRequest({
90+
name: "New Name",
91+
slug: "new-slug",
92+
});
93+
94+
// Call the endpoint
95+
const response = await POST(mockRequest);
96+
const responseBody = await response.json();
97+
98+
// Assertions
99+
expect(response.status).toBe(401);
100+
expect(responseBody.error).toBe("Unauthorized");
101+
});
102+
103+
it("should return 400 if name or slug is missing", async () => {
104+
// Setup mocks
105+
(getServerSession as jest.Mock).mockResolvedValue(mockSession);
106+
107+
// Create mock request with missing slug
108+
const mockRequest = createMockNextRequest({
109+
name: "New Name",
110+
});
111+
112+
// Call the endpoint
113+
const response = await POST(mockRequest);
114+
const responseBody = await response.json();
115+
116+
// Assertions
117+
expect(response.status).toBe(400);
118+
expect(responseBody.error).toBe("Name and slug are required");
119+
});
120+
121+
it("should return 400 if slug is invalid", async () => {
122+
// Setup mocks
123+
(getServerSession as jest.Mock).mockResolvedValue(mockSession);
124+
125+
// Create mock request with invalid slug
126+
const mockRequest = createMockNextRequest({
127+
name: "New Name",
128+
slug: "Invalid Slug!",
129+
});
130+
131+
// Call the endpoint
132+
const response = await POST(mockRequest);
133+
const responseBody = await response.json();
134+
135+
// Assertions
136+
expect(response.status).toBe(400);
137+
expect(responseBody.error).toBe("Slug must be alphanumeric and lowercase");
138+
});
139+
140+
it("should return 400 if slug is already taken", async () => {
141+
// Setup mocks
142+
(getServerSession as jest.Mock).mockResolvedValue(mockSession);
143+
(prisma.user.findUnique as jest.Mock).mockResolvedValue({
144+
id: "another-user",
145+
slug: "existing-slug",
146+
});
147+
148+
// Create mock request
149+
const mockRequest = createMockNextRequest({
150+
name: "New Name",
151+
slug: "existing-slug",
152+
});
153+
154+
// Call the endpoint
155+
const response = await POST(mockRequest);
156+
const responseBody = await response.json();
157+
158+
// Assertions
159+
expect(response.status).toBe(400);
160+
expect(responseBody.error).toBe("Slug is already taken");
161+
});
162+
163+
it("should handle unexpected errors", async () => {
164+
// Setup mocks to throw an error
165+
(getServerSession as jest.Mock).mockRejectedValue(new Error("Unexpected error"));
166+
167+
// Create mock request
168+
const mockRequest = createMockNextRequest({
169+
name: "New Name",
170+
slug: "new-slug",
171+
});
172+
173+
// Call the endpoint
174+
const response = await POST(mockRequest);
175+
const responseBody = await response.json();
176+
177+
// Assertions
178+
expect(response.status).toBe(500);
179+
expect(responseBody.error).toBeTruthy();
180+
});
181+
});

__tests__/auth.test.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,14 +41,12 @@ describe("Authentication Configuration", () => {
4141
expect(authOptions.adapter).toBeDefined();
4242
});
4343

44-
// it("should have custom pages configured", () => {
45-
// expect(authOptions.pages).toEqual({
46-
// signIn: "/auth/signin",
47-
// signOut: "/auth/signout",
48-
// error: "/auth/error",
49-
// verifyRequest: "/auth/verify-request",
50-
// });
51-
// });
44+
it("should have custom pages configured", () => {
45+
expect(authOptions.pages).toEqual({
46+
signIn: "/login",
47+
signOut: "/logout",
48+
});
49+
});
5250
});
5351

5452
describe("Email Verification", () => {

jest.setup.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
1-
// jest.setup.ts
21
import "@testing-library/jest-dom";
2+
import { Request, Response } from "@whatwg-node/fetch";
3+
4+
// Polyfill global Request if not available
5+
if (typeof globalThis.Request === "undefined") {
6+
globalThis.Request = Request;
7+
}
8+
9+
// Polyfill global Response if not available
10+
if (typeof globalThis.Response === "undefined") {
11+
globalThis.Response = Response;
12+
}

package-lock.json

Lines changed: 76 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
"@types/nodemailer": "^6.4.17",
5353
"@types/react": "^18.3.12",
5454
"@types/react-dom": "^18.3.1",
55+
"@whatwg-node/fetch": "^0.10.1",
5556
"babel-jest": "^29.7.0",
5657
"eslint": "^8",
5758
"eslint-config-next": "15.0.3",

0 commit comments

Comments
 (0)