Bug 540385 - Manually marking a message as NOT JUNK is insufficient; message gets refiled as junk (imapPump test framework), r=bienvenu
authorKent James <kent@caspia.com>
Thu, 08 Apr 2010 09:41:41 -0700
changeset 5401 e677ea9438fa1e3538048a1094b3f648cbef94ff
parent 5400 359fc1dbd00e9a0ca26149db9d3f80e21c08999d
child 5402 5c3ab02dab302404ba19840d7d0033a63dfd14bb
push idunknown
push userunknown
push dateunknown
reviewersbienvenu
bugs540385
Bug 540385 - Manually marking a message as NOT JUNK is insufficient; message gets refiled as junk (imapPump test framework), r=bienvenu
mailnews/base/test/unit/test_imapPump.js
mailnews/imap/test/unit/test_preserveDataOnMove.js
mailnews/test/resources/IMAPpump.js
new file mode 100644
--- /dev/null
+++ b/mailnews/base/test/unit/test_imapPump.js
@@ -0,0 +1,105 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Kent James <kent@caspia.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This test is intended as a simple demonstration of the imap pump test method
+
+// async support 
+load("../../mailnews/resources/logHelper.js");
+load("../../mailnews/resources/mailTestUtils.js");
+load("../../mailnews/resources/asyncTestUtils.js");
+
+// IMAP pump
+load("../../mailnews/resources/IMAPpump.js");
+
+// Globals
+
+// Messages to load must have CRLF line endings, that is Windows style
+const gMessage = "bugmail10"; // message file used as the test message
+
+setupIMAPPump();
+
+// Definition of tests
+var tests = [
+  loadImapMessage,
+  endTest
+]
+
+// load and update a message in the imap fake server
+function loadImapMessage()
+{
+  gIMAPMailbox.addMessage(new imapMessage(specForFileName(gMessage),
+                          gIMAPMailbox.uidnext++, []));
+  gIMAPInbox.updateFolderWithListener(null, asyncUrlListener);
+  yield false;
+  do_check_eq(1, gIMAPInbox.getTotalMessages(false));
+  let msgHdr = firstMsgHdr(gIMAPInbox);
+  do_check_true(msgHdr instanceof Ci.nsIMsgDBHdr);
+  yield true;
+}
+
+// Cleanup at end
+function endTest()
+{
+  teardownIMAPPump();
+}
+
+function run_test()
+{
+  async_run_tests(tests);
+}
+
+/*
+ * helper functions
+ */
+
+// get the first message header found in a folder
+function firstMsgHdr(folder) {
+  let enumerator = folder.messages;
+  if (enumerator.hasMoreElements())
+    return enumerator.getNext().QueryInterface(Ci.nsIMsgDBHdr);
+  return null;
+}
+
+// given a test file, return the file uri spec
+function specForFileName(aFileName)
+{
+  let file = do_get_file("../../mailnews/data/" + aFileName);
+  let msgfileuri = Cc["@mozilla.org/network/io-service;1"]
+                     .getService(Ci.nsIIOService)
+                     .newFileURI(file)
+                     .QueryInterface(Ci.nsIFileURL);
+  return msgfileuri.spec;
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/imap/test/unit/test_preserveDataOnMove.js
@@ -0,0 +1,207 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Kent James <kent@caspia.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+// This tests that arbitrary message header properties are preserved
+//  during online move of an imap message.
+
+// async support 
+load("../../mailnews/resources/logHelper.js");
+load("../../mailnews/resources/mailTestUtils.js");
+load("../../mailnews/resources/asyncTestUtils.js");
+
+// IMAP pump
+load("../../mailnews/resources/IMAPpump.js");
+
+// Globals
+
+const gMessage = "bugmail10"; // message file used as the test message
+
+setupIMAPPump();
+
+// Definition of tests
+var tests = [
+  createSubfolder,
+  loadImapMessage,
+  moveMessageToSubfolder,
+  testPropertyOnMove,
+  endTest
+]
+
+let gSubfolder;
+function createSubfolder()
+{
+  gIMAPIncomingServer.rootFolder.createSubfolder("Subfolder", null);
+  dl('wait for folderAdded notification');
+  yield false; 
+  gSubfolder = gIMAPIncomingServer.rootFolder.getChildNamed("Subfolder");
+  do_check_true(gSubfolder instanceof Ci.nsIMsgImapMailFolder);
+  gSubfolder.updateFolderWithListener(null, UrlListener);
+  dl('wait for OnStopRunningURL');
+  yield false;
+}  
+
+// load and update a message in the imap fake server
+function loadImapMessage()
+{
+  gIMAPMailbox.addMessage(new imapMessage(specForFileName(gMessage),
+                          gIMAPMailbox.uidnext++, []));
+  gIMAPInbox.updateFolder(null);
+  dl('wait for msgAdded notification');
+  yield false;
+  do_check_eq(1, gIMAPInbox.getTotalMessages(false));
+  let msgHdr = firstMsgHdr(gIMAPInbox);
+  do_check_true(msgHdr instanceof Ci.nsIMsgDBHdr);
+
+  // set an arbitrary property
+  msgHdr.setStringProperty("testprop", "somevalue");
+  yield true;
+}
+
+// move the message to a subfolder
+function moveMessageToSubfolder()
+{
+  let msgHdr = firstMsgHdr(gIMAPInbox);
+
+  // Now move this message to the subfolder.
+  var messages = Cc["@mozilla.org/array;1"]
+                   .createInstance(Ci.nsIMutableArray);
+  messages.appendElement(msgHdr, false);
+  /*
+  void CopyMessages(in nsIMsgFolder srcFolder,
+                    in nsIArray messages,
+                    in nsIMsgFolder dstFolder,
+                    in boolean isMove,
+                    in nsIMsgCopyServiceListener listener,
+                    in nsIMsgWindow msgWindow,
+                    in boolean allowUndo);
+  */
+
+  let copyService = Cc["@mozilla.org/messenger/messagecopyservice;1"]
+                      .getService(Ci.nsIMsgCopyService);
+  copyService.CopyMessages(gIMAPInbox, messages, gSubfolder, true,
+                           asyncCopyListener, null, false);
+  dl('wait for OnStopCopy');
+  yield false;
+}
+
+var UrlListener = {
+  OnStartRunningUrl: function _OnStartRunningUrl(aUrl) {
+    dl('OnStartRunningUrl');
+  },
+  OnStopRunningUrl: function _OnStopRunningUrl(aUrl, aExitCode) {
+    dl('OnStopRunningUrl');
+    async_driver();
+  }
+};
+
+function testPropertyOnMove()
+{
+  gSubfolder.updateFolderWithListener(null, UrlListener);
+  dl('wait for msgAdded');
+  yield false; // wait for msgAdded notification
+  dl('wait for OnStopRunningURL');
+  yield false; // wait for OnStopRunningUrl
+  let msgHdr = firstMsgHdr(gSubfolder);
+  do_check_eq(msgHdr.getStringProperty("testprop"), "somevalue");
+  yield true;
+}
+
+// Cleanup
+function endTest()
+{
+  teardownIMAPPump();
+}
+
+// listeners
+
+mfnListener =
+{
+  folderAdded: function folderAdded(aFolder)
+  {
+    dl('folderAdded <' + aFolder.name + '>');
+    // we are only using async yield on the Subfolder add
+    if (aFolder.name == "Subfolder")
+      async_driver();
+  },
+
+  msgAdded: function msgAdded(aMsg)
+  {
+    dl('msgAdded with subject <' + aMsg.subject + '>')
+    async_driver();
+  },
+
+};
+
+function run_test()
+{
+  // Add folder listeners that will capture async events
+  const nsIMFNService = Ci.nsIMsgFolderNotificationService;
+  var MFNService = Cc["@mozilla.org/messenger/msgnotificationservice;1"]
+                      .getService(nsIMFNService);
+  let flags =
+        nsIMFNService.folderAdded |
+        nsIMFNService.msgAdded;
+  MFNService.addListener(mfnListener, flags);
+  async_run_tests(tests);
+}
+
+/*
+ * helper functions
+ */
+
+// get the first message header found in a folder
+function firstMsgHdr(folder) {
+  let enumerator = folder.messages;
+  if (enumerator.hasMoreElements())
+    return enumerator.getNext().QueryInterface(Ci.nsIMsgDBHdr);
+  return null;
+}
+
+// given a test file, return the file uri spec
+function specForFileName(aFileName)
+{
+  let file = do_get_file("../../mailnews/data/" + aFileName);
+  let msgfileuri = Cc["@mozilla.org/network/io-service;1"]
+                     .getService(Ci.nsIIOService)
+                     .newFileURI(file)
+                     .QueryInterface(Ci.nsIFileURL);
+  return msgfileuri.spec;
+}
+
+// shorthand output of a line of text
+function dl(text) {
+  dump(text + '\n');
+}
new file mode 100644
--- /dev/null
+++ b/mailnews/test/resources/IMAPpump.js
@@ -0,0 +1,167 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ *   Kent James <kent@caspia.com>
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/*
+ * This file provides a simple interface to the imap fake server. Demonstration
+ *  of its use can be found in test_imapPump.js
+ *
+ * The code that forms the core of this file, in its original incarnation,
+ *  was test_imapFolderCopy.js  There have been several iterations since
+ *  then.
+ */
+
+// Make sure we execute this file exactly once
+if (typeof gIMAPpump_js__ == "undefined") {
+var gIMAPpump_js__ = true;
+
+// add imap fake server methods if missing
+
+if (typeof gMaild_js__ == "undefined")
+  load("../../mailnews/fakeserver/maild.js");
+if (typeof AuthPLAIN == "undefined")
+  load("../../mailnews/fakeserver/auth.js");
+if (typeof imapDaemon == "undefined")
+  load("../../mailnews/fakeserver/imapd.js");
+
+// define globals
+var gIMAPDaemon;         // the imap fake server daemon
+var gIMAPServer;         // the imap fake server
+var gIMAPIncomingServer; // nsIMsgIncomingServer for the imap server
+var gIMAPInbox;          // nsIMsgFolder/nsIMsgImapMailFolder for imap inbox
+var gIMAPMailbox;        // imap fake server mailbox
+
+function setupIMAPPump()
+{
+
+  // These are copied from imap's head_server.js to here so we can run
+  //   this from any directory.
+
+  const IMAP_PORT = 1024 + 143;
+
+  function makeServer(daemon, infoString) {
+    if (infoString in configurations)
+      return makeServer(daemon, configurations[infoString].join(","));
+
+    var handler = new IMAP_RFC3501_handler(daemon);
+    if (!infoString)
+      infoString = "RFC2195";
+
+    var parts = infoString.split(/ *, */);
+    for each (var part in parts) {
+      if (part.substring(0, 3) == "RFC")
+        mixinExtension(handler, eval("IMAP_" + part + "_extension"));
+    }
+    var server = new nsMailServer(handler);
+    server.start(IMAP_PORT);
+    return server;
+  }
+
+  function createLocalIMAPServer() {
+    var acctmgr = Cc["@mozilla.org/messenger/account-manager;1"]
+                    .getService(Ci.nsIMsgAccountManager);
+
+    var server = acctmgr.createIncomingServer("user", "localhost", "imap");
+    server.port = IMAP_PORT;
+    server.username = "user";
+    server.password = "password";
+    server.valid = false;
+
+    var account = acctmgr.createAccount();
+    account.incomingServer = server;
+    server.valid = true;
+
+    server.QueryInterface(Ci.nsIImapIncomingServer);
+    return server;
+  }
+
+  // end copy from head_server.js
+
+  gIMAPDaemon = new imapDaemon();
+  gIMAPServer = makeServer(gIMAPDaemon, "");
+
+  gIMAPIncomingServer = createLocalIMAPServer();
+
+  if (!this.gLocalInboxFolder)
+    loadLocalMailAccount();
+
+  // We need an identity so that updateFolder doesn't fail
+  let acctMgr = Cc["@mozilla.org/messenger/account-manager;1"]
+                  .getService(Ci.nsIMsgAccountManager);
+  let localAccount = acctMgr.createAccount();
+  let identity = acctMgr.createIdentity();
+  localAccount.addIdentity(identity);
+  localAccount.defaultIdentity = identity;
+  localAccount.incomingServer = gLocalIncomingServer;
+  acctMgr.defaultAccount = localAccount;
+
+  // Let's also have another account, using the same identity
+  let imapAccount = acctMgr.createAccount();
+  imapAccount.addIdentity(identity);
+  imapAccount.defaultIdentity = identity;
+  imapAccount.incomingServer = gIMAPIncomingServer;
+
+  // The server doesn't support more than one connection
+  let prefBranch = Cc["@mozilla.org/preferences-service;1"]
+                     .getService(Ci.nsIPrefBranch);
+  prefBranch.setIntPref("mail.server.default.max_cached_connections", 1);
+  // We aren't interested in downloading messages automatically
+  prefBranch.setBoolPref("mail.server.default.download_on_biff", false);
+  prefBranch.setBoolPref("mail.biff.play_sound", false);
+  prefBranch.setBoolPref("mail.biff.show_alert", false);
+  prefBranch.setBoolPref("mail.biff.show_tray_icon", false);
+  prefBranch.setBoolPref("mail.biff.animate_dock_icon", false);
+  prefBranch.setBoolPref("mail.biff.alert.show_preview", false);
+
+  gIMAPIncomingServer.performExpand(null);
+
+  gIMAPInbox = gIMAPIncomingServer.rootFolder.getChildNamed("INBOX");
+  gIMAPMailbox = gIMAPDaemon.getMailbox("INBOX");
+  gIMAPInbox instanceof Ci.nsIMsgImapMailFolder;
+}
+
+function teardownIMAPPump()
+{
+  gIMAPInbox = null;
+  gIMAPServer.resetTest();
+  gIMAPIncomingServer.closeCachedConnections();
+  gIMAPServer.performTest();
+  gIMAPServer.stop();
+  let thread = gThreadManager.currentThread;
+  while (thread.hasPendingEvents())
+    thread.processNextEvent(true);
+}
+
+} // end run only once