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
159 lines
4.1 KiB
TypeScript
159 lines
4.1 KiB
TypeScript
import { render, screen, fireEvent, act } from "@testing-library/react";
|
|
import { useGetUserInfo } from "@/apps/new-ui/services/User";
|
|
import Services from "@/apps/new-ui/components/AppointmentComponents/Services";
|
|
|
|
// ---- MOCKS ----
|
|
|
|
// mock Swiper to avoid DOM errors
|
|
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: {},
|
|
Autoplay: {},
|
|
}));
|
|
|
|
// mock VoiceSearchInput
|
|
jest.mock("@/apps/new-ui/components/VoiceSearchInput", () => {
|
|
return function MockVoiceInput(props: any) {
|
|
return (
|
|
<input
|
|
data-testid="voice-input"
|
|
value={props.value}
|
|
placeholder={props.placeholder}
|
|
onChange={(e) => props.onChange(e.target.value)}
|
|
/>
|
|
);
|
|
};
|
|
});
|
|
|
|
|
|
// mock AddService modal
|
|
jest.mock("@/apps/new-ui/pages/AddService/AddService", () => () => (
|
|
<div data-testid="add-service">AddService Component</div>
|
|
));
|
|
|
|
// mock useGetUserInfo
|
|
jest.mock("@/apps/new-ui/services/User", () => ({
|
|
useGetUserInfo: jest.fn(),
|
|
}));
|
|
|
|
// Helper localStorage mock
|
|
const localStore: Record<string, string> = {};
|
|
beforeEach(() => {
|
|
localStorage.clear();
|
|
Object.keys(localStore).forEach((k) => delete localStore[k]);
|
|
|
|
jest.spyOn(window.localStorage.__proto__, "getItem").mockImplementation(
|
|
(...args: any[]) => {
|
|
const key = args[0];
|
|
return localStore[key] || null;
|
|
}
|
|
);
|
|
|
|
jest.spyOn(window.localStorage.__proto__, "setItem").mockImplementation(
|
|
(...args: any[]) => {
|
|
const [key, value] = args;
|
|
localStore[key] = value;
|
|
}
|
|
);
|
|
|
|
jest.spyOn(window.localStorage.__proto__, "removeItem").mockImplementation(
|
|
(...args: any[]) => {
|
|
const key = args[0];
|
|
delete localStore[key];
|
|
}
|
|
);
|
|
});
|
|
|
|
|
|
// test data
|
|
const mockServices = [
|
|
{ emoji: "💆♀️", name: "ماساژ", price: 200 },
|
|
{ emoji: "💅", name: "مانیکور", price: 150 },
|
|
{ emoji: "💇♀️", name: "اصلاح", price: 100 },
|
|
];
|
|
|
|
describe("Services Component", () => {
|
|
beforeEach(() => {
|
|
(useGetUserInfo as jest.Mock).mockReturnValue({
|
|
data: {
|
|
current_user: {
|
|
services: mockServices,
|
|
},
|
|
},
|
|
});
|
|
});
|
|
|
|
test("renders services from API", () => {
|
|
render(<Services />);
|
|
|
|
expect(screen.getByTestId("swiper")).toBeInTheDocument();
|
|
expect(screen.getAllByTestId("slide").length).toBe(3);
|
|
|
|
expect(screen.getByText("ماساژ")).toBeInTheDocument();
|
|
expect(screen.getByText("مانیکور")).toBeInTheDocument();
|
|
});
|
|
|
|
test("filters services when search input changes", () => {
|
|
render(<Services />);
|
|
|
|
const input = screen.getByTestId("voice-input");
|
|
fireEvent.change(input, { target: { value: "اص" } });
|
|
|
|
expect(screen.getByText("اصلاح")).toBeInTheDocument();
|
|
expect(screen.queryByText("مانیکور")).toBeNull();
|
|
expect(screen.queryByText("ماساژ")).toBeNull();
|
|
|
|
});
|
|
beforeEach(() => {
|
|
localStorage.clear();
|
|
jest.spyOn(localStorage.__proto__, "setItem");
|
|
});
|
|
|
|
afterEach(() => {
|
|
jest.restoreAllMocks();
|
|
});
|
|
|
|
test("selecting a service updates localStorage and dispatches event", async () => {
|
|
const eventSpy = jest.fn();
|
|
window.addEventListener("serviceSelected", eventSpy);
|
|
|
|
render(<Services />);
|
|
|
|
await act(async () => {
|
|
await new Promise((r) => setTimeout(r, 0));
|
|
});
|
|
|
|
eventSpy.mockClear();
|
|
|
|
const manicureItem = screen.getByText("مانیکور");
|
|
|
|
await act(async () => {
|
|
fireEvent.click(manicureItem);
|
|
});
|
|
|
|
expect(eventSpy).toHaveBeenCalled();
|
|
expect(localStorage.setItem).toHaveBeenCalledWith("serviceTitle", "مانیکور");
|
|
});
|
|
|
|
|
|
test("opens AddService modal when add button clicked", () => {
|
|
const dispatchSpy = jest.fn();
|
|
|
|
render(<Services dispatchEvent={dispatchSpy} />);
|
|
|
|
const addButton = screen.getByAltText("add service");
|
|
expect(addButton).toBeInTheDocument();
|
|
|
|
act(() => {
|
|
fireEvent.click(addButton);
|
|
});
|
|
|
|
expect(dispatchSpy).toHaveBeenCalledWith("OPEN");
|
|
expect(screen.getByTestId("add-service")).toBeInTheDocument();
|
|
});
|
|
});
|