(fix): add appointment code in requests and profile completion reward (test): add test coverage for multiple pages and components (fix) - Added appointment code to the Requests section (fix) - Added "Claim Gift" feature for completing the profile (test) Added tests for the following pages/components: 1- Active Devices 2- Add Service 3- Appointment Request (cards display section) 4- Create Gift Card 5- Customer List component (used in Quick Booking, Advanced Booking, etc.) 6- Customer List in Customer Club 7- Delete and Edit buttons (used across the entire app) 8- Invoice 9- Create Individual Schedule Table 10- Notification SMS in SMS Center 11- Loyalty Card List 12- Loyal Customers in ResAssistant 13- Map component 14- Staff List in Staff Management 15- Services List (used in General Link, Custom Link, Advanced Booking, etc.) 16- Services List (used in Quick Booking, Gift Card, Discount Center, etc.)
247 lines
7.4 KiB
TypeScript
247 lines
7.4 KiB
TypeScript
import { render, screen, fireEvent } from "@testing-library/react";
|
|
import PersonnelCard, {
|
|
PersonnelSimple,
|
|
} from "@/apps/new-ui/pages/Personnel/+components/PersonnelCard";
|
|
import {
|
|
useDeletePersonel,
|
|
useGetPersonelExtraInformation,
|
|
} from "@/apps/new-ui/services/PersonnelServices";
|
|
import { showWarningAlert } from "@/apps/new-ui/components/CustomAlert";
|
|
import { notifyOnce } from "@/lib/toastManager-2";
|
|
import { useNavigate } from "react-router-dom";
|
|
|
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
|
|
const queryClient = new QueryClient();
|
|
|
|
window.scrollTo = jest.fn();
|
|
|
|
jest.mock("../src/apps/new-ui/Utils/env.ts", () => ({
|
|
ENV: {
|
|
API_URL: "https://api.test",
|
|
},
|
|
}));
|
|
|
|
jest.mock("@/utils/axios-interceptor", () => ({
|
|
appointmentClient: {
|
|
get: jest.fn(),
|
|
post: jest.fn(),
|
|
put: jest.fn(),
|
|
delete: jest.fn(),
|
|
},
|
|
}));
|
|
|
|
// ------------------ Mock فایلها و کتابخانهها ------------------
|
|
jest.mock("@/apps/new-ui/assets/profilePhoto.svg", () => "mock-avatar");
|
|
|
|
jest.mock("@/apps/new-ui/services/PersonnelServices", () => ({
|
|
useDeletePersonel: jest.fn(),
|
|
useGetPersonelExtraInformation: jest.fn(),
|
|
useGetPersonel: jest.fn(() => ({
|
|
data: {
|
|
services: [],
|
|
duration_days: 20,
|
|
appointments_count: 5,
|
|
remaind_fee: 800000,
|
|
},
|
|
refetch: jest.fn(),
|
|
})),
|
|
}));
|
|
|
|
jest.mock("@/apps/new-ui/services/PersonnelServices", () => ({
|
|
useDeletePersonel: jest.fn(() => ({ mutate: jest.fn() })),
|
|
useGetPersonelExtraInformation: jest.fn(() => ({
|
|
data: { duration_days: 20, appointments_count: 5, remaind_fee: 800000 },
|
|
})),
|
|
useGetPersonel: jest.fn(() => ({
|
|
data: {
|
|
services: [],
|
|
duration_days: 20,
|
|
appointments_count: 5,
|
|
remaind_fee: 800000,
|
|
},
|
|
refetch: jest.fn(),
|
|
})),
|
|
useAddServiceToPersonel: jest.fn(() => ({ mutate: jest.fn() })),
|
|
useDeletePersonelService: jest.fn(() => ({ mutate: jest.fn() })),
|
|
}));
|
|
|
|
jest.mock(
|
|
"@/apps/new-ui/pages/Personnel/+components/ManageServicesModal",
|
|
() => () => <div>ManageServicesModal</div>,
|
|
);
|
|
|
|
jest.mock("@/apps/new-ui/components/CustomAlert", () => ({
|
|
showWarningAlert: jest.fn(),
|
|
}));
|
|
|
|
jest.mock("@/lib/toastManager-2", () => ({
|
|
notifyOnce: jest.fn(),
|
|
}));
|
|
|
|
jest.mock("react-router-dom", () => ({
|
|
...jest.requireActual("react-router-dom"),
|
|
useNavigate: jest.fn(),
|
|
useLocation: jest.fn(() => ({ pathname: "/" })),
|
|
}));
|
|
|
|
// mock محیط VITE (import.meta.env)
|
|
(global as any).import = {
|
|
meta: {
|
|
env: {
|
|
VITE_APP_API_URL: "http://localhost:3000",
|
|
},
|
|
},
|
|
};
|
|
|
|
// ------------------ داده پیشفرض ------------------
|
|
const mockPersonel: PersonnelSimple = {
|
|
personel_id: 10,
|
|
first_name: "امیر",
|
|
last_name: "عباسی",
|
|
score: 4.5,
|
|
total_appointments: 5,
|
|
services: [{ service_name: "اصلاح", type_of_service: "hair", price: 120000 }],
|
|
};
|
|
|
|
// ------------------ mocks ------------------
|
|
const mockNavigate = jest.fn();
|
|
const mockDeleteMutate = jest.fn();
|
|
|
|
describe("PersonnelCard Component", () => {
|
|
beforeEach(() => {
|
|
jest.clearAllMocks();
|
|
|
|
(useNavigate as jest.Mock).mockReturnValue(mockNavigate);
|
|
(useDeletePersonel as jest.Mock).mockReturnValue({
|
|
mutate: mockDeleteMutate,
|
|
});
|
|
|
|
(useGetPersonelExtraInformation as jest.Mock).mockReturnValue({
|
|
data: {
|
|
duration_days: 20,
|
|
appointments_count: 5,
|
|
remaind_fee: 800000,
|
|
},
|
|
});
|
|
});
|
|
|
|
const renderCard = () =>
|
|
render(
|
|
<QueryClientProvider client={queryClient}>
|
|
<PersonnelCard personel={mockPersonel} onClick={jest.fn()} />
|
|
</QueryClientProvider>,
|
|
);
|
|
|
|
// -------------------------------------------------------------
|
|
test("کارت پرسنل بهدرستی رندر میشود", () => {
|
|
renderCard();
|
|
|
|
expect(screen.getByText("امیر عباسی")).toBeInTheDocument();
|
|
screen.getAllByText("4.5").forEach((el) => {
|
|
expect(el).toBeInTheDocument();
|
|
});
|
|
|
|
expect(screen.getByText("مدیریت خدمات")).toBeInTheDocument();
|
|
});
|
|
|
|
// -------------------------------------------------------------
|
|
test("باز و بسته شدن آکاردئون کار میکند", () => {
|
|
renderCard();
|
|
|
|
const trigger = screen.getByText("امیر عباسی").closest("[role='button']")!;
|
|
|
|
// پیدا کردن کانتینر آکاردئون (نه کارت)
|
|
const accordion = document.querySelector(
|
|
"div.w-full.mx-auto.transition-all.overflow-hidden",
|
|
) as HTMLElement;
|
|
|
|
expect(accordion).toHaveClass("h-0");
|
|
|
|
fireEvent.click(trigger);
|
|
expect(accordion).not.toHaveClass("h-0");
|
|
|
|
fireEvent.click(trigger);
|
|
expect(accordion).toHaveClass("h-0");
|
|
});
|
|
|
|
// -------------------------------------------------------------
|
|
|
|
test("باز شدن مودال مدیریت خدمات", () => {
|
|
renderCard();
|
|
|
|
fireEvent.click(screen.getByText("مدیریت خدمات"));
|
|
|
|
expect(screen.getByText("ManageServicesModal")).toBeInTheDocument();
|
|
});
|
|
|
|
// -------------------------------------------------------------
|
|
test("باز شدن منوی سهنقطه (portal) و اجرای گزینههای آن", () => {
|
|
const mockOnClick = jest.fn();
|
|
|
|
render(<PersonnelCard personel={mockPersonel} onClick={mockOnClick} />);
|
|
|
|
const menuBtn = screen.getByRole("button", { name: "" });
|
|
fireEvent.click(menuBtn);
|
|
|
|
// گزینههای منو ظاهر شوند
|
|
expect(screen.getByText("تنظیمات")).toBeInTheDocument();
|
|
expect(screen.getByText("ویرایش")).toBeInTheDocument();
|
|
expect(screen.getByText("حذف")).toBeInTheDocument();
|
|
expect(screen.getByText("تماس")).toBeInTheDocument();
|
|
|
|
// تست تنظیمات
|
|
fireEvent.click(screen.getByText("تنظیمات"));
|
|
expect(mockOnClick).toHaveBeenCalledWith(10);
|
|
});
|
|
|
|
// -------------------------------------------------------------
|
|
test("دکمه ویرایش باید به /personnel/add?id=ID ناوبری کند", () => {
|
|
renderCard();
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "" })); // سهنقطه
|
|
fireEvent.click(screen.getByText("ویرایش"));
|
|
|
|
expect(mockNavigate).toHaveBeenCalledWith("/personnel/add?id=10");
|
|
});
|
|
|
|
// -------------------------------------------------------------
|
|
test("دکمه حذف alert را نمایش میدهد و سپس mutation اجرا میشود", () => {
|
|
renderCard();
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "" }));
|
|
fireEvent.click(screen.getByText("حذف"));
|
|
|
|
expect(showWarningAlert).toHaveBeenCalled();
|
|
|
|
// اجرای callback حذف
|
|
const approveCallback = (showWarningAlert as jest.Mock).mock.calls[0][1];
|
|
approveCallback();
|
|
|
|
expect(mockDeleteMutate).toHaveBeenCalledWith(10);
|
|
});
|
|
|
|
// -------------------------------------------------------------
|
|
test("در صورت نبود شماره تماس، notifyOnce اجرا میشود", () => {
|
|
const personelWithoutPhone = { ...mockPersonel, phone_number: undefined };
|
|
|
|
render(
|
|
<PersonnelCard personel={personelWithoutPhone} onClick={jest.fn()} />,
|
|
);
|
|
|
|
fireEvent.click(screen.getByRole("button", { name: "" }));
|
|
fireEvent.click(screen.getByText("تماس"));
|
|
|
|
expect(notifyOnce).toHaveBeenCalled();
|
|
});
|
|
|
|
// -------------------------------------------------------------
|
|
test("باز شدن مودال مدیریت خدمات", () => {
|
|
renderCard();
|
|
|
|
fireEvent.click(screen.getByText("مدیریت خدمات"));
|
|
|
|
expect(screen.getByText(/ManageServicesModal/i)).toBeInTheDocument();
|
|
});
|
|
});
|