summaryrefslogtreecommitdiffstats
path: root/comm/mail/test/browser/folder-display/browser_messageCommandsOnMsgstore.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mail/test/browser/folder-display/browser_messageCommandsOnMsgstore.js')
-rw-r--r--comm/mail/test/browser/folder-display/browser_messageCommandsOnMsgstore.js333
1 files changed, 333 insertions, 0 deletions
diff --git a/comm/mail/test/browser/folder-display/browser_messageCommandsOnMsgstore.js b/comm/mail/test/browser/folder-display/browser_messageCommandsOnMsgstore.js
new file mode 100644
index 0000000000..899a211de8
--- /dev/null
+++ b/comm/mail/test/browser/folder-display/browser_messageCommandsOnMsgstore.js
@@ -0,0 +1,333 @@
+/* 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 some commands on messages via the UI. But we specifically check,
+ * whether the commands have an effect in the message store on disk, i.e. the
+ * markings on the messages are stored in the msgStore, not only in the database.
+ * For now, it checks for bug 840418.
+ */
+
+"use strict";
+
+var utils = ChromeUtils.import("resource://testing-common/mozmill/utils.jsm");
+const {
+ open_compose_with_forward,
+ open_compose_with_reply,
+ setup_msg_contents,
+} = ChromeUtils.import("resource://testing-common/mozmill/ComposeHelpers.jsm");
+const {
+ be_in_folder,
+ create_folder,
+ empty_folder,
+ get_special_folder,
+ make_message_sets_in_folders,
+ mc,
+ press_delete,
+ right_click_on_row,
+ select_click_row,
+} = ChromeUtils.import(
+ "resource://testing-common/mozmill/FolderDisplayHelpers.jsm"
+);
+const {
+ click_menus_in_sequence,
+ plan_for_window_close,
+ wait_for_window_close,
+} = ChromeUtils.import("resource://testing-common/mozmill/WindowHelpers.jsm");
+
+const { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+let gInbox;
+let gOutbox;
+let gAutoRead;
+
+add_setup(async function () {
+ gAutoRead = Services.prefs.getBoolPref("mailnews.mark_message_read.auto");
+ Services.prefs.setBoolPref("mailnews.mark_message_read.auto", false);
+
+ gOutbox = await get_special_folder(Ci.nsMsgFolderFlags.Queue);
+ gInbox = await create_folder("MsgStoreChecks");
+ await make_message_sets_in_folders([gInbox], [{ count: 6 }]);
+
+ // We delete the first message so that we have to compact anything.
+ await be_in_folder(gInbox);
+ let curMessage = select_click_row(0);
+ press_delete(mc);
+ Assert.notEqual(curMessage, select_click_row(0));
+
+ let urlListener = {
+ compactDone: false,
+
+ OnStartRunningUrl(aUrl) {},
+ OnStopRunningUrl(aUrl, aExitCode) {
+ Assert.equal(aExitCode, 0);
+ Assert.ok(gInbox.msgDatabase.summaryValid);
+ this.compactDone = true;
+ },
+ };
+
+ // Compaction adds the X-Mozilla-Status rows into the messages
+ // that we will need later on.
+ Assert.ok(gInbox.msgStore.supportsCompaction);
+ gInbox.compact(urlListener, null);
+
+ utils.waitFor(
+ function () {
+ return urlListener.compactDone;
+ },
+ "Timeout waiting for compact to complete",
+ 10000,
+ 100
+ );
+});
+
+/**
+ * Checks that a message has particular status stored in the mbox file,
+ * in the X-Mozilla-Status header.
+ *
+ * @param folder The folder containing the message to check.
+ * @param offset Offset to the start of the message within mbox file.
+ * @param expectedStatus The required status of the message.
+ */
+async function check_status(folder, offset, expectedStatus) {
+ let mboxstring = await IOUtils.readUTF8(folder.filePath.path);
+
+ // Ah-hoc header parsing. Only check the first 1KB because the X-Mozilla-*
+ // headers should be near the start.
+ let msg = mboxstring.slice(offset, offset + 1024);
+ msg = msg.replace(/\r/g, ""); // Simplify by using LFs only.
+ for (let line of msg.split("\n")) {
+ if (line == "") {
+ break; // end of header block.
+ }
+ if (line.startsWith("X-Mozilla-Status:")) {
+ let hexValue = /:\s*([0-9a-f]+)/i.exec(line)[1];
+ let gotStatus = parseInt(hexValue, 16);
+ Assert.equal(
+ gotStatus,
+ expectedStatus,
+ `Check X-Mozilla-Status (for msg at offset ${offset})`
+ );
+ return;
+ }
+ }
+ // If we got this far, we didn't find the header.
+ Assert.ok(
+ false,
+ `Find X-Mozilla-Status header (for msg at offset ${offset})`
+ );
+}
+
+add_task(async function test_mark_messages_read() {
+ be_in_folder(gOutbox); // TODO shouldn't have to swap folders
+ // 5 messages in the folder
+ await be_in_folder(gInbox);
+ let curMessage = select_click_row(0);
+ // Store the offset because it will be unavailable via the hdr
+ // after the message is deleted.
+ let offset = curMessage.messageOffset;
+ await check_status(gInbox, offset, 0); // status = unread
+ press_delete(mc);
+ Assert.notEqual(curMessage, select_click_row(0));
+ await check_status(
+ gInbox,
+ offset,
+ Ci.nsMsgMessageFlags.Read + Ci.nsMsgMessageFlags.Expunged
+ );
+
+ // 4 messages in the folder.
+ curMessage = select_click_row(0);
+ await check_status(gInbox, curMessage.messageOffset, 0); // status = unread
+
+ // Make sure we can mark all read with >0 messages unread.
+ await right_click_on_row(0);
+ let hiddenPromise = BrowserTestUtils.waitForEvent(
+ getMailContext(),
+ "popuphidden"
+ );
+ await click_menus_in_sequence(getMailContext(), [
+ { id: "mailContext-mark" },
+ { id: "mailContext-markAllRead" },
+ ]);
+ await hiddenPromise;
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ // All the 4 messages should now be read.
+ Assert.ok(curMessage.isRead, "Message should have been marked Read!");
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Read
+ );
+ curMessage = select_click_row(1);
+ Assert.ok(curMessage.isRead, "Message should have been marked Read!");
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Read
+ );
+ curMessage = select_click_row(2);
+ Assert.ok(curMessage.isRead, "Message should have been marked Read!");
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Read
+ );
+ curMessage = select_click_row(3);
+ Assert.ok(curMessage.isRead, "Message should have been marked Read!");
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Read
+ );
+
+ // Let's have the last message unread.
+ await right_click_on_row(3);
+ hiddenPromise = BrowserTestUtils.waitForEvent(
+ getMailContext(),
+ "popuphidden"
+ );
+ await click_menus_in_sequence(getMailContext(), [
+ { id: "mailContext-mark" },
+ { id: "mailContext-markUnread" },
+ ]);
+ await hiddenPromise;
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ Assert.ok(!curMessage.isRead, "Message should have not been marked Read!");
+ await check_status(gInbox, curMessage.messageOffset, 0);
+});
+
+add_task(async function test_mark_messages_flagged() {
+ // Mark a message with the star.
+ let curMessage = select_click_row(1);
+ await right_click_on_row(1);
+ let hiddenPromise = BrowserTestUtils.waitForEvent(
+ getMailContext(),
+ "popuphidden"
+ );
+ await click_menus_in_sequence(getMailContext(), [
+ { id: "mailContext-mark" },
+ { id: "mailContext-markFlagged" },
+ ]);
+ await hiddenPromise;
+ await new Promise(resolve => requestAnimationFrame(resolve));
+
+ Assert.ok(curMessage.isFlagged, "Message should have been marked Flagged!");
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Read + Ci.nsMsgMessageFlags.Marked
+ );
+});
+
+async function subtest_check_queued_message() {
+ // Always check the last message in the Outbox for the correct flag.
+ await be_in_folder(gOutbox);
+ let lastMsg = [...gOutbox.messages].pop();
+ await check_status(
+ gOutbox,
+ lastMsg.messageOffset,
+ Ci.nsMsgMessageFlags.Queued
+ );
+}
+
+/**
+ * Create a reply or forward of a message and queue it for sending later.
+ *
+ * @param aMsgRow Row index of message in Inbox that is to be replied/forwarded.
+ * @param aReply true = reply, false = forward.
+ */
+async function reply_forward_message(aMsgRow, aReply) {
+ await be_in_folder(gInbox);
+ select_click_row(aMsgRow);
+ let cwc;
+ if (aReply) {
+ // Reply to the message.
+ cwc = open_compose_with_reply();
+ } else {
+ // Forward the message.
+ cwc = open_compose_with_forward();
+ // Type in some recipient.
+ setup_msg_contents(cwc, "somewhere@host.invalid", "", "");
+ }
+
+ // Send it later.
+ plan_for_window_close(cwc);
+ // Ctrl+Shift+Return = Send Later
+ cwc.window.document.getElementById("messageEditor").focus();
+ EventUtils.synthesizeKey(
+ "VK_RETURN",
+ {
+ shiftKey: true,
+ accelKey: true,
+ },
+ cwc.window
+ );
+ wait_for_window_close(cwc);
+
+ await subtest_check_queued_message();
+
+ // Now this is hacky. We can't get the message to be sent out of TB because there
+ // is no fake SMTP server support yet.
+ // But we know that upon real sending of the message, the code would/should call
+ // .addMessageDispositionState(). So call it directly and check the expected
+ // flags were set. This is risky as the real code could change and call
+ // a different function and the purpose of this test would be lost.
+ await be_in_folder(gInbox);
+ let curMessage = select_click_row(aMsgRow);
+ let disposition = aReply
+ ? gInbox.nsMsgDispositionState_Replied
+ : gInbox.nsMsgDispositionState_Forwarded;
+ gInbox.addMessageDispositionState(curMessage, disposition);
+}
+
+add_task(async function test_mark_messages_replied() {
+ await reply_forward_message(2, true);
+ let curMessage = select_click_row(2);
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Replied + Ci.nsMsgMessageFlags.Read
+ );
+});
+
+add_task(async function test_mark_messages_forwarded() {
+ await be_in_folder(gInbox);
+ // Forward a clean message.
+ await reply_forward_message(3, false);
+ let curMessage = select_click_row(3);
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Forwarded
+ );
+
+ // Forward a message that is read and already replied to.
+ curMessage = select_click_row(2);
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Replied + Ci.nsMsgMessageFlags.Read
+ );
+ await reply_forward_message(2, false);
+ await check_status(
+ gInbox,
+ curMessage.messageOffset,
+ Ci.nsMsgMessageFlags.Forwarded +
+ Ci.nsMsgMessageFlags.Replied +
+ Ci.nsMsgMessageFlags.Read
+ );
+});
+
+registerCleanupFunction(async function () {
+ Services.prefs.setBoolPref("mailnews.mark_message_read.auto", gAutoRead);
+ // Clear all the created messages.
+ await be_in_folder(gInbox.parent);
+ await empty_folder(gInbox);
+ // await empty_folder(gOutbox); TODO
+ gInbox.server.rootFolder.emptyTrash(null);
+});