import { screen, fireEvent, waitFor } from "@testing-library/react"; import * as eventThunks from "../../../src/features/Calendars/CalendarSlice"; import { renderWithProviders } from "../../utils/Renderwithproviders"; import EventDisplayModal from "../../../src/features/Events/EventDisplay"; import { EditModeDialog } from "../../../src/components/Event/EditModeDialog"; import * as EventApi from "../../../src/features/Events/EventApi"; import { createEventHandlers, EventHandlersProps, } from "../../../src/components/Calendar/handlers/eventHandlers"; import EventPreviewModal from "../../../src/components/Event/EventDisplayPreview"; describe("Recurrence Event Behavior Tests", () => { const mockOnClose = jest.fn(); const day = new Date("2025-03-15T10:00:00Z"); beforeEach(() => { jest.clearAllMocks(); (window as any).MAIL_SPA_URL = null; }); const basePreloadedState = { user: { userData: { sub: "test", email: "test@test.com", sid: "aiYbWZSk2g0F+LrQeD7Dg4QcUMR8R/zTZdZBiA7N6Ro", openpaasId: "667037022b752d0026472254", }, organiserData: { cn: "test", cal_address: "test@test.com", }, }, calendars: { list: { "667037022b752d0026472254/cal1": { id: "667037022b752d0026472254/cal1", name: "Calendar", color: "#FF0000", events: { "recurring-base/20250315T100000": { uid: "recurring-base/20250315T100000", title: "Recurring Event Instance", calId: "667037022b752d0026472254/cal1", start: day.toISOString(), end: new Date("2025-03-15T11:00:00Z").toISOString(), organizer: { cn: "test", cal_address: "test@test.com" }, recurrenceId: "20250315T100000", timezone: "UTC", URL: "/calendars/667037022b752d0026472254/cal1/recurring-base.ics", attendee: [ { cn: "test", cal_address: "test@test.com", partstat: "NEEDS-ACTION", rsvp: "TRUE", role: "REQ-PARTICIPANT", cutype: "INDIVIDUAL", }, { cn: "John", cal_address: "john@test.com", partstat: "NEEDS-ACTION", rsvp: "TRUE", role: "REQ-PARTICIPANT", cutype: "INDIVIDUAL", }, ], }, "recurring-base/20250322T100000": { uid: "recurring-base/20250322T100000", title: "Recurring Event Instance", calId: "667037022b752d0026472254/cal1", start: new Date("2025-03-22T10:00:00Z").toISOString(), end: new Date("2025-03-22T11:00:00Z").toISOString(), organizer: { cn: "test", cal_address: "test@test.com" }, recurrenceId: "20250322T100000", timezone: "UTC", URL: "/calendars/667037022b752d0026472254/cal1/recurring-base.ics", attendee: [ { cn: "test", cal_address: "test@test.com", partstat: "NEEDS-ACTION", rsvp: "TRUE", role: "REQ-PARTICIPANT", cutype: "INDIVIDUAL", }, ], }, }, }, }, pending: false, templist: {}, }, }; describe("EditModeDialog Component", () => { it("renders dialog when type is 'edit'", () => { const mockSetOpen = jest.fn(); const mockEventAction = jest.fn(); renderWithProviders( , basePreloadedState ); expect( screen.getByText("Update the reccurent event") ).toBeInTheDocument(); expect(screen.getByText("This event")).toBeInTheDocument(); expect(screen.getByText("All the events")).toBeInTheDocument(); }); it("renders dialog when type is 'attendance'", () => { const mockSetOpen = jest.fn(); const mockEventAction = jest.fn(); renderWithProviders( , basePreloadedState ); expect( screen.getByText("Update the participation status") ).toBeInTheDocument(); }); it("calls eventAction with 'solo' when solo option is selected and Ok clicked", async () => { const mockSetOpen = jest.fn(); const mockEventAction = jest.fn(); renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByLabelText("This event")); fireEvent.click(screen.getByText("Ok")); await waitFor(() => { expect(mockEventAction).toHaveBeenCalledWith("solo"); expect(mockSetOpen).toHaveBeenCalledWith(null); }); }); it("calls eventAction with 'all' when all option is selected and Ok clicked", async () => { const mockSetOpen = jest.fn(); const mockEventAction = jest.fn(); renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByLabelText("All the events")); fireEvent.click(screen.getByText("Ok")); await waitFor(() => { expect(mockEventAction).toHaveBeenCalledWith("all"); expect(mockSetOpen).toHaveBeenCalledWith(null); }); }); it("calls setOpen with null when Cancel is clicked", async () => { const mockSetOpen = jest.fn(); const mockEventAction = jest.fn(); renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByText("Cancel")); await waitFor(() => { expect(mockSetOpen).toHaveBeenCalledWith(null); expect(mockEventAction).not.toHaveBeenCalled(); }); }); }); describe("EventPreviewModal - Recurring Event Interactions", () => { it("shows EditModeDialog when editing a recurring event", async () => { jest.spyOn(eventThunks, "getEventAsync").mockImplementation((payload) => { return () => Promise.resolve({ calId: payload.calId, event: basePreloadedState.calendars.list["667037022b752d0026472254/cal1"] .events["recurring-base/20250315T100000"], }) as any; }); renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByTestId("EditIcon")); await waitFor(() => { expect( screen.getByText("Update the reccurent event") ).toBeInTheDocument(); }); }); it("shows EditModeDialog when deleting a recurring event", async () => { renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByTestId("MoreVertIcon")); fireEvent.click(screen.getByText("Delete event")); await waitFor(() => { expect( screen.getByText("Update the reccurent event") ).toBeInTheDocument(); }); }); it("shows EditModeDialog when RSVP to a recurring event", async () => { renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByRole("button", { name: "Accept" })); await waitFor(() => { expect( screen.getByText("Update the participation status") ).toBeInTheDocument(); }); }); it("does not show EditModeDialog for non-recurring events", async () => { const nonRecurringState = { ...basePreloadedState, calendars: { ...basePreloadedState.calendars, list: { "667037022b752d0026472254/cal1": { ...basePreloadedState.calendars.list[ "667037022b752d0026472254/cal1" ], events: { "single-event": { uid: "single-event", title: "Single Event", calId: "667037022b752d0026472254/cal1", start: day.toISOString(), end: new Date("2025-03-15T11:00:00Z").toISOString(), organizer: { cn: "test", cal_address: "test@test.com" }, timezone: "UTC", URL: "/calendars/667037022b752d0026472254/cal1/single-event.ics", attendee: [], }, }, }, }, }, }; const spy = jest .spyOn(eventThunks, "deleteEventAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); renderWithProviders( , nonRecurringState ); fireEvent.click(screen.getByTestId("MoreVertIcon")); fireEvent.click(screen.getByText("Delete event")); await waitFor(() => { expect(spy).toHaveBeenCalled(); expect(mockOnClose).toHaveBeenCalled(); }); expect( screen.queryByText("Update the reccurent event") ).not.toBeInTheDocument(); }); }); describe("Delete Recurring Event Instance", () => { it("calls deleteEventInstanceAsync when deleting single instance", async () => { const spy = jest .spyOn(eventThunks, "deleteEventInstanceAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByTestId("MoreVertIcon")); fireEvent.click(screen.getByText("Delete event")); await waitFor(() => { expect( screen.getByText("Update the reccurent event") ).toBeInTheDocument(); }); fireEvent.click(screen.getByLabelText("This event")); fireEvent.click(screen.getByText("Ok")); await waitFor(() => { expect(spy).toHaveBeenCalled(); }); const receivedPayload = spy.mock.calls[0][0]; expect(receivedPayload.event.uid).toBe("recurring-base/20250315T100000"); }); it("calls deleteEventAsync when deleting all instances", async () => { jest.spyOn(EventApi, "getEvent").mockResolvedValue({ ...basePreloadedState.calendars.list["667037022b752d0026472254/cal1"] .events["recurring-base/20250315T100000"], uid: "recurring-base", } as any); const spy = jest .spyOn(eventThunks, "deleteEventAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByTestId("MoreVertIcon")); fireEvent.click(screen.getByText("Delete event")); await waitFor(() => { expect( screen.getByText("Update the reccurent event") ).toBeInTheDocument(); }); fireEvent.click(screen.getByLabelText("All the events")); fireEvent.click(screen.getByText("Ok")); await waitFor(() => { expect(spy).toHaveBeenCalled(); }); const receivedPayload = spy.mock.calls[0][0]; expect(receivedPayload.eventId).toBe("recurring-base/20250315T100000"); }); }); describe("RSVP to Recurring Event", () => { it("calls updateEventInstanceAsync when accepting single instance", async () => { const spy = jest .spyOn(eventThunks, "updateEventInstanceAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByRole("button", { name: "Accept" })); await waitFor(() => { expect( screen.getByText("Update the participation status") ).toBeInTheDocument(); }); fireEvent.click(screen.getByLabelText("This event")); fireEvent.click(screen.getByText("Ok")); await waitFor(() => { expect(spy).toHaveBeenCalled(); }); const updatedEvent = spy.mock.calls[0][0].event; expect(updatedEvent.attendee[0].partstat).toBe("ACCEPTED"); }); it("calls updateSeriesAsync when accepting all instances", async () => { const getEventSpy = jest.spyOn(EventApi, "getEvent").mockResolvedValue({ ...basePreloadedState.calendars.list["667037022b752d0026472254/cal1"] .events["recurring-base/20250315T100000"], uid: "recurring-base", } as any); const spy = jest .spyOn(eventThunks, "updateSeriesAsync") .mockImplementation((payload) => { return () => Promise.resolve() as any; }); renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByRole("button", { name: "Accept" })); await waitFor(() => { expect( screen.getByText("Update the participation status") ).toBeInTheDocument(); }); fireEvent.click(screen.getByLabelText("All the events")); fireEvent.click(screen.getByText("Ok")); await waitFor(() => { expect(getEventSpy).toHaveBeenCalled(); expect(spy).toHaveBeenCalled(); }); const updatedEvent = spy.mock.calls[0][0].event; expect(updatedEvent.attendee[0].partstat).toBe("ACCEPTED"); }); }); describe("Edit Recurring Event in Full Display", () => { it("renders event with recurrenceId in URL", () => { renderWithProviders( , basePreloadedState ); expect( screen.getByDisplayValue("Recurring Event Instance") ).toBeInTheDocument(); }); it("calls updateEventInstanceAsync when saving single instance with typeOfAction='solo'", async () => { const spy = jest .spyOn(eventThunks, "updateEventInstanceAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); renderWithProviders( , basePreloadedState ); const titleField = screen.getByLabelText("Title"); fireEvent.change(titleField, { target: { value: "Updated Single Instance" }, }); fireEvent.click(screen.getByText("Save")); await waitFor(() => { expect(spy).toHaveBeenCalled(); }); const updatedEvent = spy.mock.calls[0][0].event; expect(updatedEvent.title).toBe("Updated Single Instance"); expect(updatedEvent.recurrenceId).toBe("20250315T100000"); }); it("calls updateSeriesAsync when saving all instances with typeOfAction='all'", async () => { const getEventSpy = jest.spyOn(EventApi, "getEvent").mockResolvedValue({ ...basePreloadedState.calendars.list["667037022b752d0026472254/cal1"] .events["recurring-base/20250315T100000"], uid: "recurring-base", } as any); const spy = jest .spyOn(eventThunks, "updateSeriesAsync") .mockImplementation((payload) => { return () => Promise.resolve() as any; }); renderWithProviders( , basePreloadedState ); await waitFor(() => { expect(getEventSpy).toHaveBeenCalled(); }); const titleField = screen.getByLabelText("Title"); fireEvent.change(titleField, { target: { value: "Updated All Instances" }, }); fireEvent.click(screen.getByText("Save")); await waitFor(() => { expect(spy).toHaveBeenCalled(); }); const updatedEvent = spy.mock.calls[0][0].event; expect(updatedEvent.title).toBe("Updated All Instances"); }); it("disables repetition editing when typeOfAction='solo'", () => { renderWithProviders( , basePreloadedState ); fireEvent.click(screen.getByText("Show More")); expect(screen.getByText(/repeat every/i)).toBeInTheDocument(); expect(screen.getByText(/end:/i)).toBeInTheDocument(); const frequencySelect = screen.getByRole("radio", { name: /after \d occurrences/i, }); expect(frequencySelect).toBeDisabled(); }); it("fetches master event data when typeOfAction='all'", async () => { const getEventSpy = jest.spyOn(EventApi, "getEvent").mockResolvedValue({ ...basePreloadedState.calendars.list["667037022b752d0026472254/cal1"] .events["recurring-base/20250315T100000"], uid: "recurring-base", title: "Master Event Title", description: "Master Description", } as any); renderWithProviders( , basePreloadedState ); await waitFor(() => { expect(getEventSpy).toHaveBeenCalled(); expect( screen.getByDisplayValue("Master Event Title") ).toBeInTheDocument(); }); }); }); describe("Event Drag and Drop - Recurring Events", () => { it("shows EditModeDialog when dragging recurring event", () => { const mockDispatch = jest.fn(); const mockSetSelectedEvent = jest.fn(); const mockSetOpenEditModePopup = jest.fn(); const mockSetAfterChoiceFunc = jest.fn(); const eventHandlers = createEventHandlers({ setSelectedRange: jest.fn(), setOpenEventModal: jest.fn(), setTempEvent: jest.fn(), setOpenEventDisplay: jest.fn(), dispatch: mockDispatch, calendarRange: { start: new Date(), end: new Date() }, setEventDisplayedId: jest.fn(), setEventDisplayedCalId: jest.fn(), setEventDisplayedTemp: jest.fn(), calendars: basePreloadedState.calendars.list, setSelectedEvent: mockSetSelectedEvent, setAfterChoiceFunc: mockSetAfterChoiceFunc, setOpenEditModePopup: mockSetOpenEditModePopup, } as unknown as EventHandlersProps); const mockArg = { event: { _def: { extendedProps: { uid: "recurring-base/20250315T100000", calId: "667037022b752d0026472254/cal1", }, }, }, delta: { years: 0, months: 0, days: 1, milliseconds: 0 }, }; eventHandlers.handleEventDrop(mockArg); expect(mockSetSelectedEvent).toHaveBeenCalled(); expect(mockSetOpenEditModePopup).toHaveBeenCalledWith("edit"); expect(mockSetAfterChoiceFunc).toHaveBeenCalled(); }); it("directly updates non-recurring event on drag", () => { const mockDispatch = jest.fn(); const nonRecurringState = { "667037022b752d0026472254/cal1": { ...basePreloadedState.calendars.list["667037022b752d0026472254/cal1"], events: { "single-event": { uid: "single-event", title: "Single Event", calId: "667037022b752d0026472254/cal1", start: day.toISOString(), end: new Date("2025-03-15T11:00:00Z").toISOString(), timezone: "UTC", }, }, }, }; const eventHandlers = createEventHandlers({ setSelectedRange: jest.fn(), setOpenEventModal: jest.fn(), setTempEvent: jest.fn(), setOpenEventDisplay: jest.fn(), dispatch: mockDispatch, calendarRange: { start: new Date(), end: new Date() }, setEventDisplayedId: jest.fn(), setEventDisplayedCalId: jest.fn(), setEventDisplayedTemp: jest.fn(), calendars: nonRecurringState, setSelectedEvent: jest.fn(), setAfterChoiceFunc: jest.fn(), setOpenEditModePopup: jest.fn(), } as unknown as EventHandlersProps); const mockArg = { event: { _def: { extendedProps: { uid: "single-event", calId: "667037022b752d0026472254/cal1", }, }, }, delta: { years: 0, months: 0, days: 1, milliseconds: 0 }, }; eventHandlers.handleEventDrop(mockArg); expect(mockDispatch).toHaveBeenCalledWith( expect.objectContaining({ type: expect.stringContaining("updateEventLocal"), }) ); }); }); describe("Event Resize - Recurring Events", () => { it("shows EditModeDialog when resizing recurring event", () => { const mockDispatch = jest.fn(); const mockSetSelectedEvent = jest.fn(); const mockSetOpenEditModePopup = jest.fn(); const mockSetAfterChoiceFunc = jest.fn(); const eventHandlers = createEventHandlers({ setSelectedRange: jest.fn(), setOpenEventModal: jest.fn(), setTempEvent: jest.fn(), setOpenEventDisplay: jest.fn(), dispatch: mockDispatch, calendarRange: { start: new Date(), end: new Date() }, setEventDisplayedId: jest.fn(), setEventDisplayedCalId: jest.fn(), setEventDisplayedTemp: jest.fn(), calendars: basePreloadedState.calendars.list, setSelectedEvent: mockSetSelectedEvent, setAfterChoiceFunc: mockSetAfterChoiceFunc, setOpenEditModePopup: mockSetOpenEditModePopup, } as unknown as EventHandlersProps); const mockArg = { event: { _def: { extendedProps: { uid: "recurring-base/20250315T100000", calId: "667037022b752d0026472254/cal1", }, }, }, startDelta: { years: 0, months: 0, days: 0, milliseconds: 0 }, endDelta: { years: 0, months: 0, days: 0, milliseconds: 3600000 }, // 1 hour }; eventHandlers.handleEventResize(mockArg); expect(mockSetSelectedEvent).toHaveBeenCalled(); expect(mockSetOpenEditModePopup).toHaveBeenCalledWith("edit"); expect(mockSetAfterChoiceFunc).toHaveBeenCalled(); }); }); describe("RepeatEvent Component - Recurrence Editing", () => { it("disables repetition fields when isOwn is false", () => { renderWithProviders( , { ...basePreloadedState, calendars: { ...basePreloadedState.calendars, list: { "otherCal/cal": { id: "otherCal/cal", name: "Other Calendar", color: "#00FF00", events: { "recurring-base/20250315T100000": { ...basePreloadedState.calendars.list[ "667037022b752d0026472254/cal1" ].events["recurring-base/20250315T100000"], calId: "otherCal/cal", organizer: { cn: "other", cal_address: "other@test.com" }, }, }, }, }, }, } ); fireEvent.click(screen.getByText("Show More")); // Repetition section should not be visible for non-owner expect(screen.queryByLabelText(/Repetition/i)).not.toBeInTheDocument(); }); }); describe("handleRSVP function", () => { it("calls putEventAsync for non-recurring events", async () => { const mockDispatch = jest.fn(); const mockOnClose = jest.fn(); const { handleRSVP, } = require("../../../src/components/Event/eventHandlers/eventHandlers"); jest.spyOn(eventThunks, "putEventAsync").mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); const nonRecurringEvent = { uid: "single-event", title: "Single Event", calId: "667037022b752d0026472254/cal1", start: day.toISOString(), end: new Date("2025-03-15T11:00:00Z").toISOString(), organizer: { cn: "test", cal_address: "test@test.com" }, attendee: [ { cn: "test", cal_address: "test@test.com", partstat: "NEEDS-ACTION", }, ], }; await handleRSVP( mockDispatch, basePreloadedState.calendars.list["667037022b752d0026472254/cal1"], basePreloadedState.user, nonRecurringEvent, "ACCEPTED", mockOnClose ); expect(mockDispatch).toHaveBeenCalled(); }); }); describe("handleDelete function", () => { it("calls deleteEventAsync for non-recurring events", () => { const mockDispatch = jest.fn(); const mockOnClose = jest.fn(); const { handleDelete, } = require("../../../src/components/Event/eventHandlers/eventHandlers"); jest .spyOn(eventThunks, "deleteEventAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); const nonRecurringEvent = { uid: "single-event", title: "Single Event", calId: "667037022b752d0026472254/cal1", URL: "/calendars/667037022b752d0026472254/cal1/single-event.ics", }; handleDelete( false, // isRecurring undefined, mockOnClose, mockDispatch, basePreloadedState.calendars.list["667037022b752d0026472254/cal1"], nonRecurringEvent, "667037022b752d0026472254/cal1", "single-event" ); expect(mockOnClose).toHaveBeenCalledWith({}, "backdropClick"); expect(mockDispatch).toHaveBeenCalled(); }); it("calls deleteEventInstanceAsync when deleting solo recurring event", () => { const mockDispatch = jest.fn(); const mockOnClose = jest.fn(); const { handleDelete, } = require("../../../src/components/Event/eventHandlers/eventHandlers"); jest .spyOn(eventThunks, "deleteEventInstanceAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); handleDelete( true, // isRecurring "solo", mockOnClose, mockDispatch, basePreloadedState.calendars.list["667037022b752d0026472254/cal1"], basePreloadedState.calendars.list["667037022b752d0026472254/cal1"] .events["recurring-base/20250315T100000"], "667037022b752d0026472254/cal1", "recurring-base/20250315T100000" ); expect(mockOnClose).toHaveBeenCalledWith({}, "backdropClick"); expect(mockDispatch).toHaveBeenCalled(); }); it("calls deleteEventAsync when deleting all recurring events", () => { const mockDispatch = jest.fn(); const mockOnClose = jest.fn(); const { handleDelete, } = require("../../../src/components/Event/eventHandlers/eventHandlers"); jest .spyOn(eventThunks, "deleteEventAsync") .mockImplementation((payload) => { return () => Promise.resolve(payload) as any; }); handleDelete( true, // isRecurring "all", mockOnClose, mockDispatch, basePreloadedState.calendars.list["667037022b752d0026472254/cal1"], basePreloadedState.calendars.list["667037022b752d0026472254/cal1"] .events["recurring-base/20250315T100000"], "667037022b752d0026472254/cal1", "recurring-base/20250315T100000" ); expect(mockOnClose).toHaveBeenCalledWith({}, "backdropClick"); expect(mockDispatch).toHaveBeenCalled(); }); }); describe("Calendar Integration - EditModeDialog Flow", () => { it("passes correct eventId when editing all instances from preview", async () => { const getEventSpy = jest .spyOn(eventThunks, "getEventAsync") .mockImplementation((payload) => { return () => Promise.resolve({ calId: payload.calId, event: basePreloadedState.calendars.list[ "667037022b752d0026472254/cal1" ].events["recurring-base/20250315T100000"], }) as any; }); renderWithProviders( , basePreloadedState ); // Click edit fireEvent.click(screen.getByTestId("EditIcon")); await waitFor(() => { expect( screen.getByText("Update the reccurent event") ).toBeInTheDocument(); }); // Select "All the events" fireEvent.click(screen.getByLabelText("All the events")); fireEvent.click(screen.getByText("Ok")); await waitFor(() => { expect(getEventSpy).toHaveBeenCalled(); // Full display modal should open with the first instance of the series expect(screen.getByText("Edit Event")).toBeInTheDocument(); }); }); }); describe("Event URL handling for recurring events", () => { it("uses base ID for event URL when moving recurring event", async () => { const moveEventSpy = jest .spyOn(eventThunks, "moveEventAsync") .mockImplementation((payload) => { return () => Promise.resolve({ calId: payload.cal.id, events: [] }) as any; }); const twoCalState = { ...basePreloadedState, calendars: { ...basePreloadedState.calendars, list: { ...basePreloadedState.calendars.list, "667037022b752d0026472254/cal2": { id: "667037022b752d0026472254/cal2", name: "Calendar 2", color: "#00FF00", events: {}, }, }, }, }; renderWithProviders( , twoCalState ); // Change calendar fireEvent.mouseDown(screen.getByLabelText("Calendar")); const option = await screen.findByText("Calendar 2"); fireEvent.click(option); fireEvent.click(screen.getByText("Save")); await waitFor(() => { expect(moveEventSpy).toHaveBeenCalled(); }); const movePayload = moveEventSpy.mock.calls[0][0]; // Should use base ID, not full uid with recurrence ID expect(movePayload.newURL).toContain("recurring-base.ics"); expect(movePayload.newURL).not.toContain("/20250315T100000"); }); }); });