summaryrefslogtreecommitdiffstats
path: root/comm/calendar/test/browser/eventDialog/browser_eventDialog.js
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /comm/calendar/test/browser/eventDialog/browser_eventDialog.js
parentInitial commit. (diff)
downloadthunderbird-upstream.tar.xz
thunderbird-upstream.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/calendar/test/browser/eventDialog/browser_eventDialog.js')
-rw-r--r--comm/calendar/test/browser/eventDialog/browser_eventDialog.js399
1 files changed, 399 insertions, 0 deletions
diff --git a/comm/calendar/test/browser/eventDialog/browser_eventDialog.js b/comm/calendar/test/browser/eventDialog/browser_eventDialog.js
new file mode 100644
index 0000000000..44d75d7169
--- /dev/null
+++ b/comm/calendar/test/browser/eventDialog/browser_eventDialog.js
@@ -0,0 +1,399 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+var { TIMEOUT_MODAL_DIALOG, checkMonthAlarmIcon, handleDeleteOccurrencePrompt } =
+ ChromeUtils.import("resource://testing-common/calendar/CalendarUtils.jsm");
+var { cancelItemDialog, formatTime, saveAndCloseItemDialog, setData } = ChromeUtils.import(
+ "resource://testing-common/calendar/ItemEditingHelpers.jsm"
+);
+var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+ CalEvent: "resource:///modules/CalEvent.jsm",
+});
+
+const EVENTTITLE = "Event";
+const EVENTLOCATION = "Location";
+const EVENTDESCRIPTION = "Event Description";
+const EVENTATTENDEE = "foo@example.com";
+const EVENTURL = "https://mozilla.org/";
+const EVENT_ORGANIZER_EMAIL = "pillow@example.com";
+var firstDay;
+
+var { dayView, monthView } = CalendarTestUtils;
+
+let calendar = CalendarTestUtils.createCalendar();
+// This is done so that calItemBase#isInvitation returns true.
+calendar.setProperty("organizerId", `mailto:${EVENT_ORGANIZER_EMAIL}`);
+registerCleanupFunction(() => {
+ CalendarTestUtils.removeCalendar(calendar);
+});
+
+add_task(async function testEventDialog() {
+ let now = new Date();
+
+ // Since from other tests we may be elsewhere, make sure we start today.
+ await CalendarTestUtils.setCalendarView(window, "day");
+ await CalendarTestUtils.goToDate(
+ window,
+ now.getUTCFullYear(),
+ now.getUTCMonth() + 1,
+ now.getUTCDate()
+ );
+ await CalendarTestUtils.calendarViewBackward(window, 1);
+
+ // Open month view.
+ await CalendarTestUtils.setCalendarView(window, "month");
+ firstDay = window.currentView().startDay;
+ dump(`First day in view is: ${firstDay.year}-${firstDay.month + 1}-${firstDay.day}\n`);
+
+ // Setup start- & endTime.
+ // Next full hour except last hour of the day.
+ let hour = now.getUTCHours();
+ let startHour = hour == 23 ? hour : (hour + 1) % 24;
+
+ let nextHour = cal.dtz.now();
+ nextHour.resetTo(firstDay.year, firstDay.month, firstDay.day, startHour, 0, 0, cal.dtz.UTC);
+ let startTime = formatTime(nextHour);
+ nextHour.resetTo(
+ firstDay.year,
+ firstDay.month,
+ firstDay.day,
+ (startHour + 1) % 24,
+ 0,
+ 0,
+ cal.dtz.UTC
+ );
+ let endTime = formatTime(nextHour);
+
+ // Create new event on first day in view.
+ EventUtils.synthesizeMouseAtCenter(monthView.getDayBox(window, 1, 1), {}, window);
+
+ let { dialogWindow, iframeWindow, dialogDocument, iframeDocument } =
+ await CalendarTestUtils.editNewEvent(window);
+
+ // First check all standard-values are set correctly.
+ let startPicker = iframeDocument.getElementById("event-starttime");
+ Assert.equal(startPicker._timepicker._inputField.value, startTime);
+
+ // Check selected calendar.
+ Assert.equal(iframeDocument.getElementById("item-calendar").value, "Test");
+
+ // Check standard title.
+ let defTitle = cal.l10n.getAnyString("calendar", "calendar", "newEvent");
+ Assert.equal(iframeDocument.getElementById("item-title").placeholder, defTitle);
+
+ // Prepare category.
+ let categories = cal.l10n.getAnyString("calendar", "categories", "categories2");
+ // Pick 4th value in a comma-separated list.
+ let category = categories.split(",")[4];
+ // Calculate date to repeat until.
+ let untildate = firstDay.clone();
+ untildate.addDuration(cal.createDuration("P20D"));
+
+ // Fill in the rest of the values.
+ await setData(dialogWindow, iframeWindow, {
+ title: EVENTTITLE,
+ location: EVENTLOCATION,
+ description: EVENTDESCRIPTION,
+ categories: [category],
+ repeat: "daily",
+ repeatuntil: untildate,
+ reminder: "5minutes",
+ privacy: "private",
+ attachment: { add: EVENTURL },
+ attendees: { add: EVENTATTENDEE },
+ });
+
+ // Verify attendee added.
+ EventUtils.synthesizeMouseAtCenter(
+ iframeDocument.getElementById("event-grid-tab-attendees"),
+ {},
+ dialogWindow
+ );
+
+ let attendeesTab = iframeDocument.getElementById("event-grid-tabpanel-attendees");
+ let attendeeNameElements = attendeesTab.querySelectorAll(".attendee-list .attendee-name");
+ Assert.equal(attendeeNameElements.length, 2, "there should be two attendees after save");
+ Assert.equal(attendeeNameElements[0].textContent, EVENT_ORGANIZER_EMAIL);
+ Assert.equal(attendeeNameElements[1].textContent, EVENTATTENDEE);
+ Assert.ok(!iframeDocument.getElementById("notify-attendees-checkbox").checked);
+
+ // Verify private label visible.
+ await TestUtils.waitForCondition(
+ () => !dialogDocument.getElementById("status-privacy-private-box").hasAttribute("collapsed")
+ );
+ dialogDocument.getElementById("event-privacy-menupopup").hidePopup();
+
+ // Add attachment and verify added.
+ EventUtils.synthesizeMouseAtCenter(
+ iframeDocument.getElementById("event-grid-tab-attachments"),
+ {},
+ iframeWindow
+ );
+
+ let attachmentsTab = iframeDocument.getElementById("event-grid-tabpanel-attachments");
+ Assert.equal(attachmentsTab.querySelectorAll("richlistitem").length, 1);
+
+ let alarmPromise = BrowserTestUtils.promiseAlertDialog(
+ undefined,
+ "chrome://calendar/content/calendar-alarm-dialog.xhtml",
+ {
+ callback(alarmWindow) {
+ let dismissAllButton = alarmWindow.document.getElementById("alarm-dismiss-all-button");
+ EventUtils.synthesizeMouseAtCenter(dismissAllButton, {}, alarmWindow);
+ },
+ }
+ );
+
+ // save
+ await saveAndCloseItemDialog(dialogWindow);
+
+ // Catch and dismiss alarm.
+ await alarmPromise;
+
+ // Verify event and alarm icon visible until endDate (3 full rows) and check tooltip.
+ for (let row = 1; row <= 3; row++) {
+ for (let col = 1; col <= 7; col++) {
+ await monthView.waitForItemAt(window, row, col, 1);
+ checkMonthAlarmIcon(window, row, col);
+ checkTooltip(row, col, startTime, endTime);
+ }
+ }
+ Assert.ok(!monthView.getItemAt(window, 4, 1, 1));
+
+ // Delete and verify deleted 6th col in row 1.
+ EventUtils.synthesizeMouseAtCenter(monthView.getItemAt(window, 1, 6, 1), {}, window);
+ let elemToDelete = document.getElementById("month-view");
+ await handleDeleteOccurrencePrompt(window, elemToDelete, false);
+
+ await monthView.waitForNoItemAt(window, 1, 6, 1);
+
+ // Verify all others still exist.
+ for (let col = 1; col <= 5; col++) {
+ Assert.ok(monthView.getItemAt(window, 1, col, 1));
+ }
+ Assert.ok(monthView.getItemAt(window, 1, 7, 1));
+
+ for (let row = 2; row <= 3; row++) {
+ for (let col = 1; col <= 7; col++) {
+ Assert.ok(monthView.getItemAt(window, row, col, 1));
+ }
+ }
+
+ // Delete series by deleting last item in row 1 and confirming to delete all.
+ EventUtils.synthesizeMouseAtCenter(monthView.getItemAt(window, 1, 7, 1), {}, window);
+ elemToDelete = document.getElementById("month-view");
+ await handleDeleteOccurrencePrompt(window, elemToDelete, true);
+
+ // Verify all deleted.
+ await monthView.waitForNoItemAt(window, 1, 5, 1);
+ await monthView.waitForNoItemAt(window, 1, 6, 1);
+ await monthView.waitForNoItemAt(window, 1, 7, 1);
+
+ for (let row = 2; row <= 3; row++) {
+ for (let col = 1; col <= 7; col++) {
+ await monthView.waitForNoItemAt(window, row, col, 1);
+ }
+ }
+});
+
+add_task(async function testOpenExistingEventDialog() {
+ let now = new Date();
+
+ await CalendarTestUtils.setCalendarView(window, "day");
+ await CalendarTestUtils.goToDate(
+ window,
+ now.getUTCFullYear(),
+ now.getUTCMonth() + 1,
+ now.getUTCDate()
+ );
+
+ let createBox = dayView.getHourBoxAt(window, 8);
+
+ // Create a new event.
+ let { dialogWindow, iframeWindow } = await CalendarTestUtils.editNewEvent(window, createBox);
+ await setData(dialogWindow, iframeWindow, {
+ title: EVENTTITLE,
+ location: EVENTLOCATION,
+ description: EVENTDESCRIPTION,
+ });
+ await saveAndCloseItemDialog(dialogWindow);
+
+ let eventBox = await dayView.waitForEventBoxAt(window, 1);
+
+ // Open the event in the summary dialog, it will fail if otherwise.
+ let eventWin = await CalendarTestUtils.viewItem(window, eventBox);
+ Assert.equal(
+ eventWin.document.querySelector("calendar-item-summary .item-title").textContent,
+ EVENTTITLE
+ );
+ Assert.equal(
+ eventWin.document.querySelector("calendar-item-summary .item-location").textContent,
+ EVENTLOCATION
+ );
+ Assert.equal(
+ eventWin.document.querySelector("calendar-item-summary .item-description").contentDocument.body
+ .innerText,
+ EVENTDESCRIPTION
+ );
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, eventWin);
+
+ eventBox.focus();
+ EventUtils.synthesizeKey("VK_DELETE", {}, window);
+ await dayView.waitForNoEventBoxAt(window, 1);
+});
+
+add_task(async function testEventReminderDisplay() {
+ await CalendarTestUtils.setCalendarView(window, "day");
+ await CalendarTestUtils.goToDate(window, 2020, 1, 1);
+
+ let createBox = dayView.getHourBoxAt(window, 8);
+
+ // Create an event without a reminder.
+ let { dialogWindow, iframeWindow } = await CalendarTestUtils.editNewEvent(window, createBox);
+ await setData(dialogWindow, iframeWindow, {
+ title: EVENTTITLE,
+ location: EVENTLOCATION,
+ description: EVENTDESCRIPTION,
+ });
+ await saveAndCloseItemDialog(dialogWindow);
+
+ let eventBox = await dayView.waitForEventBoxAt(window, 1);
+
+ let eventWindow = await CalendarTestUtils.viewItem(window, eventBox);
+ let doc = eventWindow.document;
+ let row = doc.querySelector(".reminder-row");
+ Assert.ok(row.hidden, "reminder dropdown is not displayed");
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, eventWindow);
+
+ await CalendarTestUtils.goToDate(window, 2020, 2, 1);
+ createBox = dayView.getHourBoxAt(window, 8);
+
+ // Create an event with a reminder.
+ ({ dialogWindow, iframeWindow } = await CalendarTestUtils.editNewEvent(window, createBox));
+ await setData(dialogWindow, iframeWindow, {
+ title: EVENTTITLE,
+ location: EVENTLOCATION,
+ description: EVENTDESCRIPTION,
+ reminder: "1week",
+ });
+ await saveAndCloseItemDialog(dialogWindow);
+
+ eventBox = await dayView.waitForEventBoxAt(window, 1);
+ eventWindow = await CalendarTestUtils.viewItem(window, eventBox);
+ doc = eventWindow.document;
+ row = doc.querySelector(".reminder-row");
+
+ Assert.ok(
+ row.textContent.includes("7 days before"),
+ "the details are shown when a reminder is set"
+ );
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, eventWindow);
+
+ // Create an invitation.
+ let icalString =
+ "BEGIN:VCALENDAR\r\n" +
+ "PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN\r\n" +
+ "VERSION:2.0\r\n" +
+ "BEGIN:VEVENT\r\n" +
+ "CREATED:20200301T152601Z\r\n" +
+ "DTSTAMP:20200301T192729Z\r\n" +
+ "UID:x137e\r\n" +
+ "SUMMARY:Nap Time\r\n" +
+ "ORGANIZER;CN=Papa Bois:mailto:papabois@example.com\r\n" +
+ "ATTENDEE;RSVP=TRUE;CN=pillow@example.com;PARTSTAT=NEEDS-ACTION;CUTY\r\n" +
+ " PE=INDIVIDUAL;ROLE=REQ-PARTICIPANT;X-NUM-GUESTS=0:mailto:pillow@example.com\r\n" +
+ "DTSTART:20200301T153000Z\r\n" +
+ "DTEND:20200301T163000Z\r\n" +
+ "DESCRIPTION:Slumber In Lumber\r\n" +
+ "SEQUENCE:0\r\n" +
+ "TRANSP:OPAQUE\r\n" +
+ "BEGIN:VALARM\r\n" +
+ "TRIGGER:-PT30M\r\n" +
+ "REPEAT:2\r\n" +
+ "DURATION:PT15M\r\n" +
+ "ACTION:DISPLAY\r\n" +
+ "END:VALARM\r\n" +
+ "END:VEVENT\r\n" +
+ "END:VCALENDAR\r\n";
+
+ let calendarEvent = await calendar.addItem(new CalEvent(icalString));
+ await CalendarTestUtils.goToDate(window, 2020, 3, 1);
+ eventBox = await dayView.waitForEventBoxAt(window, 1);
+
+ eventWindow = await CalendarTestUtils.viewItem(window, eventBox);
+ doc = eventWindow.document;
+ row = doc.querySelector(".reminder-row");
+
+ Assert.ok(!row.hidden, "reminder row is displayed");
+ Assert.ok(row.querySelector("menulist") != null, "reminder dropdown is available");
+ EventUtils.synthesizeKey("VK_ESCAPE", {}, eventWindow);
+
+ // Delete directly, as using the UI causes a prompt to appear.
+ calendar.deleteItem(calendarEvent);
+ await dayView.waitForNoEventBoxAt(window, 1);
+});
+
+/**
+ * Test that using CTRL+Enter does not result in two events being created.
+ * This only happens in the dialog window. See bug 1668478.
+ */
+add_task(async function testCtrlEnterShortcut() {
+ await CalendarTestUtils.setCalendarView(window, "day");
+ await CalendarTestUtils.goToDate(window, 2020, 9, 1);
+
+ let createBox = dayView.getHourBoxAt(window, 8);
+ let { dialogWindow, iframeWindow } = await CalendarTestUtils.editNewEvent(window, createBox);
+ await setData(dialogWindow, iframeWindow, {
+ title: EVENTTITLE,
+ location: EVENTLOCATION,
+ description: EVENTDESCRIPTION,
+ });
+ EventUtils.synthesizeKey("VK_RETURN", { ctrlKey: true }, dialogWindow);
+
+ await CalendarTestUtils.setCalendarView(window, "month");
+
+ // Give the event boxes enough time to appear before checking for duplicates.
+ // eslint-disable-next-line mozilla/no-arbitrary-setTimeout
+ await new Promise(resolve => setTimeout(resolve, 2000));
+
+ let events = document.querySelectorAll("calendar-month-day-box-item");
+ Assert.equal(events.length, 1, "event was created once");
+
+ if (Services.focus.activeWindow != window) {
+ await BrowserTestUtils.waitForEvent(window, "focus");
+ }
+
+ events[0].focus();
+ EventUtils.synthesizeKey("VK_DELETE", {}, window);
+});
+
+function checkTooltip(row, col, startTime, endTime) {
+ let item = monthView.getItemAt(window, row, col, 1);
+
+ let toolTipNode = document.getElementById("itemTooltip");
+ toolTipNode.ownerGlobal.onMouseOverItem({ currentTarget: item });
+
+ function getDescription(index) {
+ return toolTipNode.querySelector(
+ `.tooltipHeaderTable > tr:nth-of-type(${index}) > .tooltipHeaderDescription`
+ ).textContent;
+ }
+
+ // Check title.
+ Assert.equal(getDescription(1), EVENTTITLE);
+
+ // Check date and time.
+ let dateTime = getDescription(3);
+
+ let currDate = firstDay.clone();
+ currDate.addDuration(cal.createDuration(`P${7 * (row - 1) + (col - 1)}D`));
+ let startDate = cal.dtz.formatter.formatDate(currDate);
+
+ Assert.ok(dateTime.includes(`${startDate} ${startTime} – `));
+
+ // This could be on the next day if it is 00:00.
+ Assert.ok(dateTime.endsWith(endTime));
+}