summaryrefslogtreecommitdiffstats
path: root/comm/calendar/test/browser/browser_dragEventItem.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/calendar/test/browser/browser_dragEventItem.js')
-rw-r--r--comm/calendar/test/browser/browser_dragEventItem.js414
1 files changed, 414 insertions, 0 deletions
diff --git a/comm/calendar/test/browser/browser_dragEventItem.js b/comm/calendar/test/browser/browser_dragEventItem.js
new file mode 100644
index 0000000000..204e429fdd
--- /dev/null
+++ b/comm/calendar/test/browser/browser_dragEventItem.js
@@ -0,0 +1,414 @@
+/* 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/. */
+
+/**
+ * Test dragging of events in the various calendar views.
+ */
+const { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
+
+XPCOMUtils.defineLazyModuleGetters(this, {
+ CalEvent: "resource:///modules/CalEvent.jsm",
+});
+
+const calendar = CalendarTestUtils.createCalendar("Drag Test", "memory");
+// Set a low number of hours to reduce pixel -> minute rounding errors.
+Services.prefs.setIntPref("calendar.view.visiblehours", 3);
+
+registerCleanupFunction(() => {
+ CalendarTestUtils.removeCalendar(calendar);
+ Services.prefs.clearUserPref("calendar.view.visiblehours");
+ // Reset the spaces toolbar to its default visible state.
+ window.gSpacesToolbar.toggleToolbar(false);
+});
+
+/**
+ * Ensures that the window is maximised after switching dates.
+ *
+ * @param {calIDateTime} date - A date to navigate the view to.
+ */
+async function resetView(date, view) {
+ window.goToDate(date);
+
+ if (window.windowState != window.STATE_MAXIMIZED) {
+ // The multi-day views adjust scrolling dynamically when they detect a
+ // resize. Hook into the resize event and scroll after the adjustment.
+ let resizePromise = BrowserTestUtils.waitForEvent(window, "resize");
+ window.maximize();
+ await resizePromise;
+ }
+}
+
+/**
+ * End the dragging of the event at the specified location.
+ *
+ * @param {number} day - The day to drop into.
+ * @param {number} hour - The starting hour to drop to.
+ * @param {number} topOffset - An offset to apply to the mouse position.
+ */
+function endDrag(day, hour, topOffset) {
+ let view = window.currentView();
+ let hourElement;
+ if (view.id == "day-view") {
+ hourElement = CalendarTestUtils.dayView.getHourBoxAt(window, hour);
+ } else {
+ hourElement = CalendarTestUtils.weekView.getHourBoxAt(window, day, hour);
+ }
+ // We scroll to align the *end* of the hour element so we can avoid triggering
+ // the auto-scroll when we synthesize mousemove below.
+ // FIXME: Use and test auto scroll by holding mouseover at the view edges.
+ CalendarTestUtils.scrollViewToTarget(hourElement, false);
+
+ let hourRect = hourElement.getBoundingClientRect();
+
+ // We drop the event with some offset from the starting edge of the desired
+ // hourElement.
+ // NOTE: This may mean that the drop point may not be above the hourElement.
+ // NOTE: We assume that the drop point is however still above the view.
+ // Currently event "move" events get cancelled if the pointer leaves the view.
+ let top = Math.round(hourRect.top + topOffset);
+ let left = Math.round(hourRect.left + hourRect.width / 2);
+
+ EventUtils.synthesizeMouseAtPoint(left, top, { type: "mousemove", shiftKey: true }, window);
+ EventUtils.synthesizeMouseAtPoint(left, top, { type: "mouseup", shiftKey: true }, window);
+}
+
+/**
+ * Simulates the dragging of an event box in a multi-day view to another
+ * column, horizontally.
+ *
+ * @param {MozCalendarEventBox} eventBox - The event to start moving.
+ * @param {number} day - The day to drop into.
+ * @param {number} hour - The starting hour to drop to.
+ */
+function simulateDragToColumn(eventBox, day, hour) {
+ // Scroll to align to the top of the view.
+ CalendarTestUtils.scrollViewToTarget(eventBox, true);
+
+ let sourceRect = eventBox.getBoundingClientRect();
+ // Start dragging from the center of the event box to avoid the gripbars.
+ // NOTE: We assume that the eventBox's center is in view.
+ let leftOffset = sourceRect.width / 2;
+ // We round the mouse position to try and reduce rounding errors when
+ // scrolling the view.
+ let sourceTop = Math.round(sourceRect.top + sourceRect.height / 2);
+ let sourceLeft = sourceRect.left + leftOffset;
+ // Keep track of the exact offset.
+ let topOffset = sourceTop - sourceRect.top;
+
+ EventUtils.synthesizeMouseAtPoint(
+ sourceLeft,
+ sourceTop,
+ // Hold shift to avoid snapping.
+ { type: "mousedown", shiftKey: true },
+ window
+ );
+ EventUtils.synthesizeMouseAtPoint(
+ // We assume the location of the mouseout event does not matter, just as
+ // long as the event box receives it.
+ sourceLeft,
+ sourceTop,
+ { type: "mouseout", shiftKey: true },
+ window
+ );
+
+ // End drag with the same offset from the starting edge.
+ endDrag(day, hour, topOffset);
+}
+
+/**
+ * Simulates the dragging of an event box via one of the gripbars.
+ *
+ * @param {MozCalendarEventBox} eventBox - The event to resize.
+ * @param {"start"|"end"} - The side to grab.
+ * @param {number} day - The day to move into.
+ * @param {number} hour - The hour to move to.
+ */
+function simulateGripbarDrag(eventBox, side, day, hour) {
+ // Scroll the edge of the box into view.
+ CalendarTestUtils.scrollViewToTarget(eventBox, side == "start");
+
+ let gripbar = side == "start" ? eventBox.startGripbar : eventBox.endGripbar;
+
+ let sourceRect = gripbar.getBoundingClientRect();
+ let sourceTop = sourceRect.top + sourceRect.height / 2;
+ let sourceLeft = sourceRect.left + sourceRect.width / 2;
+
+ // Hover to make the gripbar visible.
+ EventUtils.synthesizeMouseAtPoint(sourceLeft, sourceTop, { type: "mouseover" }, window);
+ EventUtils.synthesizeMouseAtPoint(
+ sourceLeft,
+ sourceTop,
+ // Hold shift to avoid snapping.
+ { type: "mousedown", shiftKey: true },
+ window
+ );
+
+ // End the drag at the start of the hour.
+ endDrag(day, hour, 0);
+}
+
+/**
+ * Tests dragging an event item updates the event in the month view.
+ */
+add_task(async function testMonthViewDragEventItem() {
+ let event = new CalEvent();
+ event.id = "1";
+ event.title = "Month View Event";
+ event.startDate = cal.createDateTime("20210316T000000Z");
+ event.endDate = cal.createDateTime("20210316T110000Z");
+
+ await CalendarTestUtils.setCalendarView(window, "month");
+ await calendar.addItem(event);
+ await resetView(event.startDate);
+
+ // Hide the spaces toolbar since it interferes with the calendar
+ window.gSpacesToolbar.toggleToolbar(true);
+
+ let eventItem = await CalendarTestUtils.monthView.waitForItemAt(window, 3, 3, 1);
+ let dayBox = await CalendarTestUtils.monthView.getDayBox(window, 3, 2);
+ let dragSession = Cc["@mozilla.org/widget/dragservice;1"].getService(Ci.nsIDragService);
+ dragSession.startDragSessionForTests(Ci.nsIDragService.DRAGDROP_ACTION_MOVE);
+
+ let [result, dataTransfer] = EventUtils.synthesizeDragOver(
+ eventItem,
+ dayBox,
+ undefined,
+ undefined,
+ eventItem.ownerGlobal,
+ dayBox.ownerGlobal
+ );
+ EventUtils.synthesizeDropAfterDragOver(result, dataTransfer, dayBox);
+ dragSession.endDragSession(true);
+
+ Assert.ok(
+ !CalendarTestUtils.monthView.getItemAt(window, 3, 3, 1),
+ "item removed from initial date"
+ );
+
+ eventItem = await CalendarTestUtils.monthView.waitForItemAt(window, 3, 2, 1);
+ Assert.ok(eventItem, "item moved to new date");
+
+ let { id, title, startDate, endDate } = eventItem.occurrence;
+ Assert.equal(id, event.id, "id is correct");
+ Assert.equal(title, event.title, "title is correct");
+ Assert.equal(startDate.icalString, "20210315T000000Z", "startDate is correct");
+ Assert.equal(endDate.icalString, "20210315T110000Z", "endDate is correct");
+ await calendar.deleteItem(eventItem.occurrence);
+});
+
+/**
+ * Tests dragging an event item updates the event in the multiweek view.
+ */
+add_task(async function testMultiWeekViewDragEventItem() {
+ let event = new CalEvent();
+ event.id = "2";
+ event.title = "Multiweek View Event";
+ event.startDate = cal.createDateTime("20210316T000000Z");
+ event.endDate = cal.createDateTime("20210316T110000Z");
+
+ await CalendarTestUtils.setCalendarView(window, "multiweek");
+ await calendar.addItem(event);
+ await resetView(event.startDate);
+
+ let eventItem = await CalendarTestUtils.multiweekView.waitForItemAt(window, 1, 3, 1);
+ let dayBox = await CalendarTestUtils.multiweekView.getDayBox(window, 1, 2);
+ let dragSession = Cc["@mozilla.org/widget/dragservice;1"].getService(Ci.nsIDragService);
+ dragSession.startDragSessionForTests(Ci.nsIDragService.DRAGDROP_ACTION_MOVE);
+
+ let [result, dataTransfer] = EventUtils.synthesizeDragOver(
+ eventItem,
+ dayBox,
+ undefined,
+ undefined,
+ eventItem.ownerGlobal,
+ dayBox.ownerGlobal
+ );
+ EventUtils.synthesizeDropAfterDragOver(result, dataTransfer, dayBox);
+ dragSession.endDragSession(true);
+
+ Assert.ok(
+ !CalendarTestUtils.multiweekView.getItemAt(window, 1, 3, 1),
+ "item removed from initial date"
+ );
+
+ eventItem = await CalendarTestUtils.multiweekView.waitForItemAt(window, 1, 2, 1);
+ Assert.ok(eventItem, "item moved to new date");
+
+ let { id, title, startDate, endDate } = eventItem.occurrence;
+ Assert.equal(id, event.id, "id is correct");
+ Assert.equal(title, event.title, "title is correct");
+ Assert.equal(startDate.icalString, "20210315T000000Z", "startDate is correct");
+ Assert.equal(endDate.icalString, "20210315T110000Z", "endDate is correct");
+ await calendar.deleteItem(eventItem.occurrence);
+});
+
+/**
+ * Tests dragging an event box to the previous day updates the event in the
+ * week view.
+ */
+add_task(async function testWeekViewDragEventBoxToPreviousDay() {
+ let event = new CalEvent();
+ event.id = "3";
+ event.title = "Week View Previous Day";
+ event.startDate = cal.createDateTime("20210316T020000Z");
+ event.endDate = cal.createDateTime("20210316T030000Z");
+
+ await CalendarTestUtils.setCalendarView(window, "week");
+ await calendar.addItem(event);
+ await resetView(event.startDate);
+
+ let eventBox = await CalendarTestUtils.weekView.waitForEventBoxAt(window, 3, 1);
+ simulateDragToColumn(eventBox, 2, 2);
+
+ eventBox = await CalendarTestUtils.weekView.waitForEventBoxAt(window, 2, 1);
+ await TestUtils.waitForCondition(
+ () => !CalendarTestUtils.weekView.getEventBoxAt(window, 3, 1),
+ "Old position is empty"
+ );
+
+ let { id, title, startDate, endDate } = eventBox.occurrence;
+ Assert.equal(id, event.id, "id is correct");
+ Assert.equal(title, event.title, "title is correct");
+ Assert.equal(startDate.icalString, "20210315T020000Z", "startDate is correct");
+ Assert.equal(endDate.icalString, "20210315T030000Z", "endDate is correct");
+ await calendar.deleteItem(eventBox.occurrence);
+});
+
+/**
+ * Tests dragging an event box to the following day updates the event in the
+ * week view.
+ */
+add_task(async function testWeekViewDragEventBoxToFollowingDay() {
+ let event = new CalEvent();
+ event.id = "4";
+ event.title = "Week View Following Day";
+ event.startDate = cal.createDateTime("20210316T020000Z");
+ event.endDate = cal.createDateTime("20210316T030000Z");
+
+ await CalendarTestUtils.setCalendarView(window, "week");
+ await calendar.addItem(event);
+ await resetView(event.startDate);
+
+ let eventBox = await CalendarTestUtils.weekView.waitForEventBoxAt(window, 3, 1);
+ simulateDragToColumn(eventBox, 4, 2);
+
+ eventBox = await CalendarTestUtils.weekView.waitForEventBoxAt(window, 4, 1);
+ await TestUtils.waitForCondition(
+ () => !CalendarTestUtils.weekView.getEventBoxAt(window, 3, 1),
+ "Old position is empty"
+ );
+
+ let { id, title, startDate, endDate } = eventBox.occurrence;
+ Assert.equal(id, event.id, "id is correct");
+ Assert.equal(title, event.title, "title is correct");
+ Assert.equal(startDate.icalString, "20210317T020000Z", "startDate is correct");
+ Assert.equal(endDate.icalString, "20210317T030000Z", "endDate is correct");
+ await calendar.deleteItem(eventBox.occurrence);
+});
+
+/**
+ * Tests dragging the top of an event box updates the start time in the week
+ * view.
+ */
+add_task(async function testWeekViewDragEventBoxStartTime() {
+ let event = new CalEvent();
+ event.id = "5";
+ event.title = "Week View Start";
+ event.startDate = cal.createDateTime("20210316T020000Z");
+ event.endDate = cal.createDateTime("20210316T030000Z");
+
+ await CalendarTestUtils.setCalendarView(window, "week");
+ await calendar.addItem(event);
+ await resetView(event.startDate);
+
+ let eventBox = await CalendarTestUtils.weekView.waitForEventBoxAt(window, 3, 1);
+ simulateGripbarDrag(eventBox, "start", 3, 1);
+ eventBox = await CalendarTestUtils.weekView.waitForEventBoxAt(window, 3, 1);
+
+ let { id, title, startDate, endDate } = eventBox.occurrence;
+ Assert.equal(id, event.id, "id is correct");
+ Assert.equal(title, event.title, "title is correct");
+ Assert.equal(startDate.icalString, "20210316T010000Z", "startDate was changed");
+ Assert.equal(endDate.icalString, "20210316T030000Z", "endDate did not change");
+ await calendar.deleteItem(eventBox.occurrence);
+});
+
+/**
+ * Tests dragging the end of an event box changes the time in the week view.
+ */
+add_task(async function testWeekViewDragEventBoxEndTime() {
+ let event = new CalEvent();
+ event.id = "6";
+ event.title = "Week View End";
+ event.startDate = cal.createDateTime("20210316T020000Z");
+ event.endDate = cal.createDateTime("20210316T030000Z");
+
+ await CalendarTestUtils.setCalendarView(window, "week");
+ await calendar.addItem(event);
+ await resetView(event.startDate);
+
+ let eventBox = await CalendarTestUtils.weekView.waitForEventBoxAt(window, 3, 1);
+ simulateGripbarDrag(eventBox, "end", 3, 6);
+ eventBox = await CalendarTestUtils.weekView.waitForEventBoxAt(window, 3, 1);
+
+ let { id, title, startDate, endDate } = eventBox.occurrence;
+ Assert.equal(id, event.id, "id is correct");
+ Assert.equal(title, event.title, "title is correct");
+ Assert.equal(startDate.icalString, "20210316T020000Z", "startDate did not change");
+ Assert.equal(endDate.icalString, "20210316T060000Z", "endDate was changed");
+ await calendar.deleteItem(eventBox.occurrence);
+});
+
+/**
+ * Tests dragging the top of an event box changes the start time in the day view.
+ */
+add_task(async function testDayViewDragEventBoxStartTime() {
+ let event = new CalEvent();
+ event.id = "7";
+ event.title = "Day View Start";
+ event.startDate = cal.createDateTime("20210316T020000Z");
+ event.endDate = cal.createDateTime("20210316T030000Z");
+
+ await CalendarTestUtils.setCalendarView(window, "day");
+ await calendar.addItem(event);
+ await resetView(event.startDate);
+
+ let eventBox = await CalendarTestUtils.dayView.waitForEventBoxAt(window, 1);
+ simulateGripbarDrag(eventBox, "start", 1, 1);
+ eventBox = await CalendarTestUtils.dayView.waitForEventBoxAt(window, 1);
+
+ let { id, title, startDate, endDate } = eventBox.occurrence;
+ Assert.equal(id, event.id, "id is correct");
+ Assert.equal(title, event.title, "title is correct");
+ Assert.equal(startDate.icalString, "20210316T010000Z", "startDate was changed");
+ Assert.equal(endDate.icalString, "20210316T030000Z", "endDate did not change");
+ await calendar.deleteItem(eventBox.occurrence);
+});
+
+/**
+ * Tests dragging the bottom of an event box changes the end time in the day
+ * view.
+ */
+add_task(async function testDayViewDragEventBoxEndTime() {
+ let event = new CalEvent();
+ event.id = "8";
+ event.title = "Day View End";
+ event.startDate = cal.createDateTime("20210316T020000Z");
+ event.endDate = cal.createDateTime("20210316T030000Z");
+
+ await CalendarTestUtils.setCalendarView(window, "day");
+ await calendar.addItem(event);
+ await resetView(event.startDate);
+
+ let eventBox = await CalendarTestUtils.dayView.waitForEventBoxAt(window, 1);
+ simulateGripbarDrag(eventBox, "end", 1, 4);
+ eventBox = await CalendarTestUtils.dayView.waitForEventBoxAt(window, 1);
+
+ let { id, title, startDate, endDate } = eventBox.occurrence;
+ Assert.equal(id, event.id, "id is correct");
+ Assert.equal(title, event.title, "title is correct");
+ Assert.equal(startDate.icalString, "20210316T020000Z", "startDate did not change");
+ Assert.equal(endDate.icalString, "20210316T040000Z", "endDate was changed");
+ await calendar.deleteItem(eventBox.occurrence);
+});