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}
- |
-
- |
@@ -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)}
/>