Bug 746371 - keywords set by pop3 incoming filters aren't written into the berkeley mailbox. r+a=Standard8 SEAMONKEY_2_9b4_BUILD1 SEAMONKEY_2_9b4_RELEASE THUNDERBIRD_12_0b5_BUILD1 THUNDERBIRD_12_0b5_RELEASE
authorDavid Bienvenu <dbienvenu@mozilla.com>
Wed, 18 Apr 2012 14:42:09 +0100
changeset 10747 33ee8cf6630f1facd84fb644ef50228c229ffd4e
parent 10743 122d6253f4e800ea5bd2d530610ba9cb7b5093f2
child 10748 5f06485cddb4d5ebf568c899815a71c81c23382a
child 10753 45c8da9513c2bda6014c79e1006207b1a9514ee7
child 10755 377f41cdbd2c0ed972e2ebb3870432b3a118e2c6
push idunknown
push userunknown
push dateunknown
bugs746371
Bug 746371 - keywords set by pop3 incoming filters aren't written into the berkeley mailbox. r+a=Standard8
mailnews/local/src/nsMsgBrkMBoxStore.cpp
mailnews/local/src/nsParseMailbox.cpp
mailnews/local/test/unit/test_pop3FilterActions.js
mailnews/local/test/unit/xpcshell.ini
--- a/mailnews/local/src/nsMsgBrkMBoxStore.cpp
+++ b/mailnews/local/src/nsMsgBrkMBoxStore.cpp
@@ -722,18 +722,17 @@ nsMsgBrkMBoxStore::GetNewMsgOutputStream
     if (NS_FAILED(rv))
     {
       m_outputStreams.Remove(URI);
       NS_RELEASE(*aResult);
     }
   }
   if (!*aResult)
   {
-    rv = MsgNewBufferedFileOutputStream(aResult, mboxFile,
-                                        PR_WRONLY | PR_CREATE_FILE, 00600);
+    rv = MsgGetFileStream(mboxFile, aResult);
     NS_ASSERTION(NS_SUCCEEDED(rv), "failed opening offline store for output");
     if (NS_FAILED(rv))
       printf("failed opening offline store for %s\n", URI.get());
     NS_ENSURE_SUCCESS(rv, rv);
     seekable = do_QueryInterface(*aResult, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
     rv = seekable->Seek(nsISeekableStream::NS_SEEK_END, 0);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/mailnews/local/src/nsParseMailbox.cpp
+++ b/mailnews/local/src/nsParseMailbox.cpp
@@ -2140,17 +2140,21 @@ NS_IMETHODIMP nsParseNewMailState::Apply
         break;
       case nsMsgFilterAction::KillSubthread:
         msgHdr->OrFlags(nsMsgMessageFlags::Ignored, &newFlags);
         break;
       case nsMsgFilterAction::WatchThread:
         msgHdr->OrFlags(nsMsgMessageFlags::Watched, &newFlags);
         break;
       case nsMsgFilterAction::MarkFlagged:
-        msgHdr->MarkFlagged(true);
+        {
+          nsCOMPtr<nsIMutableArray> messageArray(do_CreateInstance(NS_ARRAY_CONTRACTID));
+          messageArray->AppendElement(msgHdr, false);
+          m_downloadFolder->MarkMessagesFlagged(messageArray, true);
+        }
         break;
       case nsMsgFilterAction::ChangePriority:
         nsMsgPriorityValue filterPriority;
         filterAction->GetPriority(&filterPriority);
         msgHdr->SetPriority(filterPriority);
         break;
       case nsMsgFilterAction::AddTag:
       {
@@ -2339,43 +2343,37 @@ nsresult nsParseNewMailState::ApplyForwa
   }
   m_replyTemplateUri.Clear();
   m_msgToForwardOrReply = nsnull;
   return rv;
 }
 
 void nsParseNewMailState::MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr)
 {
-  PRUint32 newFlags;
-  if (m_mailDB)
-  {
-    m_mailDB->MarkHdrRead(msgHdr, true, nsnull);
-  }
-  else
-  {
-    msgHdr->OrFlags(nsMsgMessageFlags::Read, &newFlags);
-    msgHdr->AndFlags(~nsMsgMessageFlags::New, &newFlags);
-  }
+  nsCOMPtr<nsIMutableArray> messageArray(do_CreateInstance(NS_ARRAY_CONTRACTID));
+  messageArray->AppendElement(msgHdr, false);
+  m_downloadFolder->MarkMessagesRead(messageArray, true);
 }
 
 void nsParseNewMailState::MarkFilteredMessageUnread(nsIMsgDBHdr *msgHdr)
 {
   PRUint32 newFlags;
   if (m_mailDB)
   {
     nsMsgKey msgKey;
     msgHdr->GetMessageKey(&msgKey);
     m_mailDB->AddToNewList(msgKey);
-    m_mailDB->MarkHdrRead(msgHdr, false, nsnull);
   }
   else
   {
-    msgHdr->AndFlags(~nsMsgMessageFlags::Read, &newFlags);
     msgHdr->OrFlags(nsMsgMessageFlags::New, &newFlags);
   }
+  nsCOMPtr<nsIMutableArray> messageArray(do_CreateInstance(NS_ARRAY_CONTRACTID));
+  messageArray->AppendElement(msgHdr, false);
+  m_downloadFolder->MarkMessagesRead(messageArray, false);
 }
 
 nsresult nsParseNewMailState::EndMsgDownload()
 {
   if (m_moveCoalescer)
     m_moveCoalescer->PlaybackMoves();
 
   // need to do this for all folders that had messages filtered into them
new file mode 100644
--- /dev/null
+++ b/mailnews/local/test/unit/test_pop3FilterActions.js
@@ -0,0 +1,191 @@
+/*
+ * This file tests that a pop3 add tag filter writes the new tag
+ * into the message keywords header. It also tests marking read,
+ * and flagging messages.
+ *
+ * Original author: David Bienvenu <dbienvenu@mozilla.com>
+ */
+
+
+load("../../../resources/POP3pump.js");
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+Components.utils.import("resource:///modules/mailServices.js");
+Components.utils.import("resource://gre/modules/Services.jsm");
+const gFiles = ["../../../data/bugmail10", "../../../data/bugmail11"];
+
+Services.prefs.setBoolPref("mail.server.default.leave_on_server", true);
+
+const bugmail10_preview = 'Do not reply to this email. You can add comments to this bug at https://bugzilla.mozilla.org/show_bug.cgi?id=436880 -- Configure bugmail: https://bugzilla.mozilla.org/userprefs.cgi?tab=email ------- You are receiving this mail because: -----';
+const bugmail11_preview = 'Bugzilla has received a request to create a user account using your email address (example@example.org). To confirm that you want to create an account using that email address, visit the following link: https://bugzilla.mozilla.org/token.cgi?t=xxx';
+
+var gFilter; // the test filter
+var gFilterList;
+var gCurTestNum = 1;
+const gTestArray =
+[
+  function createFilters() {
+    gFilterList = gPOP3Pump.fakeServer.getFilterList(null);
+    gFilter = gFilterList.createFilter("AddKeyword");
+    let searchTerm = gFilter.createTerm();
+    searchTerm.matchAll = true;
+    gFilter.appendTerm(searchTerm);
+    let tagAction = gFilter.createAction();
+    tagAction.type = Ci.nsMsgFilterAction.AddTag;
+    tagAction.strValue = "TheTag";
+    gFilter.appendAction(tagAction);
+    tagAction = gFilter.createAction();
+    tagAction.type = Ci.nsMsgFilterAction.MarkRead;
+    gFilter.appendAction(tagAction);
+    tagAction = gFilter.createAction();
+    tagAction.type = Ci.nsMsgFilterAction.MarkFlagged;
+    gFilter.appendAction(tagAction);
+    gFilter.enabled = true;
+    gFilter.filterType = Ci.nsMsgFilterType.InboxRule;
+    gFilterList.insertFilterAt(0, gFilter);
+    ++gCurTestNum;
+    doTest();
+  },
+  // just get a message into the local folder
+  function getLocalMessages1() {
+    gPOP3Pump.files = gFiles;
+    gPOP3Pump.onDone = doTest;
+    ++gCurTestNum;
+    gPOP3Pump.run();
+  },
+  function verifyFolders2() {
+    do_check_eq(folderCount(gLocalInboxFolder), 2);
+
+    // invalidate the inbox summary file, to be sure that we wrote the keywords
+    // into the mailbox.
+    gLocalInboxFolder.msgDatabase.summaryValid = false;
+    gLocalInboxFolder.msgDatabase = null;
+    gLocalInboxFolder.ForceDBClosed();
+    try {
+      gLocalInboxFolder.getDatabaseWithReparse(ParseListener, null);
+    } catch (ex) {
+      do_check_true(ex.result == Cr.NS_ERROR_NOT_INITIALIZED);
+    }
+  },
+  function verifyMessages() {
+    let hdrs = [];
+    let keys = [];
+    let asyncResults = new Object;
+    let enumerator = gLocalInboxFolder.msgDatabase.EnumerateMessages();
+    while (enumerator.hasMoreElements())
+    {
+      let hdr = enumerator.getNext().QueryInterface(Ci.nsIMsgDBHdr);
+      keys.push(hdr.messageKey);
+      hdrs.push(hdr);
+    }
+    gLocalInboxFolder.fetchMsgPreviewText(keys, keys.length, false, null, asyncResults);
+    do_check_eq(hdrs[0].getStringProperty('preview'), bugmail10_preview);
+    do_check_eq(hdrs[1].getStringProperty('preview'), bugmail11_preview);
+    do_check_eq(hdrs[0].getStringProperty('keywords'), "TheTag");
+    do_check_eq(hdrs[1].getStringProperty('keywords'), "TheTag");
+    do_check_eq(hdrs[0].flags, Ci.nsMsgMessageFlags.Read |
+                               Ci.nsMsgMessageFlags.Marked);
+    do_check_eq(hdrs[1].flags, Ci.nsMsgMessageFlags.Read |
+                               Ci.nsMsgMessageFlags.Marked);
+    ++gCurTestNum;
+    doTest();
+  },
+];
+
+var ParseListener =
+{
+  OnStartRunningUrl: function (aUrl) {
+  },
+  OnStopRunningUrl: function (aUrl, aExitCode) {
+    do_check_eq(aExitCode, 0);
+    do_check_true(gLocalInboxFolder.msgDatabase.summaryValid);
+    do_check_eq(folderCount(gLocalInboxFolder), 2);
+    ++gCurTestNum;
+    doTest();
+  }
+};
+
+function folderCount(folder)
+{
+  let enumerator = folder.msgDatabase.EnumerateMessages();
+  let count = 0;
+  while (enumerator.hasMoreElements())
+  {
+    count++;
+    let hdr = enumerator.getNext();
+  }
+  return count;
+}
+
+function run_test()
+{
+  // Make sure we're not quarantining messages
+  Services.prefs.setBoolPref("mailnews.downloadToTempFile", false);
+  if (!gLocalInboxFolder)
+    loadLocalMailAccount();
+
+  gMoveFolder = gLocalIncomingServer.rootFolder.createLocalSubfolder("MoveFolder");
+
+  MailServices.mailSession.AddFolderListener(FolderListener,
+                                             Ci.nsIFolderListener.event |
+                                               Ci.nsIFolderListener.added |
+                                               Ci.nsIFolderListener.removed);
+
+  // "Master" do_test_pending(), paired with a do_test_finished() at the end of
+  // all the operations.
+  do_test_pending();
+
+  //start first test
+  doTest();
+}
+
+function doTest()
+{
+  var test = gCurTestNum;
+  if (test <= gTestArray.length)
+  {
+    var testFn = gTestArray[test-1];
+    dump("Doing test " + test + " " + testFn.name + "\n");
+
+    try {
+      testFn();
+    } catch(ex) {
+      do_throw ('TEST FAILED ' + ex);
+    }
+  }
+  else
+    do_timeout(1000, endTest);
+}
+
+// nsIFolderListener implementation
+var FolderListener = {
+  OnItemAdded: function OnItemAdded(aParentItem, aItem) {
+    this._showEvent(aParentItem, "OnItemAdded");
+  },
+  OnItemRemoved: function OnItemRemoved(aParentItem, aItem) {
+    this._showEvent(aParentItem, "OnItemRemoved");
+    // continue test, as all tests remove a message during the move
+    do_timeout(0, doTest);
+  },
+  OnItemEvent: function OnItemEvent(aEventFolder, aEvent) {
+    this._showEvent(aEventFolder, aEvent.toString())
+  },
+  _showEvent: function showEvent(aFolder, aEventString) {
+        dump("received folder event " + aEventString +
+         " folder " + aFolder.name +
+         "\n");
+  }
+};
+
+function endTest()
+{
+  // Cleanup, null out everything, close all cached connections and stop the
+  // server
+  dump("Exiting mail tests\n");
+  let thread = gThreadManager.currentThread;
+  while (thread.hasPendingEvents())
+    thread.processNextEvent(true);
+  gPOP3Pump = null;
+
+  do_test_finished(); // for the one in run_test()
+}
+
--- a/mailnews/local/test/unit/xpcshell.ini
+++ b/mailnews/local/test/unit/xpcshell.ini
@@ -10,16 +10,17 @@ tail = tail_local.js
 [test_msgCopy.js]
 [test_msgIDParsing.js]
 [test_over2GBMailboxes.js]
 [test_over4GBMailboxes.js]
 [test_pop3AuthMethods.js]
 [test_pop3Download.js]
 [test_pop3DownloadTempFileHandling.js]
 [test_pop3Duplicates.js]
+[test_pop3FilterActions.js]
 [test_pop3GSSAPIFail.js]
 [test_pop3GetNewMail.js]
 [test_pop3MoveFilter.js]
 [test_pop3MoveFilter2.js]
 [test_pop3Password.js]
 [test_pop3Password2.js]
 [test_pop3Password3.js]
 [test_pop3PasswordFailure.js]