From c6e6235f51ad5514c547d939754cc1df7a5cf165 Mon Sep 17 00:00:00 2001 From: belwalshubham Date: Thu, 3 Apr 2025 11:27:28 +0530 Subject: [PATCH 1/2] add user page test cases --- __tests__/UsersPage.test.js | 104 +++++++++++++++++++++++++++++++++ src/app/(app)/users/page.js | 111 +++++++++++++++--------------------- 2 files changed, 150 insertions(+), 65 deletions(-) create mode 100644 __tests__/UsersPage.test.js diff --git a/__tests__/UsersPage.test.js b/__tests__/UsersPage.test.js new file mode 100644 index 0000000..cb2b4c1 --- /dev/null +++ b/__tests__/UsersPage.test.js @@ -0,0 +1,104 @@ +import { render, screen, fireEvent, waitFor } from "@testing-library/react"; +import UsersPage from "../src/app/(app)/users/page"; +import { useUserActions } from "@/hooks/user"; +import { useAuth } from "@/hooks/auth"; +import React from "react"; + +// Mock hooks +jest.mock("@/hooks/user"); +jest.mock("@/hooks/auth"); + +const mockUsers = [ + { id: 1, name: "John Doe", email: "john@example.com", roles: [{ name: "Admin" }] }, + { id: 2, name: "Jane Smith", email: "jane@example.com", roles: [{ name: "User" }] }, +]; + +const mockRoles = [ + { id: 1, name: "Admin" }, + { id: 2, name: "User" }, + { id: 3, name: "Editor" }, +]; + +describe("UsersPage Component", () => { + let mockFetchUsers, mockFetchRoles, mockUpdateUserRoles, mockDeleteUser; + + beforeEach(() => { + mockFetchUsers = jest.fn().mockResolvedValue({ data: mockUsers, last_page: 1 }); + mockFetchRoles = jest.fn().mockResolvedValue(mockRoles); + mockUpdateUserRoles = jest.fn().mockResolvedValue({}); + mockDeleteUser = jest.fn().mockResolvedValue({}); + + useUserActions.mockReturnValue({ + fetchUsers: mockFetchUsers, + fetchRoles: mockFetchRoles, + updateUserRoles: mockUpdateUserRoles, + deleteUser: mockDeleteUser, + }); + + useAuth.mockReturnValue({ user: { id: 3, name: "Admin User" } }); + }); + + test("renders user list and roles dropdown correctly", async () => { + render(); + + // Check loading state + expect(screen.getByTestId("loading-users")).toBeInTheDocument(); + + await waitFor(() => { + expect(mockFetchUsers).toHaveBeenCalledTimes(1); + expect(screen.queryByTestId("loading-users")).not.toBeInTheDocument(); + }); + + // Verify user data + expect(screen.getByText("John Doe")).toBeInTheDocument(); + expect(screen.getByText("Jane Smith")).toBeInTheDocument(); + + // Verify role selects + expect(screen.getByTestId("role-select-1")).toBeInTheDocument(); + expect(screen.getByTestId("role-select-2")).toBeInTheDocument(); + }); + + test("updates user role and refreshes data", async () => { + render(); + + await waitFor(() => expect(mockFetchUsers).toHaveBeenCalledTimes(1)); + + const roleSelect = await screen.findByTestId("role-select-2"); + fireEvent.change(roleSelect, { target: { value: "Editor" } }); + + await waitFor(() => { + expect(mockUpdateUserRoles).toHaveBeenCalledWith(2, ["Editor"]); + expect(mockFetchUsers).toHaveBeenCalledTimes(2); + }); + }); + + test("deletes a user after confirmation", async () => { + render(); + + await waitFor(() => expect(mockFetchUsers).toHaveBeenCalledTimes(1)); + + const deleteButton = await screen.findByTestId("delete-user-2"); + fireEvent.click(deleteButton); + + const confirmButton = await screen.findByText("Confirm"); + fireEvent.click(confirmButton); + + await waitFor(() => { + expect(mockDeleteUser).toHaveBeenCalledWith(2); + expect(mockFetchUsers).toHaveBeenCalledTimes(2); + }); + }); + + test("handles pagination with Next button", async () => { + mockFetchUsers.mockResolvedValueOnce({ data: mockUsers, last_page: 2 }); + + render(); + + await waitFor(() => expect(mockFetchUsers).toHaveBeenCalledTimes(1)); + + const nextButton = await screen.findByTestId("pagination-next"); + fireEvent.click(nextButton); + + await waitFor(() => expect(mockFetchUsers).toHaveBeenCalledWith(2)); + }); +}); \ No newline at end of file diff --git a/src/app/(app)/users/page.js b/src/app/(app)/users/page.js index bf86f29..5b89bcc 100644 --- a/src/app/(app)/users/page.js +++ b/src/app/(app)/users/page.js @@ -83,17 +83,7 @@ const UsersPage = () => { setUserToDelete(null); }; - const handleSearchChange = (value) => { - setSearchQuery(value); - }; - - const handlePageChange = (newPage) => { - if (newPage >= 1 && newPage <= totalPages) { - setCurrentPage(newPage); - } - }; - - if (loading) return

Loading users...

; + if (loading) return

Loading users...

; return (
@@ -101,7 +91,7 @@ const UsersPage = () => {

Manage Users

setSearchQuery(value)} />
@@ -114,63 +104,57 @@ const UsersPage = () => { - {filteredUsers.length > 0 ? ( - filteredUsers.map((user) => ( - - - - + + + + - - - )) - ) : ( - - - )} + ))}
- {user.name} - - {user.email} - -
+ {user.name} + + {user.email} + + + + - -
- No users found. + }} + disabled={user.id === currentUser.id} + className="bg-red-500 hover:bg-red-600" + > + Delete +
@@ -178,9 +162,9 @@ const UsersPage = () => { Page {currentPage} of {totalPages} @@ -190,10 +174,7 @@ const UsersPage = () => { isOpen={isPopupOpen} message="Are you sure you want to delete this user?" onConfirm={handleConfirmDelete} - onCancel={() => { - setIsPopupOpen(false); - setUserToDelete(null); - }} + onCancel={() => setIsPopupOpen(false)} />
From 04c8438a8e4d87a96a5eec40d7136781e1713ae1 Mon Sep 17 00:00:00 2001 From: belwalshubham Date: Thu, 3 Apr 2025 11:32:30 +0530 Subject: [PATCH 2/2] code cleanups --- __tests__/UsersPage.test.js | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/__tests__/UsersPage.test.js b/__tests__/UsersPage.test.js index cb2b4c1..34c2467 100644 --- a/__tests__/UsersPage.test.js +++ b/__tests__/UsersPage.test.js @@ -9,21 +9,32 @@ jest.mock("@/hooks/user"); jest.mock("@/hooks/auth"); const mockUsers = [ - { id: 1, name: "John Doe", email: "john@example.com", roles: [{ name: "Admin" }] }, - { id: 2, name: "Jane Smith", email: "jane@example.com", roles: [{ name: "User" }] }, + { + id: 1, + name: "John Doe", + email: "john@example.com", + roles: [{ name: "Admin" }], + }, + { + id: 2, + name: "Jane Smith", + email: "jane@example.com", + roles: [{ name: "User" }], + }, ]; const mockRoles = [ { id: 1, name: "Admin" }, { id: 2, name: "User" }, - { id: 3, name: "Editor" }, ]; describe("UsersPage Component", () => { let mockFetchUsers, mockFetchRoles, mockUpdateUserRoles, mockDeleteUser; beforeEach(() => { - mockFetchUsers = jest.fn().mockResolvedValue({ data: mockUsers, last_page: 1 }); + mockFetchUsers = jest + .fn() + .mockResolvedValue({ data: mockUsers, last_page: 1 }); mockFetchRoles = jest.fn().mockResolvedValue(mockRoles); mockUpdateUserRoles = jest.fn().mockResolvedValue({}); mockDeleteUser = jest.fn().mockResolvedValue({}); @@ -40,10 +51,10 @@ describe("UsersPage Component", () => { test("renders user list and roles dropdown correctly", async () => { render(); - + // Check loading state expect(screen.getByTestId("loading-users")).toBeInTheDocument(); - + await waitFor(() => { expect(mockFetchUsers).toHaveBeenCalledTimes(1); expect(screen.queryByTestId("loading-users")).not.toBeInTheDocument(); @@ -52,7 +63,7 @@ describe("UsersPage Component", () => { // Verify user data expect(screen.getByText("John Doe")).toBeInTheDocument(); expect(screen.getByText("Jane Smith")).toBeInTheDocument(); - + // Verify role selects expect(screen.getByTestId("role-select-1")).toBeInTheDocument(); expect(screen.getByTestId("role-select-2")).toBeInTheDocument(); @@ -64,10 +75,10 @@ describe("UsersPage Component", () => { await waitFor(() => expect(mockFetchUsers).toHaveBeenCalledTimes(1)); const roleSelect = await screen.findByTestId("role-select-2"); - fireEvent.change(roleSelect, { target: { value: "Editor" } }); + fireEvent.change(roleSelect, { target: { value: "Admin" } }); await waitFor(() => { - expect(mockUpdateUserRoles).toHaveBeenCalledWith(2, ["Editor"]); + expect(mockUpdateUserRoles).toHaveBeenCalledWith(2, ["Admin"]); expect(mockFetchUsers).toHaveBeenCalledTimes(2); }); }); @@ -101,4 +112,4 @@ describe("UsersPage Component", () => { await waitFor(() => expect(mockFetchUsers).toHaveBeenCalledWith(2)); }); -}); \ No newline at end of file +});