diff --git a/.github/workflows/node.js.yml b/.github/workflows/node.js.yml index b0bba9fc..84ecc8b1 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/node.js.yml @@ -33,3 +33,4 @@ jobs: - name: Run Eslint run: npm run lint - run: npm run build --if-present + working-directory: frontend diff --git a/frontend/__test__/hooks/useUser.test.ts b/frontend/__test__/hooks/useUser.test.ts index b044ff4d..edd45b50 100644 --- a/frontend/__test__/hooks/useUser.test.ts +++ b/frontend/__test__/hooks/useUser.test.ts @@ -30,6 +30,10 @@ vi.mock('react-router-dom', () => ({ MemoryRouter: ({ children }) => children, })); +// Mock window.alert to prevent "Not implemented" error +vi.spyOn(window, 'alert').mockImplementation(() => {}); + + describe('useLogin Hook', () => { const setAuth = vi.fn(); const setAppLoading = vi.fn(); diff --git a/frontend/__test__/pages/LoginPage.test.tsx b/frontend/__test__/pages/LoginPage.test.tsx index ff0f7338..86c4f5e8 100644 --- a/frontend/__test__/pages/LoginPage.test.tsx +++ b/frontend/__test__/pages/LoginPage.test.tsx @@ -33,7 +33,7 @@ describe("Login Page renders corriquely", () => { render(, { wrapper: BrowserRouter }); const emailInput = await screen.findByPlaceholderText( - "Email or phone number" + "Email address" ); const passwordInput = await screen.findByPlaceholderText( "Enter your password" @@ -46,7 +46,7 @@ describe("Login Page renders corriquely", () => { it("이메일 및 비밀번호 필드의 값을 업데이트해야 합니다", async () => { render(, { wrapper: BrowserRouter }); - const emailInput = screen.getByPlaceholderText("Email or phone number"); + const emailInput = screen.getByPlaceholderText("Email address"); const passwordInput = screen.getByPlaceholderText("Enter your password"); fireEvent.change(emailInput, { target: { value: "test@example.com" } }); @@ -55,6 +55,4 @@ describe("Login Page renders corriquely", () => { expect(emailInput).toHaveProperty("value", "test@example.com"); expect(passwordInput).toHaveProperty("value", "password123"); }); - - }); diff --git a/frontend/__test__/pages/ViewProfile.test.tsx b/frontend/__test__/pages/ViewProfile.test.tsx new file mode 100644 index 00000000..400d80af --- /dev/null +++ b/frontend/__test__/pages/ViewProfile.test.tsx @@ -0,0 +1,101 @@ +import React from "react"; +import { describe, it, expect, vi, beforeEach, Mock } from "vitest"; +import { fireEvent, render, renderHook, screen } from "@testing-library/react"; +import { BrowserRouter } from "react-router-dom"; +import ViewProfile from "../../src/pages/ViewProfile"; +import useGetDriver from "../../src/hooks/driver-hooks/useGetDriver"; +import useAuth from "../../src/hooks/context-hooks/useAuth"; + +// Mock the hooks +vi.mock("../../src/hooks/driver-hooks/useGetDriver"); +vi.mock("../../src/hooks/context-hooks/useAuth"); + +// Mock useGetDriver to return loading state + +// Mock useAuth to return an admin user +vi.mocked(useAuth).mockReturnValue({ + auth: { isAdmin: true }, +}); + +const sampleDriver = { + date_of_birth: "2000-05-20", + email: "YoshinoriKanemoto@gmail.com", + id: "123", + driver_type: "Student", + first_name: "Yoshinori", + last_name: "Kanemoto", + is_driver_registered: false, + license_expiration_date: "11/12/24", + license_number: "123", + middle_name: "Perfas", + sex: "Male", + user_id: "123", +}; + +describe("ViewProfile Component", () => { + beforeEach(() => { + vi.resetAllMocks(); + (useGetDriver as Mock).mockReturnValue({ + loading: false, + driver: sampleDriver, + }); + + vi.mocked(useAuth).mockReturnValue({ + auth: { isAdmin: true }, + }); + }); + + it("should be loading when there is no driver yet", () => { + vi.mocked(useGetDriver).mockReturnValue({ + driver: {}, + loading: true, + }); + + renderHook(() => useGetDriver("123")); + + render(, { wrapper: BrowserRouter }); + + expect(useGetDriver).toReturnWith({ + loading: true, + driver: {}, + }); + expect(screen.getByTestId("loading-component")).toBeDefined(); + }); + + it("should initially render profile information correctly", () => { + // Render the component + render(, { wrapper: BrowserRouter }); + + renderHook(() => useGetDriver("123")); + + expect(screen.getByTestId("profile-lastname")).toBeDefined(); + expect(screen.getByText("Kanemoto")).toBeDefined(); + + expect(useGetDriver).toHaveBeenCalledWith("123"); + expect(useGetDriver).toReturnWith({ + loading: false, + driver: { + date_of_birth: "2000-05-20", + email: "YoshinoriKanemoto@gmail.com", + id: "123", + driver_type: "Student", + first_name: "Yoshinori", + last_name: "Kanemoto", + is_driver_registered: false, + license_expiration_date: "11/12/24", + license_number: "123", + middle_name: "Perfas", + sex: "Male", + user_id: "123", + }, + }); + }); + + it("should render the vehicle list correctly", () => { + render(, { wrapper: BrowserRouter }); + const vehichleListButton = screen.getByTestId("vehicle-button") + + fireEvent.click(vehichleListButton) + expect(screen.getByTestId("vehichlelist")).toBeDefined() + }) +}); diff --git a/frontend/src/components/AdminViewProfileComponent/Profile.tsx b/frontend/src/components/AdminViewProfileComponent/Profile.tsx index a5bc289d..9c3c82c7 100644 --- a/frontend/src/components/AdminViewProfileComponent/Profile.tsx +++ b/frontend/src/components/AdminViewProfileComponent/Profile.tsx @@ -4,20 +4,7 @@ import useEditDriver from "../../hooks/driver-hooks/useEditDriver"; const Profile = ({ driver }: { driver: DriverWithVandC }) => { const [isEditing, setIsEditing] = useState(false); // Track edit mode - const [formData, setFormData] = useState({ - id: driver.id, - last_name: driver.last_name, - first_name: driver.first_name, - middle_name: driver.middle_name, - sex: driver.sex, - date_of_birth: driver.date_of_birth, - driver_type: driver.driver_type, - email: driver.email, - license_number: driver.license_number, - license_expiration_date: driver.license_expiration_date, - }); - - console.log(driver); + const [formData, setFormData] = useState(driver); const { editDriver } = useEditDriver(); @@ -42,7 +29,9 @@ const Profile = ({ driver }: { driver: DriverWithVandC }) => {
-

+

Last Name:

{isEditing ? ( diff --git a/frontend/src/components/AdminViewProfileComponent/VehicleList.tsx b/frontend/src/components/AdminViewProfileComponent/VehicleList.tsx index 3fa414ee..448882cc 100644 --- a/frontend/src/components/AdminViewProfileComponent/VehicleList.tsx +++ b/frontend/src/components/AdminViewProfileComponent/VehicleList.tsx @@ -3,14 +3,15 @@ import { DriverWithVandC } from "../../types/datatypes"; const VehicleList = ({ driver }: { driver: DriverWithVandC }) => { return ( -
+
- {driver.cars!.map((car) => ( - - ))} + { + driver.cars?.map((car) => ( + + ))}
); diff --git a/frontend/src/components/Loading.tsx b/frontend/src/components/Loading.tsx index 4148d6f2..62e3ca2c 100644 --- a/frontend/src/components/Loading.tsx +++ b/frontend/src/components/Loading.tsx @@ -2,15 +2,13 @@ import { Spinner } from "react-activity"; const Loading = ({ loading }: { loading: boolean }) => { return ( -
- +
+
); }; - export default Loading; diff --git a/frontend/src/context/AuthContext.tsx b/frontend/src/context/AuthContext.tsx index 82e53b3c..a78c4c85 100644 --- a/frontend/src/context/AuthContext.tsx +++ b/frontend/src/context/AuthContext.tsx @@ -1,9 +1,9 @@ -import React, { createContext, useState } from "react"; +import { createContext, PropsWithChildren, useState } from "react"; import { AuthContextType } from "../types/user.types"; const AuthContext = createContext({}); -export const AuthProvider = ({ children }: { children: React.ReactNode }) => { +export const AuthProvider = ({ children }: PropsWithChildren) => { const [auth, setAuth] = useState(); return ( diff --git a/frontend/src/pages/ViewProfile.tsx b/frontend/src/pages/ViewProfile.tsx index b1d98596..ee7e0bfe 100644 --- a/frontend/src/pages/ViewProfile.tsx +++ b/frontend/src/pages/ViewProfile.tsx @@ -53,7 +53,9 @@ const ViewProfile = () => { activeSection === "vehicle" ? "text-textgreen" : "text-white hover:text-textgreen" - }`}> + }`} + data-testid="vehicle-button" + > Vehicles