From fd3b095a76fc81db0da6fe80d0423d148255f7ea Mon Sep 17 00:00:00 2001 From: Shubh Tiwari Date: Wed, 7 May 2025 01:28:15 +0530 Subject: [PATCH 1/2] integrated problem.test register.test in testsuit --- reports/junit.xml | 142 ++++++--- reports/test-report.html | 6 +- tests/problems._test.ts | 111 ------- tests/problems.test.ts | 645 +++++++++++++++++++++++++++++++++++++++ tests/register.test.ts | 520 +++++++++++++++++++++++++++++++ tests/register_test.ts | 191 ------------ 6 files changed, 1268 insertions(+), 347 deletions(-) delete mode 100644 tests/problems._test.ts create mode 100644 tests/problems.test.ts create mode 100644 tests/register.test.ts delete mode 100644 tests/register_test.ts diff --git a/reports/junit.xml b/reports/junit.xml index 19b4a9a..2cc7543 100644 --- a/reports/junit.xml +++ b/reports/junit.xml @@ -1,49 +1,55 @@ - - - + + + - + - + + + - + - - - + - + - - + + - + - + - + - - + + - + - + - + - + + + + + + + - - + + - + - + @@ -51,47 +57,59 @@ - + + + + + + + + + + + + + - + - + - + - + - - + + - + - + - - + + - + - + @@ -100,14 +118,14 @@ - - + + - - + + @@ -116,4 +134,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/reports/test-report.html b/reports/test-report.html index 1936109..1b230b3 100644 --- a/reports/test-report.html +++ b/reports/test-report.html @@ -274,7 +274,7 @@ font-size: 1rem; padding: 0 0.5rem; } -

Test Report

Started: 2025-05-04 23:04:45
Suites (10)
10 passed
0 failed
0 pending
Tests (48)
48 passed
0 failed
0 pending
C:\Users\shubh\pariksa\mint\tests\me.test.ts
2.222s
GET /api/me
should return user data if session is valid
passed
0.025s
GET /api/me
should return 401 if session is invalid
passed
0.001s
GET /api/me
should return 404 if user not found
passed
0.002s
GET /api/me
should return 500 on internal error
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\code.test.ts
2.23s
POST /api/execute
should forward the request to Piston API and return the result
passed
0.021s
POST /api/execute
should return 500 on unexpected error
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\logout.test.ts
2.239s
DELETE /api/auth/logout
should logout successfully with valid session
passed
0.02s
DELETE /api/auth/logout
should handle case when no session exists
passed
0.002s
DELETE /api/auth/logout
should handle errors during logout process
passed
0.006s
DELETE /api/auth/logout
should handle errors during session invalidation
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\users.test.ts
2.316s
GET /users
should return users successfully
passed
0.022s
GET /users
should return 500 if fetching fails
passed
0.002s
POST /users
should invite user successfully
passed
0.003s
POST /users
should return 400 for invalid request body
passed
0.003s
POST /users
should return 400 for service errors
passed
0.001s
C:\Users\shubh\pariksa\mint\tests\participants.test.ts
2.32s
POST /participants
should register a participant successfully
passed
0.022s
POST /participants
should return 400 on Zod validation error
passed
0.002s
POST /participants
should return 403 for disallowed errors
passed
0.002s
GET /participants
should return participants successfully
passed
0.002s
GET /participants
should return 404 for not found errors
passed
0.001s
DELETE /participants
should remove participant successfully
passed
0.002s
DELETE /participants
should return 404 if user not registered
passed
0.001s
C:\Users\shubh\pariksa\mint\tests\problemid.test.ts
2.321s
GET /problems/:problemId
should return problem details
passed
0.02s
GET /problems/:problemId
should return 404 if not found
passed
0.002s
PATCH /problems/:problemId
should update problem successfully
passed
0.003s
PATCH /problems/:problemId
should return 404 if problem not found during update
passed
0.001s
DELETE /problems/:problemId
should delete problem successfully
passed
0.002s
DELETE /problems/:problemId
should return 404 if problem not found
passed
0.001s
DELETE /problems/:problemId
should return 409 if problem is used in contests
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\submissions.test.ts
2.329s
GET /submissions
should return submissions successfully
passed
0.029s
GET /submissions
should return 404 if org not found
passed
0.002s
POST /submissions
should create a submission successfully
passed
0.004s
POST /submissions
should return 400 for known error thrown by service
passed
0.003s
POST /submissions
should return 400 for invalid submission schema
passed
0.002s
Console Log
    at C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:22:13
+

Test Report

Started: 2025-05-07 01:26:36
Suites (12)
12 passed
0 failed
0 pending
Tests (75)
75 passed
0 failed
0 pending
C:\Users\shubh\pariksa\mint\tests\code.test.ts
2.581s
POST /api/execute
should forward the request to Piston API and return the result
passed
0.02s
POST /api/execute
should return 500 on unexpected error
passed
0.001s
C:\Users\shubh\pariksa\mint\tests\logout.test.ts
2.593s
DELETE /api/auth/logout
should logout successfully with valid session
passed
0.02s
DELETE /api/auth/logout
should handle case when no session exists
passed
0.002s
DELETE /api/auth/logout
should handle errors during logout process
passed
0.002s
DELETE /api/auth/logout
should handle errors during session invalidation
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\me.test.ts
2.601s
GET /api/me
should return user data if session is valid
passed
0.019s
GET /api/me
should return 401 if session is invalid
passed
0.003s
GET /api/me
should return 404 if user not found
passed
0.002s
GET /api/me
should return 500 on internal error
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\register.test.ts
2.615s
User Registration API Route
should successfully register a new user
passed
0.023s
User Registration API Route
should return 400 if email already exists
passed
0.003s
User Registration API Route
should return 400 if validation fails
passed
0.002s
User Registration API Route
should return 400 if password hashing fails
passed
0.003s
User Registration API Route
should return 400 if username generation fails
passed
0.002s
User Registration API Route
should return 400 if database insert fails
passed
0.002s
User Registration API Route
should return 400 if session creation fails
passed
0.001s
User Registration API Route
should return 400 if cookie setting fails
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\participants.test.ts
2.678s
POST /participants
should register a participant successfully
passed
0.021s
POST /participants
should return 400 on Zod validation error
passed
0.004s
POST /participants
should return 403 for disallowed errors
passed
0.003s
GET /participants
should return participants successfully
passed
0.002s
GET /participants
should return 404 for not found errors
passed
0.001s
DELETE /participants
should remove participant successfully
passed
0.002s
DELETE /participants
should return 404 if user not registered
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\users.test.ts
2.702s
GET /users
should return users successfully
passed
0.019s
GET /users
should return 500 if fetching fails
passed
0.002s
POST /users
should invite user successfully
passed
0.003s
POST /users
should return 400 for invalid request body
passed
0.002s
POST /users
should return 400 for service errors
passed
0.001s
C:\Users\shubh\pariksa\mint\tests\problemid.test.ts
2.691s
GET /problems/:problemId
should return problem details
passed
0.02s
GET /problems/:problemId
should return 404 if not found
passed
0.002s
PATCH /problems/:problemId
should update problem successfully
passed
0.003s
PATCH /problems/:problemId
should return 404 if problem not found during update
passed
0.002s
DELETE /problems/:problemId
should delete problem successfully
passed
0.002s
DELETE /problems/:problemId
should return 404 if problem not found
passed
0.002s
DELETE /problems/:problemId
should return 409 if problem is used in contests
passed
0.001s
C:\Users\shubh\pariksa\mint\tests\submissions.test.ts
2.719s
GET /submissions
should return submissions successfully
passed
0.041s
GET /submissions
should return 404 if org not found
passed
0.002s
POST /submissions
should create a submission successfully
passed
0.004s
POST /submissions
should return 400 for known error thrown by service
passed
0.002s
POST /submissions
should return 400 for invalid submission schema
passed
0.003s
Console Log
    at C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:22:13
     at Generator.next (<anonymous>)
     at fulfilled (C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:38:58)
     at processTicksAndRejections (node:internal/process/task_queues:95:5)
orgid= 1
    at C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:25:13
@@ -328,7 +328,7 @@
 }
    at C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:75:13
     at Generator.next (<anonymous>)
     at fulfilled (C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:38:58)
-    at processTicksAndRejections (node:internal/process/task_queues:95:5)
requestData {}
C:\Users\shubh\pariksa\mint\tests\submissionid.test.ts
2.335s
GET /submissions
should return submissions successfully
passed
0.032s
GET /submissions
should return 404 if org not found
passed
0.001s
POST /submissions
should create a submission successfully
passed
0.004s
POST /submissions
should return 400 for known error thrown by service
passed
0.001s
POST /submissions
should return 400 for invalid submission schema
passed
0.001s
GET /submissions/[submissionId]
should return a single submission successfully
passed
0.007s
GET /submissions/[submissionId]
should return 404 if submission not found
passed
0.002s
GET /submissions/[submissionId]
should return 400 for invalid input
passed
0.001s
Console Log
    at C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:22:13
+    at processTicksAndRejections (node:internal/process/task_queues:95:5)
requestData {}
C:\Users\shubh\pariksa\mint\tests\submissionid.test.ts
2.733s
GET /submissions
should return submissions successfully
passed
0.058s
GET /submissions
should return 404 if org not found
passed
0.001s
POST /submissions
should create a submission successfully
passed
0.003s
POST /submissions
should return 400 for known error thrown by service
passed
0.001s
POST /submissions
should return 400 for invalid submission schema
passed
0.002s
GET /submissions/[submissionId]
should return a single submission successfully
passed
0.007s
GET /submissions/[submissionId]
should return 404 if submission not found
passed
0.002s
GET /submissions/[submissionId]
should return 400 for invalid input
passed
0.001s
Console Log
    at C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:22:13
     at Generator.next (<anonymous>)
     at fulfilled (C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:38:58)
     at processTicksAndRejections (node:internal/process/task_queues:95:5)
orgid= 1
    at C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:25:13
@@ -382,4 +382,4 @@
 }
    at C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:75:13
     at Generator.next (<anonymous>)
     at fulfilled (C:\Users\shubh\pariksa\mint\app\api\orgs\[orgId]\submissions\route.ts:38:58)
-    at processTicksAndRejections (node:internal/process/task_queues:95:5)
requestData {}
C:\Users\shubh\pariksa\mint\tests\health.test.ts
2.386s
GET /api/health
should return 200 if DB connection is healthy
passed
0.017s
GET /api/health
should return 503 if DB connection fails
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\login.test.ts
2.508s
POST /api/login
should return user data on valid credentials
passed
0.014s
POST /api/login
should return 401 if user not found
passed
0.001s
POST /api/login
should return 401 on invalid password
passed
0.001s
POST /api/login
should return 400 on invalid request
passed
0.001s
\ No newline at end of file + at processTicksAndRejections (node:internal/process/task_queues:95:5)
requestData {}
C:\Users\shubh\pariksa\mint\tests\health.test.ts
2.793s
GET /api/health
should return 200 if DB connection is healthy
passed
0.018s
GET /api/health
should return 503 if DB connection fails
passed
0.002s
C:\Users\shubh\pariksa\mint\tests\login.test.ts
2.893s
POST /api/login
should return user data on valid credentials
passed
0.013s
POST /api/login
should return 401 if user not found
passed
0.001s
POST /api/login
should return 401 on invalid password
passed
0.001s
POST /api/login
should return 400 on invalid request
passed
0.001s
C:\Users\shubh\pariksa\mint\tests\problems.test.ts
0.724s
Contest Problems API Routes > POST endpoint - Add Problem to Contest
should successfully add a problem to a contest
passed
0.005s
Contest Problems API Routes > POST endpoint - Add Problem to Contest
should handle case when order is not provided
passed
0.001s
Contest Problems API Routes > POST endpoint - Add Problem to Contest
should return 400 for validation errors
passed
0.001s
Contest Problems API Routes > POST endpoint - Add Problem to Contest
should return 404 when organization is not found
passed
0.001s
Contest Problems API Routes > POST endpoint - Add Problem to Contest
should return 404 when contest is not found
passed
0.001s
Contest Problems API Routes > POST endpoint - Add Problem to Contest
should return 404 when problem is not found
passed
0.001s
Contest Problems API Routes > POST endpoint - Add Problem to Contest
should return 409 when problem is already added to contest
passed
0.001s
Contest Problems API Routes > POST endpoint - Add Problem to Contest
should return 500 for unexpected errors
passed
0.001s
Contest Problems API Routes > GET endpoint - Fetch Contest Problems
should successfully fetch problems for a contest
passed
0.001s
Contest Problems API Routes > GET endpoint - Fetch Contest Problems
should return 400 for validation errors
passed
0.001s
Contest Problems API Routes > GET endpoint - Fetch Contest Problems
should return 404 when organization is not found
passed
0.001s
Contest Problems API Routes > GET endpoint - Fetch Contest Problems
should return 404 when contest is not found
passed
0.001s
Contest Problems API Routes > GET endpoint - Fetch Contest Problems
should return 500 for unexpected errors
passed
Contest Problems API Routes > DELETE endpoint - Remove Problem from Contest
should successfully remove a problem from a contest
passed
0.002s
Contest Problems API Routes > DELETE endpoint - Remove Problem from Contest
should return 400 for validation errors
passed
Contest Problems API Routes > DELETE endpoint - Remove Problem from Contest
should return 404 when organization is not found
passed
Contest Problems API Routes > DELETE endpoint - Remove Problem from Contest
should return 404 when contest is not found
passed
0.001s
Contest Problems API Routes > DELETE endpoint - Remove Problem from Contest
should return 404 when problem is not found
passed
0.001s
Contest Problems API Routes > DELETE endpoint - Remove Problem from Contest
should return 500 for unexpected errors
passed
\ No newline at end of file diff --git a/tests/problems._test.ts b/tests/problems._test.ts deleted file mode 100644 index 1311f7b..0000000 --- a/tests/problems._test.ts +++ /dev/null @@ -1,111 +0,0 @@ -// tests/problems.test.ts -import { - POST, - GET, - DELETE, -} from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/route"; -import * as problemService from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/service"; -import { getOrgIdFromNameId, getContestIdFromNameId } from "@/app/api/service"; -import { getProblemIdFromCode } from "@/app/api/orgs/[orgId]/problems/service"; - -import { NextRequest } from "next/server"; - -jest.mock( - "@/app/api/orgs/[orgId]/contests/[contestId]/problems/service", - () => ({ - addProblemToContest: jest.fn(), - getContestProblems: jest.fn(), - removeProblemFromContest: jest.fn(), - }), -); - -jest.mock("@/app/api/service", () => ({ - getOrgIdFromNameId: jest.fn(), - getContestIdFromNameId: jest.fn(), -})); - -jest.mock("@/app/api/orgs/[orgId]/contests/problems/service", () => ({ - getProblemIdFromCode: jest.fn(), -})); - -jest.mock("next/server", () => ({ - NextResponse: { - json: jest.fn((data, init) => ({ data, status: init?.status || 200 })), - }, -})); - -const mockOrgId = 1; -const mockContestId = 2; -const mockProblemId = 3; -const mockProblemCode = "mock-problem"; -const validParams = { orgId: "test-org", contestId: "test-contest" }; -const createMockRequest = (body: any): NextRequest => - ({ json: async () => body }) as unknown as NextRequest; - -describe("POST /problems", () => { - beforeEach(jest.clearAllMocks); - - it("should add a problem successfully", async () => { - (getOrgIdFromNameId as jest.Mock).mockResolvedValue(mockOrgId); - (getContestIdFromNameId as jest.Mock).mockResolvedValue(mockContestId); - (getProblemIdFromCode as jest.Mock).mockResolvedValue(mockProblemId); - (problemService.addProblemToContest as jest.Mock).mockResolvedValue({ - id: mockProblemId, - }); - - const req = createMockRequest({ problemCode: mockProblemCode }); - const res = await POST(req, { params: validParams }); - - expect(res.status).toBe(201); - expect(res.data).toEqual({ id: mockProblemId }); - }); - - it("should return 409 if problem already added", async () => { - (getOrgIdFromNameId as jest.Mock).mockResolvedValue(mockOrgId); - (getContestIdFromNameId as jest.Mock).mockResolvedValue(mockContestId); - (getProblemIdFromCode as jest.Mock).mockResolvedValue(mockProblemId); - (problemService.addProblemToContest as jest.Mock).mockRejectedValue( - new Error("Problem already added to contest"), - ); - - const req = createMockRequest({ problemCode: mockProblemCode }); - const res = await POST(req, { params: validParams }); - expect(res.status).toBe(409); - expect(res.data).toEqual({ error: "Problem already added to contest" }); - }); -}); - -describe("GET /problems", () => { - beforeEach(jest.clearAllMocks); - - it("should return problems successfully", async () => { - (getOrgIdFromNameId as jest.Mock).mockResolvedValue(mockOrgId); - (getContestIdFromNameId as jest.Mock).mockResolvedValue(mockContestId); - (problemService.getContestProblems as jest.Mock).mockResolvedValue([ - { id: mockProblemId }, - ]); - - const res = await GET({} as unknown as NextRequest, { - params: validParams, - }); - expect(res.status).toBe(200); - expect(res.data).toEqual([{ id: mockProblemId }]); - }); -}); - -describe("DELETE /problems", () => { - beforeEach(jest.clearAllMocks); - - it("should remove a problem successfully", async () => { - const deleteParams = { ...validParams, problemId: mockProblemCode }; - (getOrgIdFromNameId as jest.Mock).mockResolvedValue(mockOrgId); - (getContestIdFromNameId as jest.Mock).mockResolvedValue(mockContestId); - (problemService.removeProblemFromContest as jest.Mock).mockResolvedValue( - undefined, - ); - - const req = createMockRequest({}); - const res = await DELETE(req, { params: deleteParams }); - expect(res.status).toBe(204); - }); -}); diff --git a/tests/problems.test.ts b/tests/problems.test.ts new file mode 100644 index 0000000..cc882be --- /dev/null +++ b/tests/problems.test.ts @@ -0,0 +1,645 @@ +// // tests/problems.test.ts +// import { +// POST, +// GET, +// DELETE, +// } from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/route"; +// import * as problemService from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/service"; +// import { getOrgIdFromNameId, getContestIdFromNameId } from "@/app/api/service"; +// import { getProblemIdFromCode } from "@/app/api/orgs/[orgId]/problems/service"; + +// import { NextRequest } from "next/server"; + +// jest.mock( +// "@/app/api/orgs/[orgId]/contests/[contestId]/problems/service", +// () => ({ +// addProblemToContest: jest.fn(), +// getContestProblems: jest.fn(), +// removeProblemFromContest: jest.fn(), +// }), +// ); + +// jest.mock("@/app/api/service", () => ({ +// getOrgIdFromNameId: jest.fn(), +// getContestIdFromNameId: jest.fn(), +// })); + +// jest.mock("@/app/api/orgs/[orgId]/contests/problems/service", () => ({ +// getProblemIdFromCode: jest.fn(), +// })); + +// jest.mock("next/server", () => ({ +// NextResponse: { +// json: jest.fn((data, init) => ({ data, status: init?.status || 200 })), +// }, +// })); + +// const mockOrgId = 1; +// const mockContestId = 2; +// const mockProblemId = 3; +// const mockProblemCode = "mock-problem"; +// const validParams = { orgId: "test-org", contestId: "test-contest" }; +// const createMockRequest = (body: any): NextRequest => +// ({ json: async () => body }) as unknown as NextRequest; + +// describe("POST /problems", () => { +// beforeEach(jest.clearAllMocks); + +// it("should add a problem successfully", async () => { +// (getOrgIdFromNameId as jest.Mock).mockResolvedValue(mockOrgId); +// (getContestIdFromNameId as jest.Mock).mockResolvedValue(mockContestId); +// (getProblemIdFromCode as jest.Mock).mockResolvedValue(mockProblemId); +// (problemService.addProblemToContest as jest.Mock).mockResolvedValue({ +// id: mockProblemId, +// }); + +// const req = createMockRequest({ problemCode: mockProblemCode }); +// const res = await POST(req, { params: validParams }); + +// expect(res.status).toBe(201); +// expect(res.data).toEqual({ id: mockProblemId }); +// }); + +// it("should return 409 if problem already added", async () => { +// (getOrgIdFromNameId as jest.Mock).mockResolvedValue(mockOrgId); +// (getContestIdFromNameId as jest.Mock).mockResolvedValue(mockContestId); +// (getProblemIdFromCode as jest.Mock).mockResolvedValue(mockProblemId); +// (problemService.addProblemToContest as jest.Mock).mockRejectedValue( +// new Error("Problem already added to contest"), +// ); + +// const req = createMockRequest({ problemCode: mockProblemCode }); +// const res = await POST(req, { params: validParams }); +// expect(res.status).toBe(409); +// expect(res.data).toEqual({ error: "Problem already added to contest" }); +// }); +// }); + +// describe("GET /problems", () => { +// beforeEach(jest.clearAllMocks); + +// it("should return problems successfully", async () => { +// (getOrgIdFromNameId as jest.Mock).mockResolvedValue(mockOrgId); +// (getContestIdFromNameId as jest.Mock).mockResolvedValue(mockContestId); +// (problemService.getContestProblems as jest.Mock).mockResolvedValue([ +// { id: mockProblemId }, +// ]); + +// const res = await GET({} as unknown as NextRequest, { +// params: validParams, +// }); +// expect(res.status).toBe(200); +// expect(res.data).toEqual([{ id: mockProblemId }]); +// }); +// }); + +// describe("DELETE /problems", () => { +// beforeEach(jest.clearAllMocks); + +// it("should remove a problem successfully", async () => { +// const deleteParams = { ...validParams, problemId: mockProblemCode }; +// (getOrgIdFromNameId as jest.Mock).mockResolvedValue(mockOrgId); +// (getContestIdFromNameId as jest.Mock).mockResolvedValue(mockContestId); +// (problemService.removeProblemFromContest as jest.Mock).mockResolvedValue( +// undefined, +// ); + +// const req = createMockRequest({}); +// const res = await DELETE(req, { params: deleteParams }); +// expect(res.status).toBe(204); +// }); +// }); + + + + +import { NextRequest, NextResponse } from "next/server"; +import { z } from "zod"; +import * as problemService from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/service"; +import { getOrgIdFromNameId, getContestIdFromNameId } from "@/app/api/service"; +import { addProblemSchema, NameIdSchema } from "@/lib/validations"; +import { getProblemIdFromCode } from "@/app/api/orgs/[orgId]/problems/service"; +import { POST, GET, DELETE } from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/route"; + +// Mock the imported modules +jest.mock("next/server", () => ({ + NextRequest: jest.fn(), + NextResponse: { + json: jest.fn((data, options) => ({ data, options })), + }, +})); + +jest.mock("zod", () => { + const actual = jest.requireActual("zod"); + return { + ...actual, + ZodError: class MockZodError extends Error { + errors: any[]; + constructor(errors: any[]) { + super("Validation Error"); + this.errors = errors; + this.name = "ZodError"; + } + }, + }; +}); + +jest.mock("@/app/api/orgs/[orgId]/contests/[contestId]/problems/service", () => ({ + addProblemToContest: jest.fn(), + getContestProblems: jest.fn(), + removeProblemFromContest: jest.fn(), +})); + +jest.mock("@/app/api/service", () => ({ + getOrgIdFromNameId: jest.fn(), + getContestIdFromNameId: jest.fn(), +})); + +jest.mock("@/lib/validations", () => ({ + addProblemSchema: { + parse: jest.fn(), + }, + NameIdSchema: { + parse: jest.fn((value) => value), + }, +})); + +jest.mock("@/app/api/orgs/[orgId]/problems/service", () => ({ + getProblemIdFromCode: jest.fn(), +})); + +describe("Contest Problems API Routes", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + describe("POST endpoint - Add Problem to Contest", () => { + const mockParams = { + orgId: "org-abc", + contestId: "contest-123", + }; + + const mockRequestBody = { + problemCode: "PROB-123", + order: 1, + }; + + const mockOrgId = 1; + const mockContestId = 2; + const mockProblemId = 3; + const mockAddedProblem = { + id: 100, + contestId: mockContestId, + problemId: mockProblemId, + order: 1, + }; + + beforeEach(() => { + // Default mock implementations + const mockRequest = { + json: jest.fn().mockResolvedValue(mockRequestBody), + }; + Object.defineProperty(NextRequest, "prototype", { value: mockRequest }); + + getOrgIdFromNameId.mockResolvedValue(mockOrgId); + getContestIdFromNameId.mockResolvedValue(mockContestId); + getProblemIdFromCode.mockResolvedValue(mockProblemId); + addProblemSchema.parse.mockReturnValue(mockRequestBody); + problemService.addProblemToContest.mockResolvedValue(mockAddedProblem); + }); + + it("should successfully add a problem to a contest", async () => { + // Call the function + const result = await POST(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.orgId); + expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.contestId); + expect(getOrgIdFromNameId).toHaveBeenCalledWith(mockParams.orgId); + expect(getContestIdFromNameId).toHaveBeenCalledWith(mockOrgId, mockParams.contestId); + expect(addProblemSchema.parse).toHaveBeenCalledWith(mockRequestBody); + expect(getProblemIdFromCode).toHaveBeenCalledWith(mockOrgId, mockRequestBody.problemCode); + expect(problemService.addProblemToContest).toHaveBeenCalledWith( + mockContestId, + mockProblemId, + mockRequestBody.order + ); + expect(NextResponse.json).toHaveBeenCalledWith(mockAddedProblem, { status: 201 }); + expect(result).toEqual({ + data: mockAddedProblem, + options: { status: 201 }, + }); + }); + + it("should handle case when order is not provided", async () => { + // Setup + const bodyWithoutOrder = { problemCode: "PROB-123" }; + NextRequest.prototype.json.mockResolvedValueOnce(bodyWithoutOrder); + addProblemSchema.parse.mockReturnValueOnce(bodyWithoutOrder); + + // Call the function + await POST(new NextRequest(), { params: mockParams }); + + // Assertions + expect(problemService.addProblemToContest).toHaveBeenCalledWith( + mockContestId, + mockProblemId, + 0 // Default order value + ); + }); + + it("should return 400 for validation errors", async () => { + // Setup validation error + const validationErrors = [{ path: ["problemCode"], message: "Required" }]; + const zodError = new z.ZodError(validationErrors); + addProblemSchema.parse.mockImplementation(() => { + throw zodError; + }); + + // Call the function + const result = await POST(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: validationErrors }, + { status: 400 } + ); + expect(result).toEqual({ + data: { error: validationErrors }, + options: { status: 400 }, + }); + }); + + it("should return 404 when organization is not found", async () => { + // Setup + const notFoundError = new Error("Organization not found"); + getOrgIdFromNameId.mockRejectedValue(notFoundError); + + // Call the function + const result = await POST(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Organization not found" }, + { status: 404 } + ); + expect(result).toEqual({ + data: { error: "Organization not found" }, + options: { status: 404 }, + }); + }); + + it("should return 404 when contest is not found", async () => { + // Setup + const notFoundError = new Error("Contest not found"); + getContestIdFromNameId.mockRejectedValue(notFoundError); + + // Call the function + const result = await POST(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Contest not found" }, + { status: 404 } + ); + expect(result).toEqual({ + data: { error: "Contest not found" }, + options: { status: 404 }, + }); + }); + + it("should return 404 when problem is not found", async () => { + // Setup + const notFoundError = new Error("Problem not found"); + getProblemIdFromCode.mockRejectedValue(notFoundError); + + // Call the function + const result = await POST(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Problem not found" }, + { status: 404 } + ); + expect(result).toEqual({ + data: { error: "Problem not found" }, + options: { status: 404 }, + }); + }); + + it("should return 409 when problem is already added to contest", async () => { + // Setup + const conflictError = new Error("Problem already added to contest"); + problemService.addProblemToContest.mockRejectedValue(conflictError); + + // Call the function + const result = await POST(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Problem already added to contest" }, + { status: 409 } + ); + expect(result).toEqual({ + data: { error: "Problem already added to contest" }, + options: { status: 409 }, + }); + }); + + it("should return 500 for unexpected errors", async () => { + // Setup + const unexpectedError = new Error("Unexpected database error"); + problemService.addProblemToContest.mockRejectedValue(unexpectedError); + + // Call the function + const result = await POST(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Failed to add problem to contest" }, + { status: 500 } + ); + expect(result).toEqual({ + data: { error: "Failed to add problem to contest" }, + options: { status: 500 }, + }); + }); + }); + + describe("GET endpoint - Fetch Contest Problems", () => { + const mockParams = { + orgId: "org-abc", + contestId: "contest-123", + }; + + const mockOrgId = 1; + const mockContestId = 2; + const mockProblems = [ + { + id: 100, + contestId: 2, + problemId: 3, + order: 1, + problem: { id: 3, code: "PROB-A", title: "Problem A" }, + }, + { + id: 101, + contestId: 2, + problemId: 4, + order: 2, + problem: { id: 4, code: "PROB-B", title: "Problem B" }, + }, + ]; + + beforeEach(() => { + getOrgIdFromNameId.mockResolvedValue(mockOrgId); + getContestIdFromNameId.mockResolvedValue(mockContestId); + problemService.getContestProblems.mockResolvedValue(mockProblems); + }); + + it("should successfully fetch problems for a contest", async () => { + // Call the function + const result = await GET(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.orgId); + expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.contestId); + expect(getOrgIdFromNameId).toHaveBeenCalledWith(mockParams.orgId); + expect(getContestIdFromNameId).toHaveBeenCalledWith(mockOrgId, mockParams.contestId); + expect(problemService.getContestProblems).toHaveBeenCalledWith(mockContestId); + expect(NextResponse.json).toHaveBeenCalledWith(mockProblems); + expect(result).toEqual({ + data: mockProblems, + options: undefined, + }); + }); + + it("should return 400 for validation errors", async () => { + // Setup validation error + const validationErrors = [{ path: ["orgId"], message: "Invalid format" }]; + const zodError = new z.ZodError(validationErrors); + NameIdSchema.parse.mockImplementationOnce(() => { + throw zodError; + }); + + // Call the function + const result = await GET(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: validationErrors }, + { status: 400 } + ); + expect(result).toEqual({ + data: { error: validationErrors }, + options: { status: 400 }, + }); + }); + + it("should return 404 when organization is not found", async () => { + // Setup + const notFoundError = new Error("Organization not found"); + getOrgIdFromNameId.mockRejectedValue(notFoundError); + + // Call the function + const result = await GET(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Organization not found" }, + { status: 404 } + ); + expect(result).toEqual({ + data: { error: "Organization not found" }, + options: { status: 404 }, + }); + }); + + it("should return 404 when contest is not found", async () => { + // Setup + const notFoundError = new Error("Contest not found"); + getContestIdFromNameId.mockRejectedValue(notFoundError); + + // Call the function + const result = await GET(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Contest not found" }, + { status: 404 } + ); + expect(result).toEqual({ + data: { error: "Contest not found" }, + options: { status: 404 }, + }); + }); + + it("should return 500 for unexpected errors", async () => { + // Setup + const unexpectedError = new Error("Unexpected database error"); + problemService.getContestProblems.mockRejectedValue(unexpectedError); + + // Call the function + const result = await GET(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Failed to fetch contest problems" }, + { status: 500 } + ); + expect(result).toEqual({ + data: { error: "Failed to fetch contest problems" }, + options: { status: 500 }, + }); + }); + }); + + describe("DELETE endpoint - Remove Problem from Contest", () => { + const mockParams = { + orgId: "org-abc", + contestId: "contest-123", + problemId: "PROB-A", + }; + + const mockOrgId = 1; + const mockContestId = 2; + + beforeEach(() => { + getOrgIdFromNameId.mockResolvedValue(mockOrgId); + getContestIdFromNameId.mockResolvedValue(mockContestId); + problemService.removeProblemFromContest.mockResolvedValue(undefined); + + // Mock the Response constructor + global.Response = jest.fn().mockImplementation((body, init) => ({ + body, + init, + status: init?.status, + })); + }); + + it("should successfully remove a problem from a contest", async () => { + // Call the function + const result = await DELETE(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.orgId); + expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.contestId); + expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.problemId); + expect(getOrgIdFromNameId).toHaveBeenCalledWith(mockParams.orgId); + expect(getContestIdFromNameId).toHaveBeenCalledWith(mockOrgId, mockParams.contestId); + expect(problemService.removeProblemFromContest).toHaveBeenCalledWith( + mockOrgId, + mockContestId, + mockParams.problemId + ); + expect(Response).toHaveBeenCalledWith(null, { status: 204 }); + expect(result).toEqual({ + body: null, + init: { status: 204 }, + status: 204, + }); + }); + + it("should return 400 for validation errors", async () => { + // Setup validation error + const validationErrors = [{ path: ["problemId"], message: "Invalid format" }]; + const zodError = new z.ZodError(validationErrors); + NameIdSchema.parse.mockImplementationOnce(() => { + return mockParams.orgId; + }).mockImplementationOnce(() => { + return mockParams.contestId; + }).mockImplementationOnce(() => { + throw zodError; + }); + + // Call the function + const result = await DELETE(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: validationErrors }, + { status: 400 } + ); + expect(result).toEqual({ + data: { error: validationErrors }, + options: { status: 400 }, + }); + }); + + it("should return 404 when organization is not found", async () => { + // Setup + const notFoundError = new Error("Organization not found"); + getOrgIdFromNameId.mockRejectedValue(notFoundError); + + // Call the function + const result = await DELETE(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Organization not found" }, + { status: 404 } + ); + expect(result).toEqual({ + data: { error: "Organization not found" }, + options: { status: 404 }, + }); + }); + + it("should return 404 when contest is not found", async () => { + // Setup + const notFoundError = new Error("Contest not found"); + getContestIdFromNameId.mockRejectedValue(notFoundError); + + // Call the function + const result = await DELETE(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Contest not found" }, + { status: 404 } + ); + expect(result).toEqual({ + data: { error: "Contest not found" }, + options: { status: 404 }, + }); + }); + + it("should return 404 when problem is not found", async () => { + // Setup + const notFoundError = new Error("Problem not found"); + problemService.removeProblemFromContest.mockRejectedValue(notFoundError); + + // Call the function + const result = await DELETE(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Problem not found" }, + { status: 404 } + ); + expect(result).toEqual({ + data: { error: "Problem not found" }, + options: { status: 404 }, + }); + }); + + it("should return 500 for unexpected errors", async () => { + // Setup + const unexpectedError = new Error("Unexpected database error"); + problemService.removeProblemFromContest.mockRejectedValue(unexpectedError); + + // Call the function + const result = await DELETE(new NextRequest(), { params: mockParams }); + + // Assertions + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Failed to remove problem from contest" }, + { status: 500 } + ); + expect(result).toEqual({ + data: { error: "Failed to remove problem from contest" }, + options: { status: 500 }, + }); + }); + }); +}); \ No newline at end of file diff --git a/tests/register.test.ts b/tests/register.test.ts new file mode 100644 index 0000000..fea85a6 --- /dev/null +++ b/tests/register.test.ts @@ -0,0 +1,520 @@ +// import { jest } from "@jest/globals"; + +// // Mock Next.js modules +// jest.mock("next/server", () => ({ +// NextResponse: { +// json: jest.fn((data, options) => { +// return { +// data, +// status: options?.status || 200, +// headers: new Map(), +// }; +// }), +// }, +// })); + +// // Mocked user used inside db mock must be defined before mocks +// const mockUser = { +// id: "user-123", +// email: "newuser@example.com", +// name: "New User", +// nameId: "newuser", +// hashedPassword: "hashed_password", +// createdAt: new Date(), +// updatedAt: new Date(), +// }; +// const findFirstMock = jest.fn(); +// const insertReturningMock = jest.fn(() => Promise.resolve([mockUser])); +// const insertValuesMock = jest.fn(() => ({ returning: insertReturningMock })); +// const insertMock = jest.fn(() => ({ values: insertValuesMock })); + +// jest.mock("@/db/drizzle", () => ({ +// db: { +// query: { +// users: { +// findFirst: findFirstMock, +// }, +// }, +// insert: insertMock, +// }, +// })); +// // expect(findFirstMock).toHaveBeenCalled(); +// // expect(insertMock).toHaveBeenCalled(); + +// jest.mock("@/lib/password", () => ({ +// hashPassword: jest.fn(), +// })); + +// jest.mock("@/lib/username", () => ({ +// generateUsername: jest.fn(), +// })); + +// jest.mock("@/lib/server/session", () => ({ +// generateSessionToken: jest.fn(), +// createSession: jest.fn(), +// })); + +// jest.mock("@/lib/server/cookies", () => ({ +// setSessionTokenCookie: jest.fn(), +// })); + +// import { NextRequest } from "next/server"; +// import { db } from "@/db/drizzle"; +// import { hashPassword } from "@/lib/password"; +// import { generateUsername } from "@/lib/username"; +// import { generateSessionToken, createSession } from "@/lib/server/session"; +// import { setSessionTokenCookie } from "@/lib/server/cookies"; +// import { POST } from "@/app/api/auth/register/route"; + +// describe("POST /api/auth/register", () => { +// beforeEach(() => { +// jest.clearAllMocks(); +// }); + +// it("should register a new user successfully", async () => { +// const requestData = { +// email: "newuser@example.com", +// password: "Password123!", +// name: "New User", +// }; + +// const mockSession = { +// id: "session-123", +// userId: "user-123", +// token: "token-123", +// expiresAt: new Date(Date.now() + 86400000), +// }; + +// (db.query.users.findFirst as jest.Mock).mockResolvedValue(null); +// (hashPassword as jest.Mock).mockResolvedValue("hashed_password"); +// (generateUsername as jest.Mock).mockResolvedValue("newuser"); +// mockReturning.mockResolvedValue([mockUser]); +// (generateSessionToken as jest.Mock).mockReturnValue("token-123"); +// (createSession as jest.Mock).mockResolvedValue(mockSession); +// (setSessionTokenCookie as jest.Mock).mockResolvedValue(undefined); + +// const request = { +// json: jest.fn().mockResolvedValue(requestData), +// } as unknown as NextRequest; + +// const response = await POST(request); + +// expect(db.query.users.findFirst).toHaveBeenCalled(); +// expect(hashPassword).toHaveBeenCalledWith("Password123!"); +// expect(generateUsername).toHaveBeenCalledWith("newuser@example.com"); +// expect(db.insert).toHaveBeenCalled(); +// expect(generateSessionToken).toHaveBeenCalled(); +// expect(createSession).toHaveBeenCalled(); +// expect(setSessionTokenCookie).toHaveBeenCalled(); + +// expect(response.data).toEqual({ +// _id: "user-123", +// email: "newuser@example.com", +// name: "New User", +// nameId: "newuser", +// }); +// expect(response.status).toBe(200); +// }); + +// it("should return 400 if email already exists", async () => { +// const requestData = { +// email: "existing@example.com", +// password: "Password123!", +// name: "Existing User", +// }; + +// const mockExistingUser = { ...mockUser, email: "existing@example.com" }; + +// (db.query.users.findFirst as jest.Mock).mockResolvedValue(mockExistingUser); + +// const request = { +// json: jest.fn().mockResolvedValue(requestData), +// } as unknown as NextRequest; + +// const response = await POST(request); + +// expect(db.query.users.findFirst).toHaveBeenCalled(); +// expect(hashPassword).not.toHaveBeenCalled(); +// expect(generateUsername).not.toHaveBeenCalled(); +// expect(db.insert).not.toHaveBeenCalled(); +// expect(response.data).toEqual({ error: "Email already exists" }); +// expect(response.status).toBe(400); +// }); + +// it("should return 400 on validation error", async () => { +// const request = { +// json: jest.fn().mockResolvedValue({ +// email: "invalid-email", +// password: "123", +// name: "", +// }), +// } as unknown as NextRequest; + +// const response = await POST(request); + +// expect(response.data).toEqual({ error: "Invalid request" }); +// expect(response.status).toBe(400); +// }); + +// it("should handle database errors", async () => { +// const requestData = { +// email: "newuser@example.com", +// password: "Password123!", +// name: "New User", +// }; + +// (db.query.users.findFirst as jest.Mock).mockResolvedValue(null); +// (hashPassword as jest.Mock).mockResolvedValue("hashed_password"); +// (generateUsername as jest.Mock).mockResolvedValue("newuser"); +// mockReturning.mockRejectedValue(new Error("Database error")); + +// const request = { +// json: jest.fn().mockResolvedValue(requestData), +// } as unknown as NextRequest; + +// const response = await POST(request); + +// expect(response.data).toEqual({ error: "Invalid request" }); +// expect(response.status).toBe(400); +// }); + +// it("should handle request parsing errors", async () => { +// const request = { +// json: jest.fn().mockRejectedValue(new Error("Invalid JSON")), +// } as unknown as NextRequest; + +// const response = await POST(request); + +// expect(response.data).toEqual({ error: "Invalid request" }); +// expect(response.status).toBe(400); +// }); +// }); + + + + + + + + + + + +import { NextRequest, NextResponse } from "next/server"; +import { POST } from "@/app/api/auth/register/route"; // Assuming this file is in the same directory as the route +import { registerSchema } from "@/lib/validations"; +import { db } from "@/db/drizzle"; +import { users } from "@/db/schema"; +import { eq } from "drizzle-orm"; +import { generateSessionToken, createSession } from "@/lib/server/session"; +import { setSessionTokenCookie } from "@/lib/server/cookies"; +import { hashPassword } from "@/lib/password"; +import { generateUsername } from "@/lib/username"; + +// Mock the imported modules +jest.mock("next/server", () => ({ + NextRequest: jest.fn(), + NextResponse: { + json: jest.fn((data, options) => ({ data, options })), + }, +})); + +jest.mock("@/lib/validations", () => ({ + registerSchema: { + parse: jest.fn(), + }, +})); + +jest.mock("@/db/drizzle", () => ({ + db: { + query: { + users: { + findFirst: jest.fn(), + }, + }, + insert: jest.fn().mockReturnThis(), + values: jest.fn().mockReturnThis(), + returning: jest.fn(), + }, +})); + +jest.mock("@/db/schema", () => ({ + users: { + email: "email", + }, +})); + +jest.mock("drizzle-orm", () => ({ + eq: jest.fn(), +})); + +jest.mock("@/lib/server/session", () => ({ + generateSessionToken: jest.fn(), + createSession: jest.fn(), +})); + +jest.mock("@/lib/server/cookies", () => ({ + setSessionTokenCookie: jest.fn(), +})); + +jest.mock("@/lib/password", () => ({ + hashPassword: jest.fn(), +})); + +jest.mock("@/lib/username", () => ({ + generateUsername: jest.fn(), +})); + +describe("User Registration API Route", () => { + const mockRequestBody = { + email: "test@example.com", + password: "Password123!", + name: "Test User", + }; + + const mockUser = { + id: "user-123", + email: "test@example.com", + name: "Test User", + nameId: "test-user", + }; + + const mockToken = "mock-session-token"; + const mockSession = { + id: "session-123", + userId: mockUser.id, + expiresAt: new Date(Date.now() + 1000 * 60 * 60 * 24), // 1 day from now + }; + + beforeEach(() => { + jest.clearAllMocks(); + + // Default mock implementations + const mockRequest = { + json: jest.fn().mockResolvedValue(mockRequestBody), + }; + Object.defineProperty(NextRequest, "prototype", { value: mockRequest }); + + registerSchema.parse.mockReturnValue(mockRequestBody); + db.query.users.findFirst.mockResolvedValue(null); // No existing user by default + eq.mockReturnValue({ operator: "=", field: "email", value: mockRequestBody.email }); + hashPassword.mockResolvedValue("hashed-password"); + generateUsername.mockResolvedValue(mockUser.nameId); + db.returning.mockResolvedValue([mockUser]); + generateSessionToken.mockReturnValue(mockToken); + createSession.mockResolvedValue(mockSession); + setSessionTokenCookie.mockResolvedValue(undefined); + }); + + it("should successfully register a new user", async () => { + // Call the function + const result = await POST(new NextRequest()); + + // Assertions + expect(registerSchema.parse).toHaveBeenCalledWith(mockRequestBody); + expect(db.query.users.findFirst).toHaveBeenCalledWith({ + where: expect.anything(), // We mock eq so we can't check its exact value + }); + expect(eq).toHaveBeenCalledWith(users.email, mockRequestBody.email); + expect(hashPassword).toHaveBeenCalledWith(mockRequestBody.password); + expect(generateUsername).toHaveBeenCalledWith(mockRequestBody.email); + + expect(db.insert).toHaveBeenCalledTimes(1); + expect(db.values).toHaveBeenCalledWith({ + email: mockRequestBody.email, + hashedPassword: "hashed-password", + name: mockRequestBody.name, + nameId: mockUser.nameId, + }); + expect(db.returning).toHaveBeenCalledTimes(1); + + expect(generateSessionToken).toHaveBeenCalledTimes(1); + expect(createSession).toHaveBeenCalledWith(mockToken, mockUser.id); + expect(setSessionTokenCookie).toHaveBeenCalledWith(mockToken, mockSession.expiresAt); + + expect(NextResponse.json).toHaveBeenCalledWith({ + _id: mockUser.id, + email: mockUser.email, + name: mockUser.name, + nameId: mockUser.nameId, + }); + + expect(result).toEqual({ + data: { + _id: mockUser.id, + email: mockUser.email, + name: mockUser.name, + nameId: mockUser.nameId, + }, + options: undefined, + }); + }); + + it("should return 400 if email already exists", async () => { + // Setup existing user + db.query.users.findFirst.mockResolvedValue({ + id: "existing-user-123", + email: mockRequestBody.email, + }); + + // Call the function + const result = await POST(new NextRequest()); + + // Assertions + expect(db.query.users.findFirst).toHaveBeenCalled(); + expect(db.insert).not.toHaveBeenCalled(); + expect(generateSessionToken).not.toHaveBeenCalled(); + expect(createSession).not.toHaveBeenCalled(); + expect(setSessionTokenCookie).not.toHaveBeenCalled(); + + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Email already exists" }, + { status: 400 } + ); + + expect(result).toEqual({ + data: { error: "Email already exists" }, + options: { status: 400 }, + }); + }); + + it("should return 400 if validation fails", async () => { + // Setup validation error + const validationError = new Error("Validation failed"); + registerSchema.parse.mockImplementation(() => { + throw validationError; + }); + + // Call the function + const result = await POST(new NextRequest()); + + // Assertions + expect(registerSchema.parse).toHaveBeenCalled(); + expect(db.query.users.findFirst).not.toHaveBeenCalled(); + expect(db.insert).not.toHaveBeenCalled(); + + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Invalid request" }, + { status: 400 } + ); + + expect(result).toEqual({ + data: { error: "Invalid request" }, + options: { status: 400 }, + }); + }); + + it("should return 400 if password hashing fails", async () => { + // Setup password hashing error + const hashingError = new Error("Hashing failed"); + hashPassword.mockRejectedValue(hashingError); + + // Call the function + const result = await POST(new NextRequest()); + + // Assertions + expect(hashPassword).toHaveBeenCalled(); + expect(db.insert).not.toHaveBeenCalled(); + + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Invalid request" }, + { status: 400 } + ); + + expect(result).toEqual({ + data: { error: "Invalid request" }, + options: { status: 400 }, + }); + }); + + it("should return 400 if username generation fails", async () => { + // Setup username generation error + const usernameError = new Error("Username generation failed"); + generateUsername.mockRejectedValue(usernameError); + + // Call the function + const result = await POST(new NextRequest()); + + // Assertions + expect(generateUsername).toHaveBeenCalled(); + expect(db.insert).not.toHaveBeenCalled(); + + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Invalid request" }, + { status: 400 } + ); + + expect(result).toEqual({ + data: { error: "Invalid request" }, + options: { status: 400 }, + }); + }); + + it("should return 400 if database insert fails", async () => { + // Setup database error + const dbError = new Error("Database error"); + db.returning.mockRejectedValue(dbError); + + // Call the function + const result = await POST(new NextRequest()); + + // Assertions + expect(db.returning).toHaveBeenCalled(); + expect(generateSessionToken).not.toHaveBeenCalled(); + + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Invalid request" }, + { status: 400 } + ); + + expect(result).toEqual({ + data: { error: "Invalid request" }, + options: { status: 400 }, + }); + }); + + it("should return 400 if session creation fails", async () => { + // Setup session error + const sessionError = new Error("Session creation failed"); + createSession.mockRejectedValue(sessionError); + + // Call the function + const result = await POST(new NextRequest()); + + // Assertions + expect(createSession).toHaveBeenCalled(); + expect(setSessionTokenCookie).not.toHaveBeenCalled(); + + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Invalid request" }, + { status: 400 } + ); + + expect(result).toEqual({ + data: { error: "Invalid request" }, + options: { status: 400 }, + }); + }); + + it("should return 400 if cookie setting fails", async () => { + // Setup cookie error + const cookieError = new Error("Cookie setting failed"); + setSessionTokenCookie.mockRejectedValue(cookieError); + + // Call the function + const result = await POST(new NextRequest()); + + // Assertions + expect(setSessionTokenCookie).toHaveBeenCalled(); + + expect(NextResponse.json).toHaveBeenCalledWith( + { error: "Invalid request" }, + { status: 400 } + ); + + expect(result).toEqual({ + data: { error: "Invalid request" }, + options: { status: 400 }, + }); + }); +}); \ No newline at end of file diff --git a/tests/register_test.ts b/tests/register_test.ts deleted file mode 100644 index b04bb9d..0000000 --- a/tests/register_test.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { jest } from "@jest/globals"; - -// Mock Next.js modules -jest.mock("next/server", () => ({ - NextResponse: { - json: jest.fn((data, options) => { - return { - data, - status: options?.status || 200, - headers: new Map(), - }; - }), - }, -})); - -// Mocked user used inside db mock must be defined before mocks -const mockUser = { - id: "user-123", - email: "newuser@example.com", - name: "New User", - nameId: "newuser", - hashedPassword: "hashed_password", - createdAt: new Date(), - updatedAt: new Date(), -}; -const findFirstMock = jest.fn(); -const insertReturningMock = jest.fn(() => Promise.resolve([mockUser])); -const insertValuesMock = jest.fn(() => ({ returning: insertReturningMock })); -const insertMock = jest.fn(() => ({ values: insertValuesMock })); - -jest.mock("@/db/drizzle", () => ({ - db: { - query: { - users: { - findFirst: findFirstMock, - }, - }, - insert: insertMock, - }, -})); -// expect(findFirstMock).toHaveBeenCalled(); -// expect(insertMock).toHaveBeenCalled(); - -jest.mock("@/lib/password", () => ({ - hashPassword: jest.fn(), -})); - -jest.mock("@/lib/username", () => ({ - generateUsername: jest.fn(), -})); - -jest.mock("@/lib/server/session", () => ({ - generateSessionToken: jest.fn(), - createSession: jest.fn(), -})); - -jest.mock("@/lib/server/cookies", () => ({ - setSessionTokenCookie: jest.fn(), -})); - -import { NextRequest } from "next/server"; -import { db } from "@/db/drizzle"; -import { hashPassword } from "@/lib/password"; -import { generateUsername } from "@/lib/username"; -import { generateSessionToken, createSession } from "@/lib/server/session"; -import { setSessionTokenCookie } from "@/lib/server/cookies"; -import { POST } from "@/app/api/auth/register/route"; - -describe("POST /api/auth/register", () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it("should register a new user successfully", async () => { - const requestData = { - email: "newuser@example.com", - password: "Password123!", - name: "New User", - }; - - const mockSession = { - id: "session-123", - userId: "user-123", - token: "token-123", - expiresAt: new Date(Date.now() + 86400000), - }; - - (db.query.users.findFirst as jest.Mock).mockResolvedValue(null); - (hashPassword as jest.Mock).mockResolvedValue("hashed_password"); - (generateUsername as jest.Mock).mockResolvedValue("newuser"); - mockReturning.mockResolvedValue([mockUser]); - (generateSessionToken as jest.Mock).mockReturnValue("token-123"); - (createSession as jest.Mock).mockResolvedValue(mockSession); - (setSessionTokenCookie as jest.Mock).mockResolvedValue(undefined); - - const request = { - json: jest.fn().mockResolvedValue(requestData), - } as unknown as NextRequest; - - const response = await POST(request); - - expect(db.query.users.findFirst).toHaveBeenCalled(); - expect(hashPassword).toHaveBeenCalledWith("Password123!"); - expect(generateUsername).toHaveBeenCalledWith("newuser@example.com"); - expect(db.insert).toHaveBeenCalled(); - expect(generateSessionToken).toHaveBeenCalled(); - expect(createSession).toHaveBeenCalled(); - expect(setSessionTokenCookie).toHaveBeenCalled(); - - expect(response.data).toEqual({ - _id: "user-123", - email: "newuser@example.com", - name: "New User", - nameId: "newuser", - }); - expect(response.status).toBe(200); - }); - - it("should return 400 if email already exists", async () => { - const requestData = { - email: "existing@example.com", - password: "Password123!", - name: "Existing User", - }; - - const mockExistingUser = { ...mockUser, email: "existing@example.com" }; - - (db.query.users.findFirst as jest.Mock).mockResolvedValue(mockExistingUser); - - const request = { - json: jest.fn().mockResolvedValue(requestData), - } as unknown as NextRequest; - - const response = await POST(request); - - expect(db.query.users.findFirst).toHaveBeenCalled(); - expect(hashPassword).not.toHaveBeenCalled(); - expect(generateUsername).not.toHaveBeenCalled(); - expect(db.insert).not.toHaveBeenCalled(); - expect(response.data).toEqual({ error: "Email already exists" }); - expect(response.status).toBe(400); - }); - - it("should return 400 on validation error", async () => { - const request = { - json: jest.fn().mockResolvedValue({ - email: "invalid-email", - password: "123", - name: "", - }), - } as unknown as NextRequest; - - const response = await POST(request); - - expect(response.data).toEqual({ error: "Invalid request" }); - expect(response.status).toBe(400); - }); - - it("should handle database errors", async () => { - const requestData = { - email: "newuser@example.com", - password: "Password123!", - name: "New User", - }; - - (db.query.users.findFirst as jest.Mock).mockResolvedValue(null); - (hashPassword as jest.Mock).mockResolvedValue("hashed_password"); - (generateUsername as jest.Mock).mockResolvedValue("newuser"); - mockReturning.mockRejectedValue(new Error("Database error")); - - const request = { - json: jest.fn().mockResolvedValue(requestData), - } as unknown as NextRequest; - - const response = await POST(request); - - expect(response.data).toEqual({ error: "Invalid request" }); - expect(response.status).toBe(400); - }); - - it("should handle request parsing errors", async () => { - const request = { - json: jest.fn().mockRejectedValue(new Error("Invalid JSON")), - } as unknown as NextRequest; - - const response = await POST(request); - - expect(response.data).toEqual({ error: "Invalid request" }); - expect(response.status).toBe(400); - }); -}); From 87379a2cc7c96c5a21b8fe6b77e08f5cad792cc6 Mon Sep 17 00:00:00 2001 From: Shubh Tiwari Date: Wed, 7 May 2025 01:31:42 +0530 Subject: [PATCH 2/2] Implemented register.test problems.test and formatted --- tests/problems.test.ts | 113 +++++++++++++++++++++++++---------------- tests/register.test.ts | 73 +++++++++++++------------- 2 files changed, 105 insertions(+), 81 deletions(-) diff --git a/tests/problems.test.ts b/tests/problems.test.ts index cc882be..b8a9616 100644 --- a/tests/problems.test.ts +++ b/tests/problems.test.ts @@ -110,16 +110,17 @@ // }); // }); - - - import { NextRequest, NextResponse } from "next/server"; import { z } from "zod"; import * as problemService from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/service"; import { getOrgIdFromNameId, getContestIdFromNameId } from "@/app/api/service"; import { addProblemSchema, NameIdSchema } from "@/lib/validations"; import { getProblemIdFromCode } from "@/app/api/orgs/[orgId]/problems/service"; -import { POST, GET, DELETE } from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/route"; +import { + POST, + GET, + DELETE, +} from "@/app/api/orgs/[orgId]/contests/[contestId]/problems/route"; // Mock the imported modules jest.mock("next/server", () => ({ @@ -144,11 +145,14 @@ jest.mock("zod", () => { }; }); -jest.mock("@/app/api/orgs/[orgId]/contests/[contestId]/problems/service", () => ({ - addProblemToContest: jest.fn(), - getContestProblems: jest.fn(), - removeProblemFromContest: jest.fn(), -})); +jest.mock( + "@/app/api/orgs/[orgId]/contests/[contestId]/problems/service", + () => ({ + addProblemToContest: jest.fn(), + getContestProblems: jest.fn(), + removeProblemFromContest: jest.fn(), + }), +); jest.mock("@/app/api/service", () => ({ getOrgIdFromNameId: jest.fn(), @@ -216,15 +220,23 @@ describe("Contest Problems API Routes", () => { expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.orgId); expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.contestId); expect(getOrgIdFromNameId).toHaveBeenCalledWith(mockParams.orgId); - expect(getContestIdFromNameId).toHaveBeenCalledWith(mockOrgId, mockParams.contestId); + expect(getContestIdFromNameId).toHaveBeenCalledWith( + mockOrgId, + mockParams.contestId, + ); expect(addProblemSchema.parse).toHaveBeenCalledWith(mockRequestBody); - expect(getProblemIdFromCode).toHaveBeenCalledWith(mockOrgId, mockRequestBody.problemCode); + expect(getProblemIdFromCode).toHaveBeenCalledWith( + mockOrgId, + mockRequestBody.problemCode, + ); expect(problemService.addProblemToContest).toHaveBeenCalledWith( mockContestId, mockProblemId, - mockRequestBody.order + mockRequestBody.order, ); - expect(NextResponse.json).toHaveBeenCalledWith(mockAddedProblem, { status: 201 }); + expect(NextResponse.json).toHaveBeenCalledWith(mockAddedProblem, { + status: 201, + }); expect(result).toEqual({ data: mockAddedProblem, options: { status: 201 }, @@ -244,7 +256,7 @@ describe("Contest Problems API Routes", () => { expect(problemService.addProblemToContest).toHaveBeenCalledWith( mockContestId, mockProblemId, - 0 // Default order value + 0, // Default order value ); }); @@ -262,7 +274,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: validationErrors }, - { status: 400 } + { status: 400 }, ); expect(result).toEqual({ data: { error: validationErrors }, @@ -281,7 +293,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Organization not found" }, - { status: 404 } + { status: 404 }, ); expect(result).toEqual({ data: { error: "Organization not found" }, @@ -300,7 +312,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Contest not found" }, - { status: 404 } + { status: 404 }, ); expect(result).toEqual({ data: { error: "Contest not found" }, @@ -319,7 +331,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Problem not found" }, - { status: 404 } + { status: 404 }, ); expect(result).toEqual({ data: { error: "Problem not found" }, @@ -338,7 +350,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Problem already added to contest" }, - { status: 409 } + { status: 409 }, ); expect(result).toEqual({ data: { error: "Problem already added to contest" }, @@ -357,7 +369,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Failed to add problem to contest" }, - { status: 500 } + { status: 500 }, ); expect(result).toEqual({ data: { error: "Failed to add problem to contest" }, @@ -405,8 +417,13 @@ describe("Contest Problems API Routes", () => { expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.orgId); expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.contestId); expect(getOrgIdFromNameId).toHaveBeenCalledWith(mockParams.orgId); - expect(getContestIdFromNameId).toHaveBeenCalledWith(mockOrgId, mockParams.contestId); - expect(problemService.getContestProblems).toHaveBeenCalledWith(mockContestId); + expect(getContestIdFromNameId).toHaveBeenCalledWith( + mockOrgId, + mockParams.contestId, + ); + expect(problemService.getContestProblems).toHaveBeenCalledWith( + mockContestId, + ); expect(NextResponse.json).toHaveBeenCalledWith(mockProblems); expect(result).toEqual({ data: mockProblems, @@ -428,7 +445,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: validationErrors }, - { status: 400 } + { status: 400 }, ); expect(result).toEqual({ data: { error: validationErrors }, @@ -447,7 +464,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Organization not found" }, - { status: 404 } + { status: 404 }, ); expect(result).toEqual({ data: { error: "Organization not found" }, @@ -466,7 +483,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Contest not found" }, - { status: 404 } + { status: 404 }, ); expect(result).toEqual({ data: { error: "Contest not found" }, @@ -485,7 +502,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Failed to fetch contest problems" }, - { status: 500 } + { status: 500 }, ); expect(result).toEqual({ data: { error: "Failed to fetch contest problems" }, @@ -526,11 +543,14 @@ describe("Contest Problems API Routes", () => { expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.contestId); expect(NameIdSchema.parse).toHaveBeenCalledWith(mockParams.problemId); expect(getOrgIdFromNameId).toHaveBeenCalledWith(mockParams.orgId); - expect(getContestIdFromNameId).toHaveBeenCalledWith(mockOrgId, mockParams.contestId); + expect(getContestIdFromNameId).toHaveBeenCalledWith( + mockOrgId, + mockParams.contestId, + ); expect(problemService.removeProblemFromContest).toHaveBeenCalledWith( mockOrgId, mockContestId, - mockParams.problemId + mockParams.problemId, ); expect(Response).toHaveBeenCalledWith(null, { status: 204 }); expect(result).toEqual({ @@ -542,15 +562,20 @@ describe("Contest Problems API Routes", () => { it("should return 400 for validation errors", async () => { // Setup validation error - const validationErrors = [{ path: ["problemId"], message: "Invalid format" }]; + const validationErrors = [ + { path: ["problemId"], message: "Invalid format" }, + ]; const zodError = new z.ZodError(validationErrors); - NameIdSchema.parse.mockImplementationOnce(() => { - return mockParams.orgId; - }).mockImplementationOnce(() => { - return mockParams.contestId; - }).mockImplementationOnce(() => { - throw zodError; - }); + NameIdSchema.parse + .mockImplementationOnce(() => { + return mockParams.orgId; + }) + .mockImplementationOnce(() => { + return mockParams.contestId; + }) + .mockImplementationOnce(() => { + throw zodError; + }); // Call the function const result = await DELETE(new NextRequest(), { params: mockParams }); @@ -558,7 +583,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: validationErrors }, - { status: 400 } + { status: 400 }, ); expect(result).toEqual({ data: { error: validationErrors }, @@ -577,7 +602,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Organization not found" }, - { status: 404 } + { status: 404 }, ); expect(result).toEqual({ data: { error: "Organization not found" }, @@ -596,7 +621,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Contest not found" }, - { status: 404 } + { status: 404 }, ); expect(result).toEqual({ data: { error: "Contest not found" }, @@ -615,7 +640,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Problem not found" }, - { status: 404 } + { status: 404 }, ); expect(result).toEqual({ data: { error: "Problem not found" }, @@ -626,7 +651,9 @@ describe("Contest Problems API Routes", () => { it("should return 500 for unexpected errors", async () => { // Setup const unexpectedError = new Error("Unexpected database error"); - problemService.removeProblemFromContest.mockRejectedValue(unexpectedError); + problemService.removeProblemFromContest.mockRejectedValue( + unexpectedError, + ); // Call the function const result = await DELETE(new NextRequest(), { params: mockParams }); @@ -634,7 +661,7 @@ describe("Contest Problems API Routes", () => { // Assertions expect(NextResponse.json).toHaveBeenCalledWith( { error: "Failed to remove problem from contest" }, - { status: 500 } + { status: 500 }, ); expect(result).toEqual({ data: { error: "Failed to remove problem from contest" }, @@ -642,4 +669,4 @@ describe("Contest Problems API Routes", () => { }); }); }); -}); \ No newline at end of file +}); diff --git a/tests/register.test.ts b/tests/register.test.ts index fea85a6..c24de23 100644 --- a/tests/register.test.ts +++ b/tests/register.test.ts @@ -190,16 +190,6 @@ // }); // }); - - - - - - - - - - import { NextRequest, NextResponse } from "next/server"; import { POST } from "@/app/api/auth/register/route"; // Assuming this file is in the same directory as the route import { registerSchema } from "@/lib/validations"; @@ -297,7 +287,11 @@ describe("User Registration API Route", () => { registerSchema.parse.mockReturnValue(mockRequestBody); db.query.users.findFirst.mockResolvedValue(null); // No existing user by default - eq.mockReturnValue({ operator: "=", field: "email", value: mockRequestBody.email }); + eq.mockReturnValue({ + operator: "=", + field: "email", + value: mockRequestBody.email, + }); hashPassword.mockResolvedValue("hashed-password"); generateUsername.mockResolvedValue(mockUser.nameId); db.returning.mockResolvedValue([mockUser]); @@ -318,7 +312,7 @@ describe("User Registration API Route", () => { expect(eq).toHaveBeenCalledWith(users.email, mockRequestBody.email); expect(hashPassword).toHaveBeenCalledWith(mockRequestBody.password); expect(generateUsername).toHaveBeenCalledWith(mockRequestBody.email); - + expect(db.insert).toHaveBeenCalledTimes(1); expect(db.values).toHaveBeenCalledWith({ email: mockRequestBody.email, @@ -327,18 +321,21 @@ describe("User Registration API Route", () => { nameId: mockUser.nameId, }); expect(db.returning).toHaveBeenCalledTimes(1); - + expect(generateSessionToken).toHaveBeenCalledTimes(1); expect(createSession).toHaveBeenCalledWith(mockToken, mockUser.id); - expect(setSessionTokenCookie).toHaveBeenCalledWith(mockToken, mockSession.expiresAt); - + expect(setSessionTokenCookie).toHaveBeenCalledWith( + mockToken, + mockSession.expiresAt, + ); + expect(NextResponse.json).toHaveBeenCalledWith({ _id: mockUser.id, email: mockUser.email, name: mockUser.name, nameId: mockUser.nameId, }); - + expect(result).toEqual({ data: { _id: mockUser.id, @@ -366,12 +363,12 @@ describe("User Registration API Route", () => { expect(generateSessionToken).not.toHaveBeenCalled(); expect(createSession).not.toHaveBeenCalled(); expect(setSessionTokenCookie).not.toHaveBeenCalled(); - + expect(NextResponse.json).toHaveBeenCalledWith( { error: "Email already exists" }, - { status: 400 } + { status: 400 }, ); - + expect(result).toEqual({ data: { error: "Email already exists" }, options: { status: 400 }, @@ -392,12 +389,12 @@ describe("User Registration API Route", () => { expect(registerSchema.parse).toHaveBeenCalled(); expect(db.query.users.findFirst).not.toHaveBeenCalled(); expect(db.insert).not.toHaveBeenCalled(); - + expect(NextResponse.json).toHaveBeenCalledWith( { error: "Invalid request" }, - { status: 400 } + { status: 400 }, ); - + expect(result).toEqual({ data: { error: "Invalid request" }, options: { status: 400 }, @@ -415,12 +412,12 @@ describe("User Registration API Route", () => { // Assertions expect(hashPassword).toHaveBeenCalled(); expect(db.insert).not.toHaveBeenCalled(); - + expect(NextResponse.json).toHaveBeenCalledWith( { error: "Invalid request" }, - { status: 400 } + { status: 400 }, ); - + expect(result).toEqual({ data: { error: "Invalid request" }, options: { status: 400 }, @@ -438,12 +435,12 @@ describe("User Registration API Route", () => { // Assertions expect(generateUsername).toHaveBeenCalled(); expect(db.insert).not.toHaveBeenCalled(); - + expect(NextResponse.json).toHaveBeenCalledWith( { error: "Invalid request" }, - { status: 400 } + { status: 400 }, ); - + expect(result).toEqual({ data: { error: "Invalid request" }, options: { status: 400 }, @@ -461,12 +458,12 @@ describe("User Registration API Route", () => { // Assertions expect(db.returning).toHaveBeenCalled(); expect(generateSessionToken).not.toHaveBeenCalled(); - + expect(NextResponse.json).toHaveBeenCalledWith( { error: "Invalid request" }, - { status: 400 } + { status: 400 }, ); - + expect(result).toEqual({ data: { error: "Invalid request" }, options: { status: 400 }, @@ -484,12 +481,12 @@ describe("User Registration API Route", () => { // Assertions expect(createSession).toHaveBeenCalled(); expect(setSessionTokenCookie).not.toHaveBeenCalled(); - + expect(NextResponse.json).toHaveBeenCalledWith( { error: "Invalid request" }, - { status: 400 } + { status: 400 }, ); - + expect(result).toEqual({ data: { error: "Invalid request" }, options: { status: 400 }, @@ -506,15 +503,15 @@ describe("User Registration API Route", () => { // Assertions expect(setSessionTokenCookie).toHaveBeenCalled(); - + expect(NextResponse.json).toHaveBeenCalledWith( { error: "Invalid request" }, - { status: 400 } + { status: 400 }, ); - + expect(result).toEqual({ data: { error: "Invalid request" }, options: { status: 400 }, }); }); -}); \ No newline at end of file +});