Files
salona/tests/ServicesQA.test.tsx
farnoosh-krm cf568fd39b test: add comprehensive test coverage for multiple
components

(fix) - Add new test files for:
  • ActiveAccounts
  • AddService
  • CreateGiftCard
  • CustomerCard
  • CustomerCards
  • DeleteButton
  • EditButton
  • LoyaltyCardListItem
  • MapPicker
  • Services
  • ServicesQA
(fix) - Add axios interceptor mock
(fix) - Add importMetaEnv mock
(fix) - Add environment setup file for test environment
2026-04-12 19:13:00 +03:30

140 lines
3.8 KiB
TypeScript

/**
* @file ServicesQA.test.tsx
* Full stable test suite for ServicesQA component
*/
import { render, screen, fireEvent, act } from "@testing-library/react";
import "@testing-library/jest-dom";
import ServicesQA from "@/apps/new-ui/components/AppointmentComponents/ServicesQA";
// ---------- MOCKS ----------
// Swiper mock
jest.mock("swiper/react", () => ({
Swiper: ({ children }: any) => <div data-testid="swiper">{children}</div>,
SwiperSlide: ({ children }: any) => <div data-testid="slide">{children}</div>,
}));
jest.mock("swiper/modules", () => ({ Navigation: {} }));
// useGetUserInfo mock
jest.mock("@/apps/new-ui/services/User", () => ({
useGetUserInfo: () => ({
data: {
current_user: {
services: [
{ name: "ماساژ", emoji: "💆", price: 200 },
{ name: "مانیکور", emoji: "💅", price: 150 },
{ name: "اصلاح", emoji: "✂️", price: 120 },
],
},
},
}),
}));
// react-router
jest.mock("react-router-dom", () => ({
...jest.requireActual("react-router-dom"),
useLocation: () => ({ pathname: "/dashboard" }),
}));
// AddService mock
jest.mock("@/apps/new-ui/pages/AddService/AddService", () => {
return function MockAddService({ onclick }: any) {
return (
<div data-testid="add-service">
<button data-testid="close-add-service" onClick={onclick}>
close
</button>
</div>
);
};
});
// localStorage mock
beforeEach(() => {
Storage.prototype.getItem = jest.fn(() => null);
Storage.prototype.setItem = jest.fn();
Storage.prototype.removeItem = jest.fn();
});
afterEach(() => {
jest.clearAllMocks();
});
// ------------------------------------------------------
// TESTS
// ------------------------------------------------------
test("renders services from API (useGetUserInfo)", () => {
render(<ServicesQA />);
expect(screen.getByText("ماساژ")).toBeInTheDocument();
expect(screen.getByText("مانیکور")).toBeInTheDocument();
expect(screen.getByText("اصلاح")).toBeInTheDocument();
});
test("selects a service and persists serviceTitle + price", async () => {
const onChange = jest.fn();
render(<ServicesQA onChange={onChange} />);
const manicure = screen.getByText("مانیکور");
await act(async () => {
fireEvent.click(manicure);
});
expect(localStorage.setItem).toHaveBeenCalledWith("serviceTitle", "مانیکور");
expect(localStorage.setItem).toHaveBeenCalledWith("servicePrice", "150");
expect(onChange).toHaveBeenCalledWith("مانیکور");
});
test("opens AddService modal when no services available", async () => {
jest.mocked(Storage.prototype.getItem).mockReturnValue(null);
render(<ServicesQA serviceList={[]} />);
const addBtn = screen.getByText("افزودن خدمات");
await act(async () => {
fireEvent.click(addBtn);
});
expect(screen.getByTestId("add-service")).toBeInTheDocument();
});
test("closing AddService modal via overlay click", async () => {
render(<ServicesQA serviceList={[]} />);
await act(async () => {
fireEvent.click(screen.getByText("افزودن خدمات"));
});
// modal should exist
expect(screen.getByTestId("add-service")).toBeInTheDocument();
// click backdrop
const backdrop = document.querySelector(".fixed");
await act(async () => {
fireEvent.click(backdrop!);
});
});
test("closing AddService modal via X button inside mock AddService", async () => {
render(<ServicesQA serviceList={[]} />);
await act(async () => {
fireEvent.click(screen.getByText("افزودن خدمات"));
});
expect(screen.getByTestId("add-service")).toBeInTheDocument();
await act(async () => {
fireEvent.click(screen.getByTestId("close-add-service"));
});
expect(screen.queryByTestId("add-service")).toBeNull();
});