fix url endcoding

This commit is contained in:
lenhanphung
2026-01-07 15:43:49 +07:00
parent ecc844de0a
commit 994ea1c45e
8 changed files with 84 additions and 17 deletions
+72 -1
View File
@@ -662,7 +662,78 @@ describe("Event Preview Display", () => {
preloadedState.calendars.list["667037022b752d0026472254/cal1"].events[
"event1"
];
const expectedUrl = `test/mailto/?uri=mailto:john@test.com?subject=Test Event`;
const expectedUrl = `test/mailto/?uri=mailto:john@test.com?subject=Test%20Event`;
expect(mockOpen).toHaveBeenCalledWith(expectedUrl);
});
it("message button encodes special characters in event title correctly", () => {
(window as any).MAIL_SPA_URL = "test";
const mockOpen = jest.fn();
window.open = mockOpen;
const specialCharState = {
...preloadedState,
calendars: {
...preloadedState.calendars,
list: {
...preloadedState.calendars.list,
"667037022b752d0026472254/cal1": {
...preloadedState.calendars.list["667037022b752d0026472254/cal1"],
events: {
...preloadedState.calendars.list["667037022b752d0026472254/cal1"]
.events,
eventWithSpecialChars: {
uid: "eventWithSpecialChars",
title: "Meeting & Discussion? #Important",
calId: "667037022b752d0026472254/cal1",
start: day.toISOString(),
end: day.toISOString(),
organizer: { cn: "test", cal_address: "test@test.com" },
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",
},
],
},
},
},
},
},
};
renderWithProviders(
<EventPreviewModal
open={true}
onClose={mockOnClose}
calId={"667037022b752d0026472254/cal1"}
eventId={"eventWithSpecialChars"}
/>,
specialCharState
);
fireEvent.click(screen.getByTestId("MoreVertIcon"));
const emailButton = screen.getByRole("menuitem", {
name: "eventPreview.emailAttendees",
});
expect(emailButton).toBeInTheDocument();
fireEvent.click(emailButton);
const expectedUrl = `test/mailto/?uri=mailto:john@test.com?subject=Meeting%20%26%20Discussion%3F%20%23Important`;
expect(mockOpen).toHaveBeenCalledWith(expectedUrl);
});
-5
View File
@@ -29,9 +29,4 @@ export default defineConfig({
"react-dom": require.resolve("react-dom"),
},
},
performance: {
chunkOverflow: {
maxAssetSize: 2000000,
},
},
});
+2 -2
View File
@@ -1,10 +1,10 @@
import React from "react";
import { MenuItem } from "@linagora/twake-mui";
import { Calendars } from "../../features/Calendars/CalendarTypes";
import { Calendar } from "../../features/Calendars/CalendarTypes";
import { CalendarName } from "./CalendarName";
export function CalendarItemList(
userPersonalCalendars: Calendars[]
userPersonalCalendars: Calendar[]
): React.ReactNode {
return Object.values(userPersonalCalendars).map((calendar) => (
<MenuItem key={calendar.id} value={calendar.id}>
+2 -2
View File
@@ -1,7 +1,7 @@
import { Box, Typography } from "@linagora/twake-mui";
import { Calendars } from "../../features/Calendars/CalendarTypes";
import { Calendar } from "../../features/Calendars/CalendarTypes";
import SquareRoundedIcon from "@mui/icons-material/SquareRounded";
export function CalendarName({ calendar }: { calendar: Calendars }) {
export function CalendarName({ calendar }: { calendar: Calendar }) {
return (
<Box style={{ display: "flex", flexDirection: "row", gap: 8 }}>
<SquareRoundedIcon
+2 -2
View File
@@ -13,7 +13,7 @@ import { useState } from "react";
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { getCalendars } from "../../features/Calendars/CalendarApi";
import { addSharedCalendarAsync } from "../../features/Calendars/CalendarSlice";
import { Calendars } from "../../features/Calendars/CalendarTypes";
import { Calendar } from "../../features/Calendars/CalendarTypes";
import { PeopleSearch, User } from "../Attendees/PeopleSearch";
import { ResponsiveDialog } from "../Dialog";
import { ColorPicker } from "./CalendarColorPicker";
@@ -95,7 +95,7 @@ function SelectedCalendarsList({
onRemove,
onColorChange,
}: {
calendars: Record<string, Calendars>;
calendars: Record<string, Calendar>;
selectedCal: CalendarWithOwner[];
onRemove: (cal: CalendarWithOwner) => void;
onColorChange: (
@@ -6,7 +6,7 @@ import {
DialogActions,
Button,
} from "@linagora/twake-mui";
import { Calendars } from "../../features/Calendars/CalendarTypes";
import { Calendar } from "../../features/Calendars/CalendarTypes";
import { useI18n } from "twake-i18n";
export function DeleteCalendarDialog({
@@ -19,7 +19,7 @@ export function DeleteCalendarDialog({
}: {
deletePopupOpen: boolean;
setDeletePopupOpen: (e: boolean) => void;
calendars: Record<string, Calendars>;
calendars: Record<string, Calendar>;
id: string;
isPersonal: boolean;
handleDeleteConfirm: () => void;
-1
View File
@@ -8,7 +8,6 @@ import SettingsIcon from "@mui/icons-material/Settings";
import LogoutIcon from "@mui/icons-material/Logout";
import "./Menubar.styl";
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { stringToColor } from "../Event/utils/eventUtils";
import { stringToGradient } from "../../utils/avatarUtils";
import {
Avatar,
+4 -2
View File
@@ -99,7 +99,7 @@ export default function EventPreviewModal({
const attendeePreview = makeAttendeePreview(event.attendee, t);
const hasCheckedSessionStorageRef = useRef(false);
const [toggleActionMenu, setToggleActionMenu] = useState<HTMLElement | null>(
const [toggleActionMenu, setToggleActionMenu] = useState<Element | null>(
null
);
const mailSpaUrl = (window as any).MAIL_SPA_URL ?? null;
@@ -368,7 +368,9 @@ export default function EventPreviewModal({
`${mailSpaUrl}/mailto/?uri=mailto:${event.attendee
.map((a) => a.cal_address)
.filter((mail) => mail !== user.email)
.join(",")}?subject=${encodeURIComponent(event.title ?? "")}`
.join(
","
)}?subject=${encodeURIComponent(event.title ?? "")}`
)
}
>