summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/test/resources/msgFolderListenerSetup.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/test/resources/msgFolderListenerSetup.js')
-rw-r--r--comm/mailnews/test/resources/msgFolderListenerSetup.js429
1 files changed, 429 insertions, 0 deletions
diff --git a/comm/mailnews/test/resources/msgFolderListenerSetup.js b/comm/mailnews/test/resources/msgFolderListenerSetup.js
new file mode 100644
index 0000000000..72eaedb7a3
--- /dev/null
+++ b/comm/mailnews/test/resources/msgFolderListenerSetup.js
@@ -0,0 +1,429 @@
+/* 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/. */
+
+// ChromeUtils.import should be used for this, but it breaks mozmill.
+// Assume whatever test loaded this file already has mailTestUtils.
+/* globals mailTestUtils */
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var allTestedEvents =
+ MailServices.mfn.msgAdded |
+ MailServices.mfn.msgsClassified |
+ MailServices.mfn.msgsJunkStatusChanged |
+ MailServices.mfn.msgsDeleted |
+ MailServices.mfn.msgsMoveCopyCompleted |
+ MailServices.mfn.msgKeyChanged |
+ MailServices.mfn.msgUnincorporatedMoved |
+ MailServices.mfn.folderAdded |
+ MailServices.mfn.folderDeleted |
+ MailServices.mfn.folderMoveCopyCompleted |
+ MailServices.mfn.folderRenamed |
+ MailServices.mfn.folderCompactStart |
+ MailServices.mfn.folderCompactFinish |
+ MailServices.mfn.folderReindexTriggered;
+
+// Current test being executed
+var gTest = 1;
+
+// Which events are expected
+var gExpectedEvents = [];
+
+// The current status (what all has been done)
+var gCurrStatus = 0;
+var kStatus = {
+ notificationsDone: 0x1,
+ onStopCopyDone: 0x2,
+ functionCallDone: 0x4,
+ everythingDone: 0,
+};
+kStatus.everythingDone =
+ kStatus.notificationsDone | kStatus.onStopCopyDone | kStatus.functionCallDone;
+
+// For copyFileMessage: this stores the header that was received
+var gHdrsReceived = [];
+
+var gMsgHdrs = [];
+
+// Our listener, which captures events and verifies them as they are received.
+var gMFListener = {
+ msgAdded(aMsg) {
+ verify([MailServices.mfn.msgAdded, aMsg]);
+ // We might not actually have a header in gHdrsReceived in the IMAP case,
+ // so use the aMsg we got instead
+ gMsgHdrs.push({ hdr: aMsg, ID: aMsg.messageId });
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ } else if (gExpectedEvents[0][0] == MailServices.mfn.msgsClassified) {
+ // XXX this is a hack to deal with limitations of the classification logic
+ // and the new list. We want to issue a call to clear the list once all
+ // the messages have been added, which would be when the next expected
+ // event is msgsClassified. (The limitation is that if we don't do this,
+ // we can end up getting told about this message again later.)
+ aMsg.folder.clearNewMessages();
+ }
+ },
+
+ msgsClassified(aMsgs, aJunkProcessed, aTraitProcessed) {
+ dump("classified id: " + aMsgs[0].messageId + "\n");
+ verify([
+ MailServices.mfn.msgsClassified,
+ aMsgs,
+ aJunkProcessed,
+ aTraitProcessed,
+ ]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ msgsJunkStatusChanged(messages) {
+ verify([MailServices.mfn.msgsJunkStatusChanged, messages]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ msgsDeleted(aMsgs) {
+ verify([MailServices.mfn.msgsDeleted, aMsgs]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ msgsMoveCopyCompleted(aMove, aSrcMsgs, aDestFolder, aDestMsgs) {
+ verify([
+ MailServices.mfn.msgsMoveCopyCompleted,
+ aMove,
+ aSrcMsgs,
+ aDestFolder,
+ aDestMsgs,
+ ]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ msgKeyChanged(aOldKey, aNewMsgHdr) {
+ verify([MailServices.mfn.msgKeyChanged, aOldKey, aNewMsgHdr]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ msgUnincorporatedMoved(srcFolder, msg) {
+ verify([MailServices.mfn.msgUnincorporatedMoved, srcFolder, msg]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ folderAdded(aFolder) {
+ verify([MailServices.mfn.folderAdded, aFolder]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ folderDeleted(aFolder) {
+ verify([MailServices.mfn.folderDeleted, aFolder]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ folderMoveCopyCompleted(aMove, aSrcFolder, aDestFolder) {
+ verify([
+ MailServices.mfn.folderMoveCopyCompleted,
+ aMove,
+ aSrcFolder,
+ aDestFolder,
+ ]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ folderRenamed(aOrigFolder, aNewFolder) {
+ verify([MailServices.mfn.folderRenamed, aOrigFolder, aNewFolder]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ folderCompactStart(folder) {
+ verify([MailServices.mfn.folderCompactStart, folder]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ folderCompactFinish(folder) {
+ verify([MailServices.mfn.folderCompactFinish, folder]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+
+ folderReindexTriggered(folder) {
+ verify([MailServices.mfn.folderReindexTriggered, folder]);
+ if (gExpectedEvents.length == 0) {
+ gCurrStatus |= kStatus.notificationsDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ }
+ },
+};
+
+// Copy listener, for proceeding after each operation.
+var copyListener = {
+ // For copyFileMessage: this should be the folder the message is being stored to
+ mFolderStoredIn: null,
+ mMessageId: "",
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {
+ gHdrsReceived.push(this.mFolderStoredIn.GetMessageHeader(aKey));
+ },
+ GetMessageId(aMessageId) {
+ aMessageId = { value: this.mMessageId };
+ },
+ OnStopCopy(aStatus) {
+ // Check: message successfully copied.
+ Assert.equal(aStatus, 0);
+ gCurrStatus |= kStatus.onStopCopyDone;
+ if (gCurrStatus == kStatus.everythingDone) {
+ resetStatusAndProceed();
+ }
+ },
+};
+
+function resetStatusAndProceed() {
+ gHdrsReceived.length = 0;
+ gCurrStatus = 0;
+ // Ugly hack: make sure we don't get stuck in a JS->C++->JS->C++... call stack
+ // This can happen with a bunch of synchronous functions grouped together, and
+ // can even cause tests to fail because they're still waiting for the listener
+ // to return
+ do_timeout(0, () => {
+ this.doTest(++gTest);
+ });
+}
+
+// Checks whether the array returned from a function has exactly these elements.
+function hasExactlyElements(array, elements) {
+ // If an nsIArray (it could also be a single header or a folder)
+ if (elements instanceof Ci.nsIArray) {
+ var count = elements.length;
+
+ // Check: array sizes should be equal.
+ Assert.equal(count, array.length);
+
+ for (let i = 0; i < count; i++) {
+ // Check: query element, must be a header or folder and present in the array
+ var currElement;
+ try {
+ currElement = elements.queryElementAt(i, Ci.nsIMsgDBHdr);
+ } catch (e) {}
+ if (!currElement) {
+ try {
+ currElement = elements.queryElementAt(i, Ci.nsIMsgFolder);
+ } catch (e) {}
+ }
+ Assert.equal(typeof currElement, "object");
+ Assert.notEqual(
+ mailTestUtils.non_strict_index_of(array, currElement),
+ -1
+ );
+ }
+ } else if (Array.isArray(elements)) {
+ Assert.equal(elements.length, array.length);
+ for (let el of elements) {
+ Assert.equal(typeof el, "object");
+ Assert.equal(
+ el instanceof Ci.nsIMsgDBHdr || el instanceof Ci.nsIMsgFolder,
+ true
+ );
+ Assert.notEqual(mailTestUtils.non_strict_index_of(array, el), -1);
+ }
+ } else if (
+ elements instanceof Ci.nsIMsgDBHdr ||
+ elements instanceof Ci.nsIMsgFolder
+ ) {
+ // If a single header or a folder
+
+ // Check: there should be only one element in the array.
+ Assert.equal(array.length, 1);
+
+ // Check: the element should be present
+ Assert.notEqual(mailTestUtils.non_strict_index_of(array, elements), -1);
+ } else {
+ // This shouldn't happen
+ do_throw("Unrecognized item returned from listener");
+ }
+}
+
+// Verifies an event
+function verify(event) {
+ // Check: make sure we actually have an item to process
+ Assert.ok(gExpectedEvents.length >= 1);
+ var expected = gExpectedEvents.shift();
+
+ // Check: events match.
+ var eventType = expected[0];
+ Assert.equal(event[0], eventType);
+
+ dump("..... Verifying event type " + eventType + "\n");
+
+ switch (eventType) {
+ case MailServices.mfn.msgAdded:
+ // So for IMAP right now, we aren't able to get the actual nsIMsgDBHdr.
+ // Instead, we'll match up message ids as a (poor?) substitute.
+ if (expected[1].expectedMessageId) {
+ Assert.equal(expected[1].expectedMessageId, event[1].messageId);
+ break;
+ }
+ // If we do have a header, fall through to the case below
+ case MailServices.mfn.msgsDeleted:
+ case MailServices.mfn.folderDeleted:
+ // Check: headers match/folder matches.
+ hasExactlyElements(expected[1], event[1]);
+ break;
+ case MailServices.mfn.msgsClassified:
+ // In the IMAP case expected[1] is a list of mesage-id strings whereas in
+ // the local case (where we are copying from files), we actually have
+ // the headers.
+ if (typeof expected[1][0] == "string") {
+ // IMAP; message id strings
+ // The IMAP case has additional complexity in that the 'new message'
+ // list is not tailored to our needs and so may over-report about
+ // new messagse. So to deal with this we make sure the msgsClassified
+ // event is telling us about at least the N expected events and that
+ // the last N of these events match
+ if (event[1].length < expected[1].length) {
+ do_throw("Not enough reported classified messages.");
+ }
+ let ignoreCount = event[1].length - expected[1].length;
+ for (let i = 0; i < expected[1].length; i++) {
+ let eventHeader = event[1][i + ignoreCount];
+ Assert.equal(expected[1][i], eventHeader.messageId);
+ }
+ } else {
+ // actual headers
+ hasExactlyElements(expected[1], event[1]);
+ }
+ // aJunkProcessed: was the message processed for junk?
+ Assert.equal(expected[2], event[2]);
+ // aTraitProcessed: was the message processed for traits?
+ Assert.equal(expected[3], event[3]);
+ break;
+ case MailServices.mfn.msgsJunkStatusChanged:
+ // Check: same messages?
+ hasExactlyElements(expected[1], event[1]);
+ break;
+ case MailServices.mfn.msgKeyChanged:
+ Assert.equal(expected[1].expectedMessageId, event[2].messageId);
+ break;
+ case MailServices.mfn.msgUnincorporatedMoved:
+ // Check: Same folder?
+ Assert.equal(expected[1].URI, event[1].URI);
+ // Check: message matches?
+ hasExactlyElements(expected[2], event[2]);
+ break;
+ case MailServices.mfn.msgsMoveCopyCompleted:
+ case MailServices.mfn.folderMoveCopyCompleted:
+ // Check: Move or copy as expected.
+ Assert.equal(expected[1], event[1]);
+
+ // Check: headers match/folder matches.
+ hasExactlyElements(expected[2], event[2]);
+
+ // Check: destination folder matches.
+ Assert.equal(expected[3].URI, event[3].URI);
+
+ if (eventType == MailServices.mfn.folderMoveCopyCompleted) {
+ break;
+ }
+
+ // Check: destination headers. We expect these for local and imap folders,
+ // but we will not have heard about the headers ahead of time,
+ // so the best we can do is make sure they match up. To this end,
+ // we check that the message-id header values match up.
+ for (let iMsg = 0; iMsg < event[2].length; iMsg++) {
+ let srcHdr = event[2][iMsg];
+ let destHdr = event[4][iMsg];
+ Assert.equal(srcHdr.messageId, destHdr.messageId);
+ }
+ break;
+ case MailServices.mfn.folderAdded:
+ // Check: parent folder matches
+ Assert.equal(expected[1].URI, event[1].parent.URI);
+
+ // Check: folder name matches
+ Assert.equal(expected[2], event[1].prettyName);
+ Assert.equal(expected[2], event[1].name);
+
+ // Not a check, but call the passed in callback with the new folder,
+ // used e.g. to store this folder somewhere.
+ if (expected[3]) {
+ expected[3](event[1]);
+ }
+ break;
+ case MailServices.mfn.folderRenamed:
+ // Check: source folder matches
+ hasExactlyElements(expected[1], event[1]);
+
+ // Check: destination folder name matches
+ Assert.equal(expected[2], event[2].prettyName);
+ break;
+ case MailServices.mfn.folderCompactStart:
+ case MailServices.mfn.folderCompactFinish:
+ case MailServices.mfn.folderReindexTriggered:
+ // Check: same folder?
+ Assert.equal(expected[1].URI, event[1].URI);
+ break;
+ }
+}