summaryrefslogtreecommitdiffstats
path: root/comm/calendar/test/browser/browser_eventUndoRedo.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/calendar/test/browser/browser_eventUndoRedo.js')
-rw-r--r--comm/calendar/test/browser/browser_eventUndoRedo.js260
1 files changed, 260 insertions, 0 deletions
diff --git a/comm/calendar/test/browser/browser_eventUndoRedo.js b/comm/calendar/test/browser/browser_eventUndoRedo.js
new file mode 100644
index 0000000000..34ea8d0523
--- /dev/null
+++ b/comm/calendar/test/browser/browser_eventUndoRedo.js
@@ -0,0 +1,260 @@
+/* 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/. */
+
+"use strict";
+
+/**
+ * Tests for ensuring the undo/redo options are enabled properly when
+ * manipulating events.
+ */
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+ CalEvent: "resource:///modules/CalEvent.jsm",
+ CalTransactionManager: "resource:///modules/CalTransactionManager.jsm",
+});
+
+const calendar = CalendarTestUtils.createCalendar("Undo Redo Test");
+const calTransManager = CalTransactionManager.getInstance();
+
+/**
+ * Checks the value of the "disabled" property for items in either the "Edit"
+ * menu bar or the app menu. Display of the relevant menu is triggered first so
+ * the UI code can update the respective items.
+ *
+ * @param {XULElement} element - The menu item we want to check, if its id begins
+ * with "menu" then we assume it is in the menu
+ * bar, if "appmenu" then the app menu.
+ */
+async function isDisabled(element) {
+ let targetMenu = document.getElementById("menu_EditPopup");
+
+ let shownPromise = BrowserTestUtils.waitForEvent(targetMenu, "popupshown");
+ EventUtils.synthesizeMouseAtCenter(document.getElementById("menu_Edit"), {});
+ await shownPromise;
+
+ let hiddenPromise = BrowserTestUtils.waitForEvent(targetMenu, "popuphidden");
+ let status = element.disabled;
+ targetMenu.hidePopup();
+ await hiddenPromise;
+ return status;
+}
+
+async function clickItem(element) {
+ let targetMenu = document.getElementById("menu_EditPopup");
+
+ let shownPromise = BrowserTestUtils.waitForEvent(targetMenu, "popupshown");
+ EventUtils.synthesizeMouseAtCenter(document.getElementById("menu_Edit"), {});
+ await shownPromise;
+
+ targetMenu.activateItem(element);
+}
+
+/**
+ * Removes CalTransaction items from the CalTransactionManager stacks so other
+ * tests are unhindered.
+ */
+function clearTransactions() {
+ calTransManager.undoStack = [];
+ calTransManager.redoStack = [];
+}
+
+/**
+ * Test the undo/redo functionality for event creation.
+ *
+ * @param {string} undoId - The id of the "undo" menu item.
+ * @param {string} redoId - The id of the "redo" menu item.
+ */
+async function testAddUndoRedoEvent(undoId, redoId) {
+ let undo = document.getElementById(undoId);
+ let redo = document.getElementById(redoId);
+ Assert.ok(await isDisabled(undo), `#${undoId} is disabled`);
+ Assert.ok(await isDisabled(redo), `#${redoId} is disabled`);
+
+ let newBtn = document.getElementById("sidePanelNewEvent");
+ let windowOpened = CalendarTestUtils.waitForEventDialog("edit");
+ EventUtils.synthesizeMouseAtCenter(newBtn, {});
+
+ let win = await windowOpened;
+ let iframeWin = win.document.getElementById("calendar-item-panel-iframe").contentWindow;
+ await CalendarTestUtils.items.setData(win, iframeWin, { title: "A New Event" });
+ await CalendarTestUtils.items.saveAndCloseItemDialog(win);
+
+ let eventItem;
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return eventItem;
+ }, "event not created in time");
+
+ Assert.ok(!(await isDisabled(undo)), `#${undoId} is enabled`);
+ Assert.ok(await isDisabled(redo), `#${redoId} is disabled`);
+
+ // Test undo.
+ await clickItem(undo);
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return !eventItem;
+ }, "undo did not remove item in time");
+
+ Assert.ok(!eventItem, `#${undoId} reverses item creation`);
+
+ // Test redo.
+ await clickItem(redo);
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return eventItem;
+ }, `${redoId} did not re-create item in time`);
+ Assert.ok(eventItem, `#${redoId} redos item creation`);
+
+ await calendar.deleteItem(eventItem.item);
+ clearTransactions();
+}
+
+/**
+ * Test the undo/redo functionality for event modification.
+ *
+ * @param {string} undoId - The id of the "undo" menu item.
+ * @param {string} redoId - The id of the "redo" menu item.
+ */
+async function testModifyUndoRedoEvent(undoId, redoId) {
+ let undo = document.getElementById(undoId);
+ let redo = document.getElementById(redoId);
+ Assert.ok(await isDisabled(undo), `#${undoId} is disabled`);
+ Assert.ok(await isDisabled(redo), `#${redoId} is disabled`);
+
+ let event = new CalEvent();
+ event.title = "Modifiable Event";
+ event.startDate = cal.dtz.now();
+ await calendar.addItem(event);
+ window.goToDate(event.startDate);
+
+ let eventItem;
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return eventItem;
+ }, "event not created in time");
+
+ let { dialogWindow, iframeWindow } = await CalendarTestUtils.editItem(window, eventItem);
+ await CalendarTestUtils.items.setData(dialogWindow, iframeWindow, {
+ title: "Modified Event",
+ });
+ await CalendarTestUtils.items.saveAndCloseItemDialog(dialogWindow);
+
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return eventItem && eventItem.item.title == "Modified Event";
+ }, "event not modified in time");
+
+ Assert.ok(!(await isDisabled(undo)), `#${undoId} is enabled`);
+ Assert.ok(await isDisabled(redo), `#${redoId} is disabled`);
+
+ // Test undo.
+ await clickItem(undo);
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return eventItem && eventItem.item.title == "Modifiable Event";
+ }, `#${undoId} did not un-modify event in time`);
+
+ Assert.equal(eventItem.item.title, "Modifiable Event", `#${undoId} reverses item modification`);
+
+ // Test redo.
+ await clickItem(redo);
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return eventItem && eventItem.item.title == "Modified Event";
+ }, `${redoId} did not re-modify item in time`);
+
+ Assert.equal(eventItem.item.title, "Modified Event", `#${redoId} redos item modification`);
+
+ clearTransactions();
+ await calendar.deleteItem(eventItem.item);
+}
+
+/**
+ * Test the undo/redo functionality for event deletion.
+ *
+ * @param {string} undoId - The id of the "undo" menu item.
+ * @param {string} redoId - The id of the "redo" menu item.
+ */
+async function testDeleteUndoRedo(undoId, redoId) {
+ let undo = document.getElementById(undoId);
+ let redo = document.getElementById(redoId);
+ Assert.ok(await isDisabled(undo), `#${undoId} is disabled`);
+ Assert.ok(await isDisabled(redo), `#${redoId} is disabled`);
+
+ let event = new CalEvent();
+ event.title = "Deletable Event";
+ event.startDate = cal.dtz.now();
+ await calendar.addItem(event);
+ window.goToDate(event.startDate);
+
+ let eventItem;
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return eventItem;
+ }, "event not created in time");
+
+ EventUtils.synthesizeMouseAtCenter(eventItem, {});
+ EventUtils.synthesizeKey("VK_DELETE");
+
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return !eventItem;
+ }, "event not deleted in time");
+
+ Assert.ok(!(await isDisabled(undo)), `#${undoId} is enabled`);
+ Assert.ok(await isDisabled(redo), `#${redoId} is disabled`);
+
+ // Test undo.
+ await clickItem(undo);
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return eventItem;
+ }, `#${undoId} did not add event in time`);
+ Assert.ok(eventItem, `#${undoId} reverses item deletion`);
+
+ // Test redo.
+ await clickItem(redo);
+ await TestUtils.waitForCondition(() => {
+ eventItem = document.querySelector("calendar-month-day-box-item");
+ return !eventItem;
+ }, "redo did not delete item in time");
+
+ Assert.ok(!eventItem, `#${redoId} redos item deletion`);
+ clearTransactions();
+}
+
+/**
+ * Ensure the menu bar is visible and navigate the calendar view to today.
+ */
+add_setup(async function () {
+ registerCleanupFunction(() => {
+ CalendarTestUtils.removeCalendar(calendar);
+ });
+
+ clearTransactions();
+ document.getElementById("toolbar-menubar").setAttribute("autohide", null);
+ await CalendarTestUtils.setCalendarView(window, "month");
+ window.goToDate(cal.dtz.now());
+});
+
+/**
+ * Tests the menu bar's undo/redo after adding an event.
+ */
+add_task(async function testMenuBarAddEventUndoRedo() {
+ return testAddUndoRedoEvent("menu_undo", "menu_redo");
+}).__skipMe = AppConstants.platform == "macosx"; // Can't click menu bar on Mac.
+
+/**
+ * Tests the menu bar's undo/redo after modifying an event.
+ */
+add_task(async function testMenuBarModifyEventUndoRedo() {
+ return testModifyUndoRedoEvent("menu_undo", "menu_redo");
+}).__skipMe = AppConstants.platform == "macosx"; // Can't click menu bar on Mac.
+
+/**
+ * Tests the menu bar's undo/redo after deleting an event.
+ */
+add_task(async function testMenuBarDeleteEventUndoRedo() {
+ return testDeleteUndoRedo("menu_undo", "menu_redo");
+}).__skipMe = AppConstants.platform == "macosx"; // Can't click menu bar on Mac.