import CalendarSelection from "@/components/Calendar/CalendarSelection"; import * as calendarThunks from "@/features/Calendars/services"; import "@testing-library/jest-dom"; import { cleanup, fireEvent, screen, waitFor } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { renderWithProviders } from "../utils/Renderwithproviders"; describe("CalendarSelection", () => { beforeEach(() => { localStorage.clear(); }); const baseUser = { userData: { sub: "test", email: "test@test.com", sid: "mockSid", openpaasId: "user1", }, tokens: { accessToken: "token" }, }; const calendarsMock = { "user1/cal1": { name: "Calendar personal", id: "user1/cal1", color: "#FF0000", ownerEmails: ["alice@example.com"], }, "user2/cal1": { name: "Calendar delegated", delegated: true, id: "user2/cal1", color: "#00FF00", ownerEmails: ["bob@example.com"], }, "user3/cal1": { name: "Calendar shared", id: "user3/cal1", color: "#0000FF", ownerEmails: ["charlie@example.com"], }, }; beforeAll(() => { jest.clearAllMocks(); cleanup(); }); it("renders personal, delegated and calendar.other", () => { renderWithProviders( , { user: baseUser, calendars: { list: calendarsMock, pending: false }, } ); expect(screen.getByText("calendar.personal")).toBeInTheDocument(); expect(screen.getByText("calendar.delegated")).toBeInTheDocument(); expect(screen.getByText("calendar.other")).toBeInTheDocument(); expect(screen.getByLabelText("Calendar personal")).toBeChecked(); expect(screen.getByLabelText("Calendar delegated")).not.toBeChecked(); expect(screen.getByLabelText("Calendar shared")).not.toBeChecked(); }); it("toggles a calendar selection on click", () => { const setSelectedCalendars = jest.fn(); renderWithProviders( , { user: baseUser, calendars: { list: calendarsMock, pending: false }, } ); const checkbox = screen.getByLabelText("Calendar personal"); fireEvent.click(checkbox); expect(setSelectedCalendars).toHaveBeenCalledWith(expect.any(Function)); const updater = setSelectedCalendars.mock.calls[0][0]; expect(updater([])).toEqual(["user1/cal1"]); }); it("removes calendar from selection if already selected", () => { const setSelectedCalendars = jest.fn(); renderWithProviders( , { user: baseUser, calendars: { list: calendarsMock, pending: false }, } ); const checkbox = screen.getByLabelText("Calendar personal"); fireEvent.click(checkbox); const updater = setSelectedCalendars.mock.calls[0][0]; expect(updater(["user1/cal1"])).toEqual([]); }); it("opens CalendarPopover modal when personal Add button is clicked", async () => { renderWithProviders( , { user: baseUser, calendars: { list: calendarsMock, pending: false }, } ); const addButtons = screen.getAllByRole("button"); fireEvent.click(addButtons[1]); await waitFor(() => expect( screen.getByText("calendarPopover.tabs.addNew") ).toBeInTheDocument() ); }); it("Navigates to deletion dialog and deletes personal cal", async () => { const spy = jest .spyOn(calendarThunks, "removeCalendarAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); renderWithProviders( , { user: baseUser, calendars: { list: calendarsMock, pending: false }, } ); const addButtons = screen.getAllByTestId("MoreVertIcon"); fireEvent.click(addButtons[0]); userEvent.click(screen.getByText(/delete/i)); await waitFor(() => expect( screen.getByText("calendar.delete.title(name=Calendar personal)") ).toBeInTheDocument() ); fireEvent.click(screen.getByRole("button", { name: /delete/i })); await waitFor(() => expect(spy).toHaveBeenCalled()); }); it("Navigates to deletion dialog and deletes other cal", async () => { const spy = jest .spyOn(calendarThunks, "removeCalendarAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); renderWithProviders( , { user: baseUser, calendars: { list: calendarsMock, pending: false }, } ); const addButtons = screen.getAllByTestId("MoreVertIcon"); fireEvent.click(addButtons[1]); userEvent.click(screen.getByText(/remove/i)); await waitFor(() => expect( screen.getByText("calendar.delete.title(name=Calendar delegated)") ).toBeInTheDocument() ); fireEvent.click(screen.getByRole("button", { name: /remove/i })); await waitFor(() => expect(spy).toHaveBeenCalled()); }); it("opens CalendarSearch modal when Other Add button is clicked", () => { renderWithProviders( , { user: baseUser, calendars: { list: calendarsMock, pending: false }, } ); const addButtons = screen.getAllByTestId("AddIcon"); fireEvent.click(addButtons[1]); // seccond Add button (other) expect( screen.getByText("calendar.browseOtherCalendars") ).toBeInTheDocument(); }); it("when only calendar.personal are in the state, only calendar.personal and the title for other to be added are shown", () => { renderWithProviders( , { user: baseUser, calendars: { list: { "user1/cal1": calendarsMock["user1/cal1"], }, pending: false, }, } ); expect(screen.getByText("calendar.personal")).toBeInTheDocument(); expect(screen.queryByText("calendar.delegated")).not.toBeInTheDocument(); expect(screen.queryByText("calendar.other")).toBeInTheDocument(); }); it("renders nothing when no calendars are present", () => { renderWithProviders( , { user: baseUser, calendars: { list: {}, pending: false }, } ); expect(screen.queryByLabelText(/Calendar/)).not.toBeInTheDocument(); }); it("expands and collapses accordions when clicked", () => { renderWithProviders( , { user: baseUser, calendars: { list: calendarsMock, pending: false }, } ); const delegatedAccordionSummary = screen .getByText("calendar.delegated") .closest(".MuiAccordionSummary-root"); fireEvent.click(delegatedAccordionSummary!); expect(delegatedAccordionSummary).toHaveAttribute("aria-expanded", "true"); fireEvent.click(delegatedAccordionSummary!); expect(delegatedAccordionSummary).toHaveAttribute("aria-expanded", "false"); }); });