import { render, screen, fireEvent, waitFor } from "@testing-library/react"; import MapPicker from "@/apps/new-ui/components/CustomeComponents/MapPicker"; import { notifyOnce } from "@/lib/toastManager-2"; jest.mock("@/lib/toastManager-2", () => ({ notifyOnce: jest.fn(), })); // mock map component jest.mock("@neshan-maps-platform/react-openlayers", () => { return ({ onInit }: any) => { const fakeMap = { addLayer: jest.fn(), on: jest.fn(), getView: () => ({ animate: jest.fn(), }), }; if (onInit) { setTimeout(() => onInit(fakeMap), 0); } return
; }; }); jest.mock("@neshan-maps-platform/ol", () => ({})); // Mock OpenLayers / Neshan OL constructors correctly jest.mock("@neshan-maps-platform/ol/style/Icon", () => { return jest.fn().mockImplementation(() => ({ // هرچیزی لازم نیست، فقط باید constructor باشد })); }); jest.mock("@neshan-maps-platform/ol/style/Style", () => { return jest.fn().mockImplementation(() => ({})); }); jest.mock("@neshan-maps-platform/ol/Feature", () => { return jest.fn().mockImplementation(() => ({ setStyle: jest.fn(), getGeometry: () => ({ setCoordinates: jest.fn(), }), })); }); jest.mock("@neshan-maps-platform/ol/geom/Point", () => { return jest.fn().mockImplementation(() => ({})); }); jest.mock("@neshan-maps-platform/ol/source/Vector", () => { return jest.fn().mockImplementation(() => ({ // فقط وجود داشته باشد کافیست })); }); jest.mock("@neshan-maps-platform/ol/layer/Vector", () => { return jest.fn().mockImplementation(() => ({ // فقط وجود داشته باشد کافیست })); }); jest.mock("@neshan-maps-platform/ol/proj", () => ({ fromLonLat: jest.fn(() => [100, 200]), toLonLat: jest.fn(() => [20, 10]), })); describe("MapPicker", () => { const onChange = jest.fn(); beforeEach(() => { jest.clearAllMocks(); }); it("renders map correctly", () => { render( ); expect(screen.getByTestId("neshan-map")).toBeInTheDocument(); }); it("calls geolocation when location button clicked", async () => { const mockGeo = { getCurrentPosition: jest.fn((success) => success({ coords: { latitude: 10, longitude: 20 }, }) ), }; Object.defineProperty(global.navigator, "geolocation", { value: mockGeo, writable: true, }); render( ); const button = screen.getByRole("button"); fireEvent.click(button); await waitFor(() => { expect(onChange).toHaveBeenCalledWith(10, 20); }); }); it("shows error toast when geolocation permission denied", async () => { const mockGeo = { getCurrentPosition: jest.fn((_success, error) => { error({ code: 1 }); // PERMISSION DENIED }), }; Object.defineProperty(global.navigator, "geolocation", { value: mockGeo, writable: true, }); Object.defineProperty(global.navigator, "permissions", { value: { query: jest.fn().mockResolvedValue({ state: "granted", }), }, writable: true, }); render( ); fireEvent.click(screen.getByRole("button")); await waitFor(() => { expect(notifyOnce).toHaveBeenCalled(); }); }); it("shows loading state when locating", () => { const mockGeo = { getCurrentPosition: jest.fn(), }; Object.defineProperty(global.navigator, "geolocation", { value: mockGeo, writable: true, }); render( ); const button = screen.getByRole("button"); fireEvent.click(button); expect(button).toHaveTextContent("..."); }); });