import CalendarResources from "@/components/Calendar/CalendarResources"; import { getCalendars } from "@/features/Calendars/CalendarApi"; import { addCalendarResourceAsync } from "@/features/Calendars/api/addCalendarResourceAsync"; import { act, fireEvent, screen, waitFor } from "@testing-library/react"; import { renderWithProviders } from "../utils/Renderwithproviders"; jest.mock("@/features/Calendars/CalendarApi"); jest.mock("@/features/Calendars/api/addCalendarResourceAsync"); jest.mock("@/components/Attendees/ResourceSearch", () => ({ ResourceSearch: ({ onChange, }: { onChange: ( event: null, value: { displayName: string; openpaasId: string }[] ) => void; }) => (
), })); const mockedGetCalendars = getCalendars as jest.Mock; const mockedAddCalendarResourceAsync = addCalendarResourceAsync as unknown as jest.Mock; describe("CalendarResources", () => { beforeEach(() => { jest.clearAllMocks(); }); const baseUser = { userData: { sub: "test", email: "test@test.com", sid: "mockSid", openpaasId: "user1", }, tokens: { accessToken: "token" }, }; const setup = (isOpen = true) => { const onClose = jest.fn(); renderWithProviders(, { user: baseUser, }); return { onClose }; }; it("renders correctly and closes on cancel", () => { const { onClose } = setup(); expect(screen.getByText("calendar.browseResources")).toBeInTheDocument(); const cancelButton = screen.getByRole("button", { name: "common.cancel", }); fireEvent.click(cancelButton); expect(onClose).toHaveBeenCalled(); }); it("does not render when isOpen is false", () => { setup(false); expect( screen.queryByText("calendar.browseResources") ).not.toBeInTheDocument(); }); it("fetches resource calendars and adds them using Promise.allSettled logic", async () => { const mockCalendarDataA = { _embedded: { "dav:calendar": [ { _links: { self: { href: "/calendars/room-a-id/cal-a.json" } }, "dav:name": "Room A Calendar", "caldav:description": "Main room A calendar", color: "red", }, ], }, }; mockedGetCalendars.mockImplementation((userId) => { if (userId === "room-a-id") return Promise.resolve(mockCalendarDataA); // Simulate failure for room-b if (userId === "room-b-id") return Promise.reject(new Error("Failed fetching Room B")); return Promise.resolve([]); }); const mockDispatchResult = { unwrap: () => Promise.resolve({ type: "success" }), }; mockedAddCalendarResourceAsync.mockReturnValue(() => mockDispatchResult); const { onClose } = setup(); // Trigger resource selection const mockSelectBtn = screen.getByTestId("mock-resource-search-select"); await act(async () => { fireEvent.click(mockSelectBtn); }); // After selection, the button should be enabled and say Add const addButton = await screen.findByRole("button", { name: "actions.add", }); expect(addButton).not.toBeDisabled(); // Click add to trigger addCalendarResourceAsync await act(async () => { fireEvent.click(addButton); }); await waitFor(() => { // It should only have been called for Room A because Room B failed (Promise.allSettled) expect(mockedAddCalendarResourceAsync).toHaveBeenCalledTimes(1); const payload = mockedAddCalendarResourceAsync.mock.calls[0][0]; expect(payload).toEqual( expect.objectContaining({ userId: "user1", calId: expect.any(String), cal: expect.objectContaining({ cal: mockCalendarDataA._embedded["dav:calendar"][0], }), }) ); }); expect(onClose).toHaveBeenCalled(); }); it("adds existing user details fallback logic within submit handler", async () => { const mockCalendarDataA = { _embedded: { "dav:calendar": [ { _links: { self: { href: "/calendars/room-a-id/cal-a.json" } }, "dav:name": "Room A Calendar", "caldav:description": "Main room A calendar", color: "red", }, ], }, }; mockedGetCalendars.mockResolvedValueOnce(mockCalendarDataA); mockedGetCalendars.mockResolvedValueOnce([]); // Mock array of size 2 (for both A and B but second resolves empty) // Simulate successful API response const mockDispatchResult = { unwrap: () => Promise.resolve(), }; mockedAddCalendarResourceAsync.mockReturnValue(() => mockDispatchResult); const { onClose } = setup(); // Trigger resource selection const mockSelectBtn = screen.getByTestId("mock-resource-search-select"); await act(async () => { fireEvent.click(mockSelectBtn); }); const addButton = await screen.findByRole("button", { name: "actions.add", }); await act(async () => { fireEvent.click(addButton); }); await waitFor(() => { expect(onClose).toHaveBeenCalled(); }); }); });