Delete Calendars (#148)

* [#66] added delete popup and logic

* [#66] Homogenize Dialogs components between modify and delete to keep them coherent+ fixed tests

* [#66] added tests

* [#66] text adjusment

* fixup! [#66] added delete popup and logic

---------

Co-authored-by: Camille Moussu <cmoussu@linagora.com>
This commit is contained in:
Camille Moussu
2025-09-30 10:27:47 +02:00
committed by GitHub
parent b46be3af29
commit 475ab79731
10 changed files with 324 additions and 111 deletions
+73 -6
View File
@@ -1,7 +1,9 @@
import { screen, fireEvent, waitFor } from "@testing-library/react";
import { screen, fireEvent, waitFor, cleanup } from "@testing-library/react";
import "@testing-library/jest-dom";
import CalendarSelection from "../../src/components/Calendar/CalendarSelection";
import { renderWithProviders } from "../utils/Renderwithproviders";
import * as calendarThunks from "../../src/features/Calendars/CalendarSlice";
import userEvent from "@testing-library/user-event";
describe("CalendarSelection", () => {
const baseUser = {
@@ -35,7 +37,10 @@ describe("CalendarSelection", () => {
ownerEmails: ["charlie@example.com"],
},
};
beforeAll(() => {
jest.clearAllMocks();
cleanup();
});
it("renders personal, delegated and other calendars", () => {
renderWithProviders(
<CalendarSelection
@@ -101,7 +106,7 @@ describe("CalendarSelection", () => {
expect(updater(["user1/cal1"])).toEqual([]);
});
it("opens CalendarPopover modal when personal Add button is clicked", () => {
it("opens CalendarPopover modal when personal Add button is clicked", async () => {
renderWithProviders(
<CalendarSelection
selectedCalendars={[]}
@@ -114,9 +119,71 @@ describe("CalendarSelection", () => {
);
const addButtons = screen.getAllByRole("button");
fireEvent.click(addButtons[1]);
await waitFor(() =>
expect(screen.getByText("Calendar configuration")).toBeInTheDocument()
);
});
it("Navigates to deletion dialog and deletes personnal cal", async () => {
const spy = jest
.spyOn(calendarThunks, "removeCalendarAsync")
.mockImplementation((payload) => {
return () => Promise.resolve(payload) as any;
});
renderWithProviders(
<CalendarSelection
selectedCalendars={[]}
setSelectedCalendars={jest.fn()}
/>,
{
user: baseUser,
calendars: { list: calendarsMock, pending: false },
}
);
const addButtons = screen.getAllByTestId("MoreVertIcon");
fireEvent.click(addButtons[0]);
waitFor(() => expect(screen.getByRole("presentation")).toBeInTheDocument());
userEvent.click(screen.getByText(/delete/i));
await waitFor(() =>
expect(screen.getByText("Remove 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(
<CalendarSelection
selectedCalendars={[]}
setSelectedCalendars={jest.fn()}
/>,
{
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("Remove 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", () => {
@@ -131,10 +198,10 @@ describe("CalendarSelection", () => {
}
);
const addButtons = screen.getAllByRole("button");
const addButtons = screen.getAllByTestId("AddIcon");
fireEvent.click(addButtons[1]); // seccond Add button (other)
expect(screen.getByRole("presentation")).toBeInTheDocument();
expect(screen.getByText("Browse other calendars")).toBeInTheDocument();
});
it("renders only personal calendars if no delegated/other exist", () => {
@@ -5,6 +5,7 @@ import {
getCalendars,
postCalendar,
proppatchCalendar,
removeCalendar,
} from "../../../src/features/Calendars/CalendarApi";
import { clientConfig } from "../../../src/features/User/oidcAuth";
import { api } from "../../../src/utils/apiUtils";
@@ -99,4 +100,16 @@ describe("Calendar API", () => {
}),
});
});
it("remove Calendar", async () => {
const calLink = "/calendars/calId.json";
const result = await removeCalendar(calLink);
expect(api).toHaveBeenCalledWith(`dav${calLink}`, {
method: "DELETE",
headers: {
Accept: "application/json, text/plain, */*",
},
});
});
});
@@ -1,5 +1,5 @@
import { screen, fireEvent, waitFor } from "@testing-library/react";
import CalendarPopover from "../../../src/features/Calendars/CalendarModal";
import CalendarPopover from "../../../src/components/Calendar/CalendarModal";
import { renderWithProviders } from "../../utils/Renderwithproviders";
import * as eventThunks from "../../../src/features/Calendars/CalendarSlice";
@@ -23,11 +23,7 @@ describe("CalendarPopover", () => {
calendars: { list: {}, pending: true },
};
renderWithProviders(
<CalendarPopover
anchorEl={document.body}
open={open}
onClose={mockOnClose}
/>,
<CalendarPopover open={open} onClose={mockOnClose} />,
preloadedState
);
};
@@ -133,7 +129,6 @@ describe("CalendarPopover (editing mode)", () => {
it("prefills fields when calendar prop is given", () => {
renderWithProviders(
<CalendarPopover
anchorEl={document.body}
open={true}
onClose={mockOnClose}
calendar={existingCalendar}
@@ -149,14 +144,9 @@ describe("CalendarPopover (editing mode)", () => {
});
test("Save button is disabled when name is empty or whitespace only", () => {
renderWithProviders(
<CalendarPopover
anchorEl={document.createElement("div")}
open={true}
onClose={jest.fn()}
/>,
{ user: baseUser }
);
renderWithProviders(<CalendarPopover open={true} onClose={jest.fn()} />, {
user: baseUser,
});
const saveButton = screen.getByRole("button", { name: /save/i });
expect(saveButton).toBeDisabled();
@@ -180,7 +170,6 @@ describe("CalendarPopover (editing mode)", () => {
renderWithProviders(
<CalendarPopover
anchorEl={document.body}
open={true}
onClose={mockOnClose}
calendar={existingCalendar}