summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/imap/test/unit/test_imapAutoSync.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/imap/test/unit/test_imapAutoSync.js')
-rw-r--r--comm/mailnews/imap/test/unit/test_imapAutoSync.js239
1 files changed, 239 insertions, 0 deletions
diff --git a/comm/mailnews/imap/test/unit/test_imapAutoSync.js b/comm/mailnews/imap/test/unit/test_imapAutoSync.js
new file mode 100644
index 0000000000..1f49a408cc
--- /dev/null
+++ b/comm/mailnews/imap/test/unit/test_imapAutoSync.js
@@ -0,0 +1,239 @@
+/* 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 features of imap autosync
+// N.B. We need to beware of MessageInjection, since it turns off
+// imap autosync.
+
+// Our general approach is to attach an nsIAutoSyncMgrListener to the
+// autoSyncManager, and listen for the expected events. We simulate idle
+// by directly poking the nsIAutoSyncManager QI'd to nsIObserver with app
+// idle events. If we really go idle, duplicate idle events are ignored.
+
+// We test that checking non-inbox folders for new messages isn't
+// interfering with autoSync's detection of new messages.
+
+// We also test that folders that have messages added to them via move/copy
+// get put in the front of the queue.
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+var { MessageGenerator } = ChromeUtils.import(
+ "resource://testing-common/mailnews/MessageGenerator.jsm"
+);
+var { PromiseTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/PromiseTestUtils.jsm"
+);
+
+var msgFlagOffline = Ci.nsMsgMessageFlags.Offline;
+var nsIAutoSyncMgrListener = Ci.nsIAutoSyncMgrListener;
+
+var gAutoSyncManager = Cc["@mozilla.org/imap/autosyncmgr;1"].getService(
+ Ci.nsIAutoSyncManager
+);
+var gTargetFolder;
+
+add_setup(function () {
+ setupIMAPPump();
+ addMessageToFolder(IMAPPump.inbox);
+});
+
+add_task(async function test_createTargetFolder() {
+ gAutoSyncManager.addListener(gAutoSyncListener);
+
+ IMAPPump.incomingServer.rootFolder.createSubfolder("targetFolder", null);
+ await PromiseTestUtils.promiseFolderAdded("targetFolder");
+ gTargetFolder =
+ IMAPPump.incomingServer.rootFolder.getChildNamed("targetFolder");
+ Assert.ok(gTargetFolder instanceof Ci.nsIMsgImapMailFolder);
+ // set folder to be checked for new messages when inbox is checked.
+ gTargetFolder.setFlag(Ci.nsMsgFolderFlags.CheckNew);
+});
+
+add_task(function test_checkForNewMessages() {
+ addMessageToFolder(gTargetFolder);
+ // This will update the INBOX and STATUS targetFolder. We only care about
+ // the latter.
+ IMAPPump.inbox.getNewMessages(null, null);
+ IMAPPump.server.performTest("STATUS");
+ // Now we'd like to make autosync update folders it knows about, to
+ // get the initial autosync out of the way.
+});
+
+add_task(function test_triggerAutoSyncIdle() {
+ // wait for both folders to get updated.
+ gAutoSyncListener._waitingForDiscoveryList.push(IMAPPump.inbox);
+ gAutoSyncListener._waitingForDiscoveryList.push(gTargetFolder);
+ gAutoSyncListener._waitingForDiscovery = true;
+ let observer = gAutoSyncManager.QueryInterface(Ci.nsIObserver);
+ observer.observe(null, "mail-startup-done", "");
+ observer.observe(null, "mail:appIdle", "idle");
+});
+
+// move the message to a diffent folder
+add_task(async function test_moveMessageToTargetFolder() {
+ let observer = gAutoSyncManager.QueryInterface(Ci.nsIObserver);
+ observer.observe(null, "mail:appIdle", "back");
+ let msgHdr = mailTestUtils.firstMsgHdr(IMAPPump.inbox);
+ Assert.ok(msgHdr !== null);
+
+ let listener = new PromiseTestUtils.PromiseCopyListener();
+ // Now move this message to the target folder.
+ MailServices.copy.copyMessages(
+ IMAPPump.inbox,
+ [msgHdr],
+ gTargetFolder,
+ true,
+ listener,
+ null,
+ false
+ );
+ await listener.promise;
+});
+
+add_task(async function test_waitForTargetUpdate() {
+ // After the copy, now we expect to get notified of the gTargetFolder
+ // getting updated, after we simulate going idle.
+ gAutoSyncListener._waitingForUpdate = true;
+ gAutoSyncListener._waitingForUpdateList.push(gTargetFolder);
+ gAutoSyncManager
+ .QueryInterface(Ci.nsIObserver)
+ .observe(null, "mail:appIdle", "idle");
+ await gAutoSyncListener.promiseOnDownloadCompleted;
+ await gAutoSyncListener.promiseOnDiscoveryQProcessed;
+});
+
+// Cleanup
+add_task(function endTest() {
+ let numMsgs = 0;
+ for (let header of gTargetFolder.messages) {
+ numMsgs++;
+ Assert.notEqual(header.flags & Ci.nsMsgMessageFlags.Offline, 0);
+ }
+ Assert.equal(2, numMsgs);
+ Assert.equal(gAutoSyncListener._waitingForUpdateList.length, 0);
+ Assert.ok(!gAutoSyncListener._waitingForDiscovery);
+ Assert.ok(!gAutoSyncListener._waitingForUpdate);
+ teardownIMAPPump();
+});
+
+function autoSyncListenerPromise() {
+ this._inQFolderList = [];
+ this._runnning = false;
+ this._lastMessage = {};
+ this._waitingForUpdateList = [];
+ this._waitingForUpdate = false;
+ this._waitingForDiscoveryList = [];
+ this._waitingForDiscovery = false;
+
+ this._promiseOnDownloadCompleted = new Promise(resolve => {
+ this._resolveOnDownloadCompleted = resolve;
+ });
+ this._promiseOnDiscoveryQProcessed = new Promise(resolve => {
+ this._resolveOnDiscoveryQProcessed = resolve;
+ });
+}
+autoSyncListenerPromise.prototype = {
+ onStateChanged(running) {
+ this._runnning = running;
+ },
+
+ onFolderAddedIntoQ(queue, folder) {
+ dump("Folder added into Q " + this.qName(queue) + " " + folder.URI + "\n");
+ },
+ onFolderRemovedFromQ(queue, folder) {
+ dump(
+ "Folder removed from Q " + this.qName(queue) + " " + folder.URI + "\n"
+ );
+ },
+ onDownloadStarted(folder, numOfMessages, totalPending) {
+ dump("Folder download started" + folder.URI + "\n");
+ },
+
+ onDownloadCompleted(folder) {
+ dump("Folder download completed" + folder.URI + "\n");
+ if (folder instanceof Ci.nsIMsgFolder) {
+ let index = mailTestUtils.non_strict_index_of(
+ this._waitingForUpdateList,
+ folder
+ );
+ if (index != -1) {
+ this._waitingForUpdateList.splice(index, 1);
+ }
+ if (this._waitingForUpdate && this._waitingForUpdateList.length == 0) {
+ dump("Got last folder update looking for.\n");
+ this._waitingForUpdate = false;
+ this._resolveOnDownloadCompleted();
+ }
+ }
+ },
+
+ onDownloadError(folder) {
+ if (folder instanceof Ci.nsIMsgFolder) {
+ dump("OnDownloadError: " + folder.prettyName + "\n");
+ }
+ },
+
+ onDiscoveryQProcessed(folder, numOfHdrsProcessed, leftToProcess) {
+ dump("onDiscoveryQProcessed: " + folder.prettyName + "\n");
+ let index = mailTestUtils.non_strict_index_of(
+ this._waitingForDiscoveryList,
+ folder
+ );
+ if (index != -1) {
+ this._waitingForDiscoveryList.splice(index, 1);
+ }
+ if (
+ this._waitingForDiscovery &&
+ this._waitingForDiscoveryList.length == 0
+ ) {
+ dump("Got last folder discovery looking for\n");
+ this._waitingForDiscovery = false;
+ this._resolveOnDiscoveryQProcessed();
+ }
+ },
+
+ onAutoSyncInitiated(folder) {},
+ qName(queueType) {
+ if (queueType == Ci.nsIAutoSyncMgrListener.PriorityQueue) {
+ return "priorityQ";
+ }
+ if (queueType == Ci.nsIAutoSyncMgrListener.UpdateQueue) {
+ return "updateQ";
+ }
+ if (queueType == Ci.nsIAutoSyncMgrListener.DiscoveryQueue) {
+ return "discoveryQ";
+ }
+ return "";
+ },
+ get promiseOnDownloadCompleted() {
+ return this._promiseOnDownloadCompleted;
+ },
+ get promiseOnDiscoveryQProcessed() {
+ return this._promiseOnDiscoveryQProcessed;
+ },
+};
+var gAutoSyncListener = new autoSyncListenerPromise();
+
+/*
+ * helper functions
+ */
+
+// load and update a message in the imap fake server
+function addMessageToFolder(folder) {
+ let messages = [];
+ let gMessageGenerator = new MessageGenerator();
+ messages = messages.concat(gMessageGenerator.makeMessage());
+
+ let msgURI = Services.io.newURI(
+ "data:text/plain;base64," + btoa(messages[0].toMessageString())
+ );
+ let ImapMailbox = IMAPPump.daemon.getMailbox(folder.name);
+ // We add messages with \Seen flag set so that we won't accidentally
+ // trigger the code that updates imap folders that have unread messages moved
+ // into them.
+ let message = new ImapMessage(msgURI.spec, ImapMailbox.uidnext++, ["\\Seen"]);
+ ImapMailbox.addMessage(message);
+}