summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/folder-display/browser_messageCommands.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/folder-display/browser_messageCommands.js')
-rw-r--r--comm/mail/test/browser/folder-display/browser_messageCommands.js802
1 files changed, 802 insertions, 0 deletions
diff --git a/comm/mail/test/browser/folder-display/browser_messageCommands.js b/comm/mail/test/browser/folder-display/browser_messageCommands.js
new file mode 100644
index 0000000000..ab49d07df3
--- /dev/null
+++ b/comm/mail/test/browser/folder-display/browser_messageCommands.js
@@ -0,0 +1,802 @@
+/* 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/. */
+
+/**
+ * This tests various commands on messages. This is primarily for commands
+ * that can't be tested with xpcshell tests because they're handling in the
+ * front end - which is why Archive is the only command currently tested.
+ */
+
+"use strict";
+
+var { wait_for_content_tab_load } = ChromeUtils.import(
+ "resource://testing-common/mozmill/ContentTabHelpers.jsm"
+);
+var {
+ add_message_sets_to_folders,
+ archive_selected_messages,
+ assert_selected_and_displayed,
+ be_in_folder,
+ close_popup,
+ collapse_all_threads,
+ create_folder,
+ create_thread,
+ get_about_3pane,
+ get_about_message,
+ make_display_threaded,
+ make_display_unthreaded,
+ make_message_sets_in_folders,
+ mc,
+ press_delete,
+ right_click_on_row,
+ select_click_row,
+ select_control_click_row,
+ select_shift_click_row,
+ wait_for_popup_to_open,
+} = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+var { click_menus_in_sequence } = ChromeUtils.import(
+ "resource://testing-common/mozmill/WindowHelpers.jsm"
+);
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+var { MailUtils } = ChromeUtils.import("resource:///modules/MailUtils.jsm");
+
+var unreadFolder, shiftDeleteFolder, threadDeleteFolder;
+var archiveSrcFolder = null;
+
+var tagArray;
+var gAutoRead;
+
+// Adjust timeout to take care of code coverage runs needing twice as long.
+requestLongerTimeout(AppConstants.MOZ_CODE_COVERAGE ? 2 : 1);
+
+add_setup(async function () {
+ gAutoRead = Services.prefs.getBoolPref("mailnews.mark_message_read.auto");
+ Services.prefs.setBoolPref("mailnews.mark_message_read.auto", false);
+
+ unreadFolder = await create_folder("UnreadFolder");
+ shiftDeleteFolder = await create_folder("ShiftDeleteFolder");
+ threadDeleteFolder = await create_folder("ThreadDeleteFolder");
+ archiveSrcFolder = await create_folder("ArchiveSrc");
+
+ await make_message_sets_in_folders([unreadFolder], [{ count: 2 }]);
+ await make_message_sets_in_folders([shiftDeleteFolder], [{ count: 3 }]);
+ await add_message_sets_to_folders(
+ [threadDeleteFolder],
+ [create_thread(3), create_thread(3), create_thread(3)]
+ );
+
+ // Create messages from 20 different months, which will mean 2 different
+ // years as well.
+ await make_message_sets_in_folders(
+ [archiveSrcFolder],
+ [{ count: 20, age_incr: { weeks: 5 } }]
+ );
+
+ tagArray = MailServices.tags.getAllTags();
+});
+
+/**
+ * Ensures that all messages have a particular read status
+ *
+ * @param messages an array of nsIMsgDBHdrs to check
+ * @param read true if the messages should be marked read, false otherwise
+ */
+function check_read_status(messages, read) {
+ function read_str(read) {
+ return read ? "read" : "unread";
+ }
+
+ for (let i = 0; i < messages.length; i++) {
+ Assert.ok(
+ messages[i].isRead == read,
+ "Message marked as " +
+ read_str(messages[i].isRead) +
+ ", expected " +
+ read_str(read)
+ );
+ }
+}
+
+/**
+ * Ensures that the mark read/unread menu items are enabled/disabled properly
+ *
+ * @param index the row in the thread pane of the message to query
+ * @param canMarkRead true if the mark read item should be enabled
+ * @param canMarkUnread true if the mark unread item should be enabled
+ */
+async function check_read_menuitems(index, canMarkRead, canMarkUnread) {
+ await right_click_on_row(index);
+ let hiddenPromise = BrowserTestUtils.waitForEvent(
+ getMailContext(),
+ "popuphidden"
+ );
+ await click_menus_in_sequence(getMailContext(), [{ id: "mailContext-mark" }]);
+
+ let readEnabled = !getMailContext().querySelector("#mailContext-markRead")
+ .disabled;
+ let unreadEnabled = !getMailContext().querySelector("#mailContext-markUnread")
+ .disabled;
+
+ Assert.ok(
+ readEnabled == canMarkRead,
+ "Mark read menu item " +
+ (canMarkRead ? "dis" : "en") +
+ "abled when it shouldn't be!"
+ );
+
+ Assert.ok(
+ unreadEnabled == canMarkUnread,
+ "Mark unread menu item " +
+ (canMarkUnread ? "dis" : "en") +
+ "abled when it shouldn't be!"
+ );
+
+ await hiddenPromise;
+ await new Promise(resolve => requestAnimationFrame(resolve));
+}
+
+function enable_archiving(enabled) {
+ Services.prefs.setBoolPref("mail.identity.default.archive_enabled", enabled);
+}
+
+/**
+ * Mark a message read or unread via the context menu
+ *
+ * @param index the row in the thread pane of the message to mark read/unread
+ * @param read true the message should be marked read, false otherwise
+ */
+async function mark_read_via_menu(index, read) {
+ let menuItem = read ? "mailContext-markRead" : "mailContext-markUnread";
+ await right_click_on_row(index);
+ await wait_for_popup_to_open(getMailContext());
+ await click_menus_in_sequence(getMailContext(), [
+ { id: "mailContext-mark" },
+ { id: menuItem },
+ ]);
+ await close_popup(mc, getMailContext());
+}
+
+add_task(async function test_mark_one_read() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+
+ curMessage.markRead(false);
+ await mark_read_via_menu(0, true);
+ check_read_status([curMessage], true);
+});
+
+add_task(async function test_mark_one_unread() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+
+ curMessage.markRead(true);
+ await mark_read_via_menu(0, false);
+ check_read_status([curMessage], false);
+});
+
+add_task(async function test_mark_n_read() {
+ await be_in_folder(unreadFolder);
+ select_click_row(0);
+ let curMessages = select_shift_click_row(1);
+
+ for (let i = 0; i < curMessages.length; i++) {
+ curMessages[i].markRead(false);
+ }
+ await mark_read_via_menu(0, true);
+ check_read_status(curMessages, true);
+});
+
+add_task(async function test_mark_n_unread() {
+ await be_in_folder(unreadFolder);
+ select_click_row(0);
+ let curMessages = select_shift_click_row(1);
+
+ for (let i = 0; i < curMessages.length; i++) {
+ curMessages[i].markRead(true);
+ }
+ await mark_read_via_menu(0, false);
+ check_read_status(curMessages, false);
+});
+
+add_task(async function test_mark_n_read_mixed() {
+ await be_in_folder(unreadFolder);
+ select_click_row(0);
+ let curMessages = select_shift_click_row(1);
+
+ curMessages[0].markRead(true);
+ curMessages[1].markRead(false);
+ await mark_read_via_menu(0, true);
+ check_read_status(curMessages, true);
+
+ curMessages[0].markRead(false);
+ curMessages[1].markRead(true);
+ await mark_read_via_menu(0, true);
+ check_read_status(curMessages, true);
+});
+
+add_task(async function test_mark_n_unread_mixed() {
+ await be_in_folder(unreadFolder);
+ select_click_row(0);
+ let curMessages = select_shift_click_row(1);
+
+ curMessages[0].markRead(false);
+ curMessages[1].markRead(true);
+ await mark_read_via_menu(0, false);
+ check_read_status(curMessages, false);
+
+ curMessages[0].markRead(true);
+ curMessages[1].markRead(false);
+ await mark_read_via_menu(0, false);
+ check_read_status(curMessages, false);
+});
+
+add_task(async function test_toggle_read() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+
+ curMessage.markRead(false);
+ EventUtils.synthesizeKey("m", {});
+ check_read_status([curMessage], true);
+});
+
+add_task(async function test_toggle_unread() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+
+ curMessage.markRead(true);
+ EventUtils.synthesizeKey("m", {});
+ check_read_status([curMessage], false);
+});
+
+add_task(async function test_toggle_mixed() {
+ await be_in_folder(unreadFolder);
+ select_click_row(0);
+ let curMessages = select_shift_click_row(1);
+
+ curMessages[0].markRead(false);
+ curMessages[1].markRead(true);
+ EventUtils.synthesizeKey("m", {});
+ check_read_status(curMessages, true);
+
+ curMessages[0].markRead(true);
+ curMessages[1].markRead(false);
+ EventUtils.synthesizeKey("m", {});
+ check_read_status(curMessages, false);
+});
+
+add_task(async function test_mark_menu_read() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+
+ curMessage.markRead(false);
+ await check_read_menuitems(0, true, false);
+});
+
+add_task(async function test_mark_menu_unread() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+
+ curMessage.markRead(true);
+ await check_read_menuitems(0, false, true);
+});
+
+add_task(async function test_mark_menu_mixed() {
+ await be_in_folder(unreadFolder);
+ select_click_row(0);
+ let curMessages = select_shift_click_row(1);
+
+ curMessages[0].markRead(false);
+ curMessages[1].markRead(true);
+
+ await check_read_menuitems(0, true, true);
+});
+
+add_task(async function test_mark_all_read() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+ curMessage.markRead(false);
+
+ // Make sure we can mark all read with >0 messages unread.
+ await right_click_on_row(0);
+ await wait_for_popup_to_open(getMailContext());
+ await click_menus_in_sequence(getMailContext(), [
+ { id: "mailContext-mark" },
+ { id: "mailContext-markAllRead" },
+ ]);
+ await close_popup(mc, getMailContext());
+
+ Assert.ok(curMessage.isRead, "Message should have been marked read!");
+
+ // Make sure we can't mark all read, now that all messages are already read.
+ await right_click_on_row(0);
+ await wait_for_popup_to_open(getMailContext());
+ let hiddenPromise = BrowserTestUtils.waitForEvent(
+ getMailContext(),
+ "popuphidden"
+ );
+ await click_menus_in_sequence(getMailContext(), [{ id: "mailContext-mark" }]);
+ await hiddenPromise;
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ let allReadDisabled = getMailContext().querySelector(
+ "#mailContext-markAllRead"
+ ).disabled;
+ Assert.ok(allReadDisabled, "Mark All Read menu item should be disabled!");
+});
+
+add_task(async function test_mark_thread_as_read() {
+ let unreadThreadFolder = await create_folder("UnreadThreadFolder");
+ await add_message_sets_to_folders([unreadThreadFolder], [create_thread(3)]);
+ await be_in_folder(unreadThreadFolder);
+ make_display_threaded();
+
+ let serviceState = Services.prefs.getBoolPref(
+ "mailnews.mark_message_read.auto"
+ );
+ if (serviceState) {
+ // If mailnews.mark_message_read.auto is true, then we set it to false.
+ Services.prefs.setBoolPref("mailnews.mark_message_read.auto", false);
+ }
+
+ // Make sure Mark Thread as Read is enabled with >0 messages in thread unread.
+ await right_click_on_row(0);
+ await wait_for_popup_to_open(getMailContext());
+ await click_menus_in_sequence(getMailContext(), [{ id: "mailContext-mark" }]);
+
+ let markThreadAsReadDisabled = mc.window.document.getElementById(
+ "mailContext-markThreadAsRead"
+ ).disabled;
+ Assert.ok(
+ !markThreadAsReadDisabled,
+ "Mark Thread as read menu item should not be disabled!"
+ );
+
+ // Make sure messages are read when Mark Thread as Read is clicked.
+ await right_click_on_row(0);
+ await wait_for_popup_to_open(getMailContext());
+ await click_menus_in_sequence(getMailContext(), [
+ { id: "mailContext-mark" },
+ { id: "mailContext-markThreadAsRead" },
+ ]);
+ await close_popup(mc, getMailContext());
+
+ let curMessage = select_click_row(0);
+ Assert.ok(curMessage.isRead, "Message should have been marked read!");
+
+ // Make sure Mark Thread as Read is now disabled with all messages read.
+ await right_click_on_row(0);
+ await wait_for_popup_to_open(getMailContext());
+ await click_menus_in_sequence(getMailContext(), [{ id: "mailContext-mark" }]);
+
+ markThreadAsReadDisabled = mc.window.document.getElementById(
+ "mailContext-markThreadAsRead"
+ ).disabled;
+ Assert.ok(
+ markThreadAsReadDisabled,
+ "Mark Thread as read menu item should be disabled!"
+ );
+
+ // Make sure that adding an unread message enables Mark Thread as Read once more.
+ curMessage.markRead(false);
+ await right_click_on_row(0);
+ await wait_for_popup_to_open(getMailContext());
+ await click_menus_in_sequence(getMailContext(), [{ id: "mailContext-mark" }]);
+
+ markThreadAsReadDisabled = mc.window.document.getElementById(
+ "mailContext-markThreadAsRead"
+ ).disabled;
+ Assert.ok(
+ !markThreadAsReadDisabled,
+ "Mark Thread as read menu item should not be disabled!"
+ );
+
+ Services.prefs.setBoolPref("mailnews.mark_message_read.auto", true);
+}).__skipMe = true; // See bug 654362.
+
+add_task(async function roving_multi_message_buttons() {
+ await be_in_folder(unreadFolder);
+ select_click_row(0);
+ let curMessages = select_shift_click_row(1);
+ assert_selected_and_displayed(curMessages);
+
+ let multiMsgView = get_about_3pane().multiMessageBrowser;
+ const BUTTONS_SELECTOR = `toolbarbutton:not([hidden="true"]`;
+ let headerToolbar = multiMsgView.contentDocument.getElementById(
+ "header-view-toolbar"
+ );
+ let headerButtons = headerToolbar.querySelectorAll(BUTTONS_SELECTOR);
+
+ // Press tab twice while on the message selected to access the multi message
+ // view header buttons.
+ EventUtils.synthesizeKey("KEY_Tab", {});
+ EventUtils.synthesizeKey("KEY_Tab", {});
+ Assert.equal(
+ headerButtons[0].id,
+ multiMsgView.contentDocument.activeElement.id,
+ "focused on first msgHdr toolbar button"
+ );
+
+ // Simulate the Arrow Right keypress to make sure the correct button gets the
+ // focus.
+ for (let i = 1; i < headerButtons.length; i++) {
+ let previousElement = document.activeElement;
+ EventUtils.synthesizeKey("KEY_ArrowRight", {});
+ Assert.equal(
+ multiMsgView.contentDocument.activeElement.id,
+ headerButtons[i].id,
+ "The next button is focused"
+ );
+ Assert.ok(
+ multiMsgView.contentDocument.activeElement.tabIndex == 0 &&
+ previousElement.tabIndex == -1,
+ "The roving tab index was updated"
+ );
+ }
+
+ // Simulate the Arrow Left keypress to make sure the correct button gets the
+ // focus.
+ for (let i = headerButtons.length - 2; i > -1; i--) {
+ let previousElement = document.activeElement;
+ EventUtils.synthesizeKey("KEY_ArrowLeft", {});
+ Assert.equal(
+ multiMsgView.contentDocument.activeElement.id,
+ headerButtons[i].id,
+ "The previous button is focused"
+ );
+ Assert.ok(
+ multiMsgView.contentDocument.activeElement.tabIndex == 0 &&
+ previousElement.tabIndex == -1,
+ "The roving tab index was updated"
+ );
+ }
+
+ // Check that once the Escape key is pressed twice, focus will move back to
+ // the selected messages.
+ EventUtils.synthesizeKey("KEY_Escape", {});
+ EventUtils.synthesizeKey("KEY_Escape", {});
+ assert_selected_and_displayed(curMessages);
+}).__skipMe = AppConstants.platform == "macosx";
+
+add_task(async function test_shift_delete_prompt() {
+ await be_in_folder(shiftDeleteFolder);
+ let curMessage = select_click_row(0);
+ goUpdateCommand("cmd_shiftDelete");
+
+ // First, try shift-deleting and then cancelling at the prompt.
+ Services.prefs.setBoolPref("mail.warn_on_shift_delete", true);
+ let dialogPromise = BrowserTestUtils.promiseAlertDialog("cancel");
+ // We don't use press_delete here because we're not actually deleting this
+ // time!
+ SimpleTest.ignoreAllUncaughtExceptions(true);
+ EventUtils.synthesizeKey("VK_DELETE", { shiftKey: true });
+ SimpleTest.ignoreAllUncaughtExceptions(false);
+ await dialogPromise;
+ // Make sure we didn't actually delete the message.
+ Assert.equal(curMessage, select_click_row(0));
+
+ // Second, try shift-deleting and then accepting the deletion.
+ dialogPromise = BrowserTestUtils.promiseAlertDialog("accept");
+ press_delete(mc, { shiftKey: true });
+ await dialogPromise;
+ // Make sure we really did delete the message.
+ Assert.notEqual(curMessage, select_click_row(0));
+
+ // Finally, try shift-deleting when we turned off the prompt.
+ Services.prefs.setBoolPref("mail.warn_on_shift_delete", false);
+ curMessage = select_click_row(0);
+ press_delete(mc, { shiftKey: true });
+
+ // Make sure we really did delete the message.
+ Assert.notEqual(curMessage, select_click_row(0));
+
+ Services.prefs.clearUserPref("mail.warn_on_shift_delete");
+});
+
+add_task(async function test_thread_delete_prompt() {
+ await be_in_folder(threadDeleteFolder);
+ make_display_threaded();
+ collapse_all_threads();
+
+ let curMessage = select_click_row(0);
+ goUpdateCommand("cmd_delete");
+ // First, try deleting and then cancelling at the prompt.
+ Services.prefs.setBoolPref("mail.warn_on_collapsed_thread_operation", true);
+ let dialogPromise = BrowserTestUtils.promiseAlertDialog("cancel");
+ // We don't use press_delete here because we're not actually deleting this
+ // time!
+ SimpleTest.ignoreAllUncaughtExceptions(true);
+ EventUtils.synthesizeKey("VK_DELETE", {});
+ SimpleTest.ignoreAllUncaughtExceptions(false);
+ await dialogPromise;
+ // Make sure we didn't actually delete the message.
+ Assert.equal(curMessage, select_click_row(0));
+
+ // Second, try deleting and then accepting the deletion.
+ dialogPromise = BrowserTestUtils.promiseAlertDialog("accept");
+ press_delete(mc);
+ await dialogPromise;
+ // Make sure we really did delete the message.
+ Assert.notEqual(curMessage, select_click_row(0));
+
+ // Finally, try shift-deleting when we turned off the prompt.
+ Services.prefs.setBoolPref("mail.warn_on_collapsed_thread_operation", false);
+ curMessage = select_click_row(0);
+ press_delete(mc);
+
+ // Make sure we really did delete the message.
+ Assert.notEqual(curMessage, select_click_row(0));
+
+ Services.prefs.clearUserPref("mail.warn_on_collapsed_thread_operation");
+}).skip(); // TODO: not working
+
+add_task(async function test_yearly_archive() {
+ await yearly_archive(false);
+});
+
+async function yearly_archive(keep_structure) {
+ await be_in_folder(archiveSrcFolder);
+ make_display_unthreaded();
+
+ let win = get_about_3pane();
+ win.sortController.sortThreadPane("byDate");
+ win.sortController.sortAscending();
+
+ let identity = MailServices.accounts.getFirstIdentityForServer(
+ win.gDBView.getMsgHdrAt(0).folder.server
+ );
+ identity.archiveGranularity = Ci.nsIMsgIdentity.perYearArchiveFolders;
+ // We need to get all the info about the messages before we do the archive,
+ // because deleting the headers could make extracting values from them fail.
+ let firstMsgHdr = win.gDBView.getMsgHdrAt(0);
+ let lastMsgHdr = win.gDBView.getMsgHdrAt(12);
+ let firstMsgHdrMsgId = firstMsgHdr.messageId;
+ let lastMsgHdrMsgId = lastMsgHdr.messageId;
+ let firstMsgDate = new Date(firstMsgHdr.date / 1000);
+ let firstMsgYear = firstMsgDate.getFullYear().toString();
+ let lastMsgDate = new Date(lastMsgHdr.date / 1000);
+ let lastMsgYear = lastMsgDate.getFullYear().toString();
+
+ win.threadTree.scrollToIndex(0, true);
+ await TestUtils.waitForCondition(
+ () => win.threadTree.getRowAtIndex(0),
+ "Row 0 scrolled into view"
+ );
+ select_click_row(0);
+ win.threadTree.scrollToIndex(12, true);
+ await TestUtils.waitForCondition(
+ () => win.threadTree.getRowAtIndex(12),
+ "Row 12 scrolled into view"
+ );
+ select_control_click_row(12);
+
+ // Press the archive key. The results should go into two separate years.
+ archive_selected_messages();
+
+ // Figure out where the messages should have gone.
+ let archiveRoot = "mailbox://nobody@Local%20Folders/Archives";
+ let firstArchiveUri = archiveRoot + "/" + firstMsgYear;
+ let lastArchiveUri = archiveRoot + "/" + lastMsgYear;
+ if (keep_structure) {
+ firstArchiveUri += "/ArchiveSrc";
+ lastArchiveUri += "/ArchiveSrc";
+ }
+ let firstArchiveFolder = MailUtils.getOrCreateFolder(firstArchiveUri);
+ let lastArchiveFolder = MailUtils.getOrCreateFolder(lastArchiveUri);
+ await be_in_folder(firstArchiveFolder);
+ Assert.ok(
+ win.gDBView.getMsgHdrAt(0).messageId == firstMsgHdrMsgId,
+ "Message should have been archived to " +
+ firstArchiveUri +
+ ", but it isn't present there"
+ );
+ await be_in_folder(lastArchiveFolder);
+
+ Assert.ok(
+ win.gDBView.getMsgHdrAt(0).messageId == lastMsgHdrMsgId,
+ "Message should have been archived to " +
+ lastArchiveUri +
+ ", but it isn't present there"
+ );
+}
+
+add_task(async function test_monthly_archive() {
+ enable_archiving(true);
+ await monthly_archive(false);
+});
+
+async function monthly_archive(keep_structure) {
+ await be_in_folder(archiveSrcFolder);
+
+ let win = get_about_3pane();
+ let identity = MailServices.accounts.getFirstIdentityForServer(
+ win.gDBView.getMsgHdrAt(0).folder.server
+ );
+ identity.archiveGranularity = Ci.nsIMsgIdentity.perMonthArchiveFolders;
+ select_click_row(0);
+ select_control_click_row(1);
+
+ let firstMsgHdr = win.gDBView.getMsgHdrAt(0);
+ let lastMsgHdr = win.gDBView.getMsgHdrAt(1);
+ let firstMsgHdrMsgId = firstMsgHdr.messageId;
+ let lastMsgHdrMsgId = lastMsgHdr.messageId;
+ let firstMsgDate = new Date(firstMsgHdr.date / 1000);
+ let firstMsgYear = firstMsgDate.getFullYear().toString();
+ let firstMonthFolderName =
+ firstMsgYear +
+ "-" +
+ (firstMsgDate.getMonth() + 1).toString().padStart(2, "0");
+ let lastMsgDate = new Date(lastMsgHdr.date / 1000);
+ let lastMsgYear = lastMsgDate.getFullYear().toString();
+ let lastMonthFolderName =
+ lastMsgYear +
+ "-" +
+ (lastMsgDate.getMonth() + 1).toString().padStart(2, "0");
+
+ // Press the archive key. The results should go into two separate months.
+ archive_selected_messages();
+
+ // Figure out where the messages should have gone.
+ let archiveRoot = "mailbox://nobody@Local%20Folders/Archives";
+ let firstArchiveUri =
+ archiveRoot + "/" + firstMsgYear + "/" + firstMonthFolderName;
+ let lastArchiveUri =
+ archiveRoot + "/" + lastMsgYear + "/" + lastMonthFolderName;
+ if (keep_structure) {
+ firstArchiveUri += "/ArchiveSrc";
+ lastArchiveUri += "/ArchiveSrc";
+ }
+ let firstArchiveFolder = MailUtils.getOrCreateFolder(firstArchiveUri);
+ let lastArchiveFolder = MailUtils.getOrCreateFolder(lastArchiveUri);
+ await be_in_folder(firstArchiveFolder);
+ Assert.ok(
+ win.gDBView.getMsgHdrAt(0).messageId == firstMsgHdrMsgId,
+ "Message should have been archived to Local Folders/" +
+ firstMsgYear +
+ "/" +
+ firstMonthFolderName +
+ "/Archives, but it isn't present there"
+ );
+ await be_in_folder(lastArchiveFolder);
+ Assert.ok(
+ win.gDBView.getMsgHdrAt(0).messageId == lastMsgHdrMsgId,
+ "Message should have been archived to Local Folders/" +
+ lastMsgYear +
+ "/" +
+ lastMonthFolderName +
+ "/Archives, but it isn't present there"
+ );
+}
+
+add_task(async function test_folder_structure_archiving() {
+ enable_archiving(true);
+ Services.prefs.setBoolPref(
+ "mail.identity.default.archive_keep_folder_structure",
+ true
+ );
+ await monthly_archive(true);
+ await yearly_archive(true);
+});
+
+add_task(async function test_selection_after_archive() {
+ let win = get_about_3pane();
+ enable_archiving(true);
+ await be_in_folder(archiveSrcFolder);
+ let identity = MailServices.accounts.getFirstIdentityForServer(
+ win.gDBView.getMsgHdrAt(0).folder.server
+ );
+ identity.archiveGranularity = Ci.nsIMsgIdentity.perMonthArchiveFolders;
+ // We had a bug where we would always select the 0th message after an
+ // archive, so test that we'll actually select the next remaining message
+ // by archiving rows 1 & 2 and verifying that the 3rd message gets selected.
+ // let hdrToSelect =
+ select_click_row(3);
+ select_click_row(1);
+ select_control_click_row(2);
+ archive_selected_messages();
+ // assert_selected_and_displayed(hdrToSelect); TODO
+});
+
+add_task(async function test_disabled_archive() {
+ let win = get_about_message();
+ let win3 = get_about_3pane();
+ enable_archiving(false);
+ await be_in_folder(archiveSrcFolder);
+
+ // test single message
+ let current = select_click_row(0);
+ EventUtils.synthesizeKey("a", {});
+ assert_selected_and_displayed(current);
+
+ Assert.ok(
+ win.document.getElementById("hdrArchiveButton").disabled,
+ "Archive button should be disabled when archiving is disabled!"
+ );
+
+ // test message summaries
+ select_click_row(0);
+ current = select_shift_click_row(2);
+ EventUtils.synthesizeKey("a", {});
+ assert_selected_and_displayed(current);
+
+ let htmlframe = win3.multiMessageBrowser;
+ let archiveBtn = htmlframe.contentDocument.getElementById("hdrArchiveButton");
+ Assert.ok(
+ archiveBtn.collapsed,
+ "Multi-message archive button should be disabled when " +
+ "archiving is disabled!"
+ );
+
+ // test message summaries with "large" selection
+ mc.window.gFolderDisplay.MAX_COUNT_FOR_CAN_ARCHIVE_CHECK = 1;
+ select_click_row(0);
+ current = select_shift_click_row(2);
+ EventUtils.synthesizeKey("a", {});
+ assert_selected_and_displayed(current);
+ mc.window.gFolderDisplay.MAX_COUNT_FOR_CAN_ARCHIVE_CHECK = 100;
+
+ htmlframe = mc.window.document.getElementById("multimessage");
+ archiveBtn = htmlframe.contentDocument.getElementById("hdrArchiveButton");
+ Assert.ok(
+ archiveBtn.collapsed,
+ "Multi-message archive button should be disabled when " +
+ "archiving is disabled!"
+ );
+}).skip();
+
+function check_tag_in_message(message, tag, isSet) {
+ let tagSet = message
+ .getStringProperty("keywords")
+ .split(" ")
+ .includes(tag.key);
+ if (isSet) {
+ Assert.ok(tagSet, "Tag '" + tag.name + "' expected on message!");
+ } else {
+ Assert.ok(!tagSet, "Tag '" + tag.name + "' not expected on message!");
+ }
+}
+
+add_task(async function test_tag_keys() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+
+ EventUtils.synthesizeKey("1", {});
+ check_tag_in_message(curMessage, tagArray[0], true);
+
+ EventUtils.synthesizeKey("2", {});
+ check_tag_in_message(curMessage, tagArray[0], true);
+ check_tag_in_message(curMessage, tagArray[1], true);
+
+ EventUtils.synthesizeKey("0", {});
+ check_tag_in_message(curMessage, tagArray[0], false);
+ check_tag_in_message(curMessage, tagArray[1], false);
+}).skip(); // TODO: not working
+
+add_task(async function test_tag_keys_disabled_in_content_tab() {
+ await be_in_folder(unreadFolder);
+ let curMessage = select_click_row(0);
+
+ mc.window.openAddonsMgr("addons://list/theme");
+ await new Promise(resolve => setTimeout(resolve));
+
+ let tab = mc.window.document.getElementById("tabmail").currentTabInfo;
+ wait_for_content_tab_load(tab, "about:addons", 15000);
+
+ // Make sure pressing the "1" key in a content tab doesn't tag a message
+ check_tag_in_message(curMessage, tagArray[0], false);
+ EventUtils.synthesizeKey("1", {});
+ check_tag_in_message(curMessage, tagArray[0], false);
+
+ mc.window.document.getElementById("tabmail").closeTab(tab);
+}).skip(); // TODO: not working
+
+registerCleanupFunction(function () {
+ // Make sure archiving is enabled at the end
+ enable_archiving(true);
+ Services.prefs.setBoolPref("mailnews.mark_message_read.auto", gAutoRead);
+});