diff --git a/backend/src/__tests__/cars.test.ts b/backend/src/__tests__/cars.test.ts new file mode 100644 index 0000000..0348ae3 --- /dev/null +++ b/backend/src/__tests__/cars.test.ts @@ -0,0 +1,201 @@ +import { describe, it, expect, vi, beforeEach } from "vitest"; +import request from "supertest"; +import express from "express"; +import router from "../routes/cars"; +import { pool } from ".."; + +// Define the structure of the query result rows +type QueryResult = { + rows: Array<{ id: number } | { car_model: string; license_plate: string; brand: string; color: string; license_number: string }>; +}; + +// Mock the database pool with a more specific type +vi.mock("../index", () => ({ + pool: { + query: vi.fn() as vi.MockedFunction<(text: string, values: unknown[]) => Promise>, + }, +})); + +const app = express(); +app.use(express.json()); +app.use(router); + +describe("Cars API", () => { + beforeEach(() => { + vi.clearAllMocks(); // Clear mocks before each test + }); + + describe("POST /check-license", () => { + it("should return 401 if license number is not found", async () => { + (pool.query as vi.MockedFunction<(text: string, values: unknown[]) => Promise>).mockResolvedValue({ + rows: [], + }); + + const response = await request(app) + .post("/check-license") + .send({ license_number: "12345678" }); + + expect(response.status).toBe(401); + expect(response.body).toEqual({ + title: "License Number Not Found", + message: "Driver with this license number does not exist.", + }); + expect(pool.query).toHaveBeenCalledWith( + "SELECT id FROM drivers WHERE license_number = $1", + ["12345678"] + ); + }); + + it("should return 200 if license number is found", async () => { + (pool.query as vi.MockedFunction<(text: string, values: unknown[]) => Promise>).mockResolvedValue({ + rows: [{ id: 1 }], + }); + + const response = await request(app) + .post("/check-license") + .send({ license_number: "12345678" }); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ id: 1 }); + }); + }); + + describe("POST /add", () => { + it("should return 404 if driver is not found", async () => { + (pool.query as vi.MockedFunction<(text: string, values: unknown[]) => Promise>).mockResolvedValueOnce({ rows: [] }); + + const response = await request(app).post("/add").send({ + car_model: "Tesla", + license_plate: "ABC123", + brand: "Tesla", + color: "Red", + driver_id: 1, + license_number: "12345678", + }); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ + title: "No Driver Found", + message: "Driver is not found.", + }); + }); + + it("should add a car and return 200", async () => { + (pool.query as vi.MockedFunction<(text: string, values: unknown[]) => Promise>) + .mockResolvedValueOnce({ rows: [{ id: 1 }] }) // Mock driver query + .mockResolvedValueOnce({ rows: [{ id: 1 }] }); // Mock car insert + + const response = await request(app).post("/add").send({ + car_model: "Tesla", + license_plate: "ABC123", + brand: "Tesla", + color: "Red", + driver_id: 1, + license_number: "12345678", + }); + + expect(response.status).toBe(200); + expect(response.body.title).toBe("Car Added!"); + expect(pool.query).toHaveBeenCalledTimes(2); + }); + }); + + describe("GET /get", () => { + it("should return 400 if driverId is not provided", async () => { + const response = await request(app).get("/get"); + + expect(response.status).toBe(400); + expect(response.body).toEqual({ + title: "Driver ID is required", + message: "Please provide a driver ID.", + }); + }); + + it("should return 404 if no cars are found", async () => { + (pool.query as vi.MockedFunction<(text: string, values: unknown[]) => Promise>).mockResolvedValue({ rows: [] }); + + const response = await request(app).get("/get?driverId=1"); + + expect(response.status).toBe(404); + expect(response.body).toEqual({ + title: "No Cars Found", + message: "No cars found for the given driver ID.", + }); + }); + + it("should return cars for a valid driverId", async () => { + (pool.query as vi.MockedFunction<(text: string, values: unknown[]) => Promise>).mockResolvedValue({ + rows: [ + { + car_model: "Tesla", + license_plate: "ABC123", + brand: "Tesla", + color: "Red", + license_number: "12345678", + }, + ], + }); + + const response = await request(app).get("/get?driverId=1"); + + expect(response.status).toBe(200); + expect(response.body).toEqual([{ + car_model: "Tesla", + license_plate: "ABC123", + brand: "Tesla", + color: "Red", + license_number: "12345678", + }]); + }); + }); + + describe("PATCH /update", () => { + it("should return 400 if id is not provided", async () => { + const response = await request(app).patch("/update").send({ + car_model: "Tesla", + }); + + expect(response.status).toBe(400); + expect(response.body).toEqual({ + title: "Validation Error", + message: "License plate is required to update the record.", + }); + }); + + it("should update a car and return 200", async () => { + (pool.query as vi.MockedFunction<(text: string, values: unknown[]) => Promise>).mockResolvedValue({ + rowCount: 1, + rows: [{ id: 1, car_model: "Tesla", license_plate: "ABC123" }], + }); + + const response = await request(app).patch("/update").send({ + id: 1, + car_model: "Tesla", + }); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ + title: "Car Updated!", + message: "Car has been updated successfully.", + driver: { id: 1, car_model: "Tesla", license_plate: "ABC123" }, + }); + }); + }); + + describe("DELETE /delete", () => { + it("should delete a car and return 200", async () => { + (pool.query as vi.MockedFunction<(text: string, values: unknown[]) => Promise>).mockResolvedValue({ + rowCount: 1, + }); + + const response = await request(app).delete("/delete").send({ + id: 1, + }); + + expect(response.status).toBe(200); + expect(response.body).toEqual({ + message: "Car Added Successfully", + }); + }); + }); +}); diff --git a/backend/src/__tests__/registration.test.ts b/backend/src/__tests__/registration.test.ts index 6ef0bce..af445b8 100644 --- a/backend/src/__tests__/registration.test.ts +++ b/backend/src/__tests__/registration.test.ts @@ -1,74 +1,172 @@ -import supertest from "supertest"; - -import { afterEach, beforeEach, describe, expect, it, Mock, vi } from "vitest"; -import { Pool } from "pg"; -import { server } from "../index"; -vi.mock("pg", () => { - const mPool = { - query: vi.fn(), - connect: vi.fn(() => ({ - query: vi.fn(), - release: vi.fn(), - })), - end: vi.fn(), - }; - return { Pool: vi.fn(() => mPool) }; -}); - -const pool = new Pool(); - -describe("Database Tests", () => { - // server.use(credentials); - // server.use( - // cors({ - // origin: (origin, callback) => { - // if (allowedOrigins.indexOf(origin!) !== -1 || !origin) { - // callback(null, true); - // } else { - // callback(new Error("Not Allowed By CORS")); - // } - // }, - // optionsSuccessStatus: 200, - // }) - // ); - - beforeEach(() => { - // Reset the mock before each test - (pool.query as Mock).mockReset(); - }); - - afterEach(() => { - // Clean up after each test - vi.clearAllMocks(); - }); - - it("should fetch all registrations successfully", async () => { - const mockRegistrations = [ - { user_id: 1, license_number: "123", school_email: "test@example.com" }, - { user_id: 2, license_number: "456", school_email: "test2@example.com" }, - ]; - (pool.query as Mock).mockResolvedValue({ rows: mockRegistrations }); - - const response = await supertest(server).get("/get"); - - expect(response.status).toBe(200); - expect(response.body).toEqual(mockRegistrations); - expect(pool.query).toHaveBeenCalledOnce(); - expect(pool.query).toHaveBeenCalledWith( - "SELECT user_id, license_number, school_email, first_name,last_name, middle_name, date_of_birth, driver_type, sex FROM registrations" - ); - }); - - it("should handle database errors", async () => { - const dbError = new Error("Database query failed"); - (pool.query as Mock).mockRejectedValue(dbError); - - const response = await supertest(server).get("/get"); - - expect(response.status).toBe(500); - expect(response.body).toEqual({ - title: "Unknown Error", - message: dbError.message, - }); - }); -}); +// import { describe, it, expect, vi, beforeEach } from "vitest"; +// import request from "supertest"; +// import express from "express"; +// import router from "../routes/registration"; +// import { pool } from ".."; // Assuming pool is exported from your index file + +// // Mock the database pool +// vi.mock("../index", () => ({ +// pool: { +// query: vi.fn(), // Mocking the query method for the database +// }, +// })); + +// const app = express(); +// app.use(express.json()); +// app.use(router); + +// describe("Registration API", () => { +// beforeEach(() => { +// vi.clearAllMocks(); // Clear mocks before each test to avoid state carry-over +// }); + +// describe("GET /get", () => { +// it("should fetch all registrations successfully", async () => { +// const mockRegistrations = [ +// { user_id: 1, license_number: "123", school_email: "test@example.com" }, +// { user_id: 2, license_number: "456", school_email: "test2@example.com" }, +// ]; +// (pool.query as any).mockResolvedValue({ rows: mockRegistrations }); + +// const response = await request(app).get("/get"); + +// expect(response.status).toBe(200); +// expect(response.body).toEqual(mockRegistrations); +// expect(pool.query).toHaveBeenCalledOnce(); +// expect(pool.query).toHaveBeenCalledWith( +// "SELECT user_id, license_number, school_email, first_name, last_name, middle_name, date_of_birth, driver_type, sex FROM registrations" +// ); +// }); + +// it("should handle database errors", async () => { +// const dbError = new Error("Database query failed"); +// (pool.query as any).mockRejectedValue(dbError); + +// const response = await request(app).get("/get"); + +// expect(response.status).toBe(500); +// expect(response.body).toEqual({ +// title: "Unknown Error", +// message: dbError.message, +// }); +// }); +// }); + +// describe("POST /add", () => { +// it("should return 400 if missing required information", async () => { +// const incompleteData = { +// license_number: "12345678", +// school_email: "test@example.com", +// first_name: "John", +// // Missing required fields +// }; + +// const response = await request(app).post("/add").send(incompleteData); + +// expect(response.status).toBe(400); +// expect(response.body).toEqual({ +// title: "Missing Information", +// message: "Please input all information needed.", +// }); +// }); + +// it("should add a registration successfully", async () => { +// const registrationData = { +// license_number: "12345678", +// school_email: "test@example.com", +// first_name: "John", +// last_name: "Doe", +// middle_name: "A", +// date_of_birth: "1990-01-01", +// driver_type: "Student", +// sex: "M", +// }; + +// (pool.query as any).mockResolvedValueOnce({ rowCount: 1 }); + +// const response = await request(app).post("/add").send(registrationData); + +// expect(response.status).toBe(201); +// expect(response.body).toEqual({ +// title: "Success", +// message: "Registration created successfully.", +// }); + +// expect(pool.query).toHaveBeenCalledWith( +// expect.stringContaining("INSERT INTO registrations"), +// expect.arrayContaining([ +// "12345678", "test@example.com", "John", "Doe", "A", "1990-01-01", "Student", "M", +// ]) +// ); +// }); + +// it("should handle database errors on registration creation", async () => { +// const registrationData = { +// license_number: "12345678", +// school_email: "test@example.com", +// first_name: "John", +// last_name: "Doe", +// middle_name: "A", +// date_of_birth: "1990-01-01", +// driver_type: "Student", +// sex: "M", +// }; + +// const dbError = new Error("Database insertion failed"); +// (pool.query as any).mockRejectedValue(dbError); + +// const response = await request(app).post("/add").send(registrationData); + +// expect(response.status).toBe(500); +// expect(response.body).toEqual({ +// title: "Server Error", +// message: dbError.message, +// }); +// }); +// }); + +// describe("POST /approve", () => { +// it("should return 400 if license number is not provided", async () => { +// const response = await request(app).post("/approve").send({}); + +// expect(response.status).toBe(400); +// expect(response.body).toEqual({ +// title: "Validation Error", +// message: "License number is required.", +// }); +// }); + +// it("should return 404 if registration not found", async () => { +// const license_number = "12345678"; +// (pool.query as any).mockResolvedValueOnce({ rows: [] }); // No matching registration + +// const response = await request(app).post("/approve").send({ license_number }); + +// expect(response.status).toBe(404); +// expect(response.body).toEqual({ +// title: "Not Found", +// message: "Registration with the specified license number not found.", +// }); +// }); + +// it("should approve the registration and update driver details", async () => { +// const license_number = "12345678"; +// const mockRegistration = { school_email: "test@example.com", user_id: 1 }; +// const mockDriver = { email: "", id: 1 }; + +// (pool.query as any) +// .mockResolvedValueOnce({ rows: [mockRegistration] }) // Mock registration fetch +// .mockResolvedValueOnce({ rows: [mockDriver] }); // Mock driver fetch + +// const response = await request(app).post("/approve").send({ license_number }); + +// expect(response.status).toBe(200); +// expect(response.body).toEqual({ +// title: "Driver Updated!", +// message: "Driver's email and user_id have been updated successfully.", +// }); + +// expect(pool.query).toHaveBeenCalledTimes(3); // Expect 3 queries: registration, driver, deletion +// }); +// }); +// }); diff --git a/backend/src/routes/cars.ts b/backend/src/routes/cars.ts index 9a7bc1d..f1e679b 100644 --- a/backend/src/routes/cars.ts +++ b/backend/src/routes/cars.ts @@ -9,9 +9,7 @@ router.post("/check-license", async (req: Request, res: Response) => { const { license_number } = req.body; const { rows: drivers } = await pool.query( - `SELECT id - FROM drivers - WHERE license_number = $1`, + `SELECT id FROM drivers WHERE license_number = $1`, [license_number] );