diff --git a/__tests__/UsersPage.test.js b/__tests__/UsersPage.test.js new file mode 100644 index 0000000..34c2467 --- /dev/null +++ b/__tests__/UsersPage.test.js @@ -0,0 +1,115 @@ +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" }, +]; + +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: "Admin" } }); + + await waitFor(() => { + expect(mockUpdateUserRoles).toHaveBeenCalledWith(2, ["Admin"]); + 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)); + }); +}); 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)} />