summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js')
-rw-r--r--comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js428
1 files changed, 428 insertions, 0 deletions
diff --git a/comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js b/comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js
new file mode 100644
index 0000000000..2d7e00efcc
--- /dev/null
+++ b/comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js
@@ -0,0 +1,428 @@
+/*
+ * This file tests imap filter actions post-plugin, which uses nsMsgFilterAfterTheFact
+ *
+ * Original author: Kent James <kent@caspia.com>
+ * adapted from test_imapFilterActions.js
+ */
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var Is = Ci.nsMsgSearchOp.Is;
+var Subject = Ci.nsMsgSearchAttrib.Subject;
+
+// Globals
+var gSubfolder; // a local message folder used as a target for moves and copies
+var gFilter; // a message filter with a subject search
+var gAction; // current message action (reused)
+var gInboxListener; // database listener object
+var gHeader; // the current message db header
+var gInboxCount; // the previous number of messages in the Inbox
+var gSubfolderCount; // the previous number of messages in the subfolder
+var gMessage = "draft1"; // message file used as the test message
+
+// subject of the test message
+var gMessageSubject = "Hello, did you receive my bugmail?";
+
+// various object references
+var gDbService = Cc["@mozilla.org/msgDatabase/msgDBService;1"].getService(
+ Ci.nsIMsgDBService
+);
+
+// Definition of tests. The test function name is the filter action
+// being tested, with "Body" appended to tests that use delayed
+// application of filters due to a body search
+var gTestArray = [
+ setupIMAPPump,
+ setupFilters,
+ async function DoNothing() {
+ gAction.type = Ci.nsMsgFilterAction.StopExecution;
+ gInboxCount = folderCount(IMAPPump.inbox);
+ await setupTest(gFilter, gAction);
+ testCounts(false, 1, 0, 0);
+ Assert.equal(gInboxCount + 1, folderCount(IMAPPump.inbox));
+ },
+ async function Delete() {
+ gAction.type = Ci.nsMsgFilterAction.Delete;
+ gInboxCount = folderCount(IMAPPump.inbox);
+ await setupTest(gFilter, gAction);
+ testCounts(false, 0, 0, 0);
+ Assert.equal(gInboxCount, folderCount(IMAPPump.inbox));
+ },
+ async function MoveToFolder() {
+ gAction.type = Ci.nsMsgFilterAction.MoveToFolder;
+ gAction.targetFolderUri = gSubfolder.URI;
+ gInboxCount = folderCount(IMAPPump.inbox);
+ gSubfolderCount = folderCount(gSubfolder);
+ await setupTest(gFilter, gAction);
+
+ testCounts(false, 0, 0, 0);
+ Assert.equal(gSubfolderCount + 1, folderCount(gSubfolder));
+ // no net messages were added to the inbox
+ Assert.equal(gInboxCount, folderCount(IMAPPump.inbox));
+ },
+ async function MarkRead() {
+ gAction.type = Ci.nsMsgFilterAction.MarkRead;
+ await setupTest(gFilter, gAction);
+ testCounts(false, 0, 0, 0);
+ Assert.ok(gHeader.isRead);
+ },
+ async function KillThread() {
+ gAction.type = Ci.nsMsgFilterAction.KillThread;
+ await setupTest(gFilter, gAction);
+ // In non-postplugin, count here is 0 and not 1. Need to investigate.
+ testCounts(false, 1, 0, 0);
+ let thread = db().getThreadContainingMsgHdr(gHeader);
+ Assert.notEqual(0, thread.flags & Ci.nsMsgMessageFlags.Ignored);
+ },
+ async function WatchThread() {
+ gAction.type = Ci.nsMsgFilterAction.WatchThread;
+ await setupTest(gFilter, gAction);
+ // In non-postplugin, count here is 0 and not 1. Need to investigate.
+ testCounts(false, 1, 0, 0);
+ let thread = db().getThreadContainingMsgHdr(gHeader);
+ Assert.notEqual(0, thread.flags & Ci.nsMsgMessageFlags.Watched);
+ },
+ async function KillSubthread() {
+ gAction.type = Ci.nsMsgFilterAction.KillSubthread;
+ await setupTest(gFilter, gAction);
+ // In non-postplugin, count here is 0 and not 1. Need to investigate.
+ testCounts(false, 1, 0, 0);
+ Assert.notEqual(0, gHeader.flags & Ci.nsMsgMessageFlags.Ignored);
+ },
+ // this tests for marking message as junk
+ async function JunkScore() {
+ gAction.type = Ci.nsMsgFilterAction.JunkScore;
+ gAction.junkScore = 100;
+ await setupTest(gFilter, gAction);
+ // marking as junk resets new but not unread
+ testCounts(false, 1, 0, 0);
+ Assert.equal(gHeader.getStringProperty("junkscore"), "100");
+ Assert.equal(gHeader.getStringProperty("junkscoreorigin"), "filter");
+ },
+ async function MarkUnread() {
+ gAction.type = Ci.nsMsgFilterAction.MarkUnread;
+ await setupTest(gFilter, gAction);
+ testCounts(true, 1, 1, 1);
+ Assert.ok(!gHeader.isRead);
+ },
+ async function MarkFlagged() {
+ gAction.type = Ci.nsMsgFilterAction.MarkFlagged;
+ await setupTest(gFilter, gAction);
+ testCounts(true, 1, 1, 1);
+ Assert.ok(gHeader.isFlagged);
+ },
+ async function ChangePriority() {
+ gAction.type = Ci.nsMsgFilterAction.ChangePriority;
+ gAction.priority = Ci.nsMsgPriority.highest;
+ await setupTest(gFilter, gAction);
+ testCounts(true, 1, 1, 1);
+ Assert.equal(Ci.nsMsgPriority.highest, gHeader.priority);
+ },
+ async function AddTag() {
+ gAction.type = Ci.nsMsgFilterAction.AddTag;
+ gAction.strValue = "TheTag";
+ await setupTest(gFilter, gAction);
+ testCounts(true, 1, 1, 1);
+ Assert.equal(gHeader.getStringProperty("keywords"), "thetag");
+ },
+ // this tests for marking message as good
+ async function JunkScoreAsGood() {
+ gAction.type = Ci.nsMsgFilterAction.JunkScore;
+ gAction.junkScore = 0;
+ await setupTest(gFilter, gAction);
+ testCounts(true, 1, 1, 1);
+ Assert.equal(gHeader.getStringProperty("junkscore"), "0");
+ Assert.equal(gHeader.getStringProperty("junkscoreorigin"), "filter");
+ },
+ async function CopyToFolder() {
+ gAction.type = Ci.nsMsgFilterAction.CopyToFolder;
+ gAction.targetFolderUri = gSubfolder.URI;
+ gInboxCount = folderCount(IMAPPump.inbox);
+ gSubfolderCount = folderCount(gSubfolder);
+ await setupTest(gFilter, gAction);
+ testCounts(true, 1, 1, 1);
+ Assert.equal(gInboxCount + 1, folderCount(IMAPPump.inbox));
+ Assert.equal(gSubfolderCount + 1, folderCount(gSubfolder));
+ },
+ async function Custom() {
+ gAction.type = Ci.nsMsgFilterAction.Custom;
+ gAction.customId = "mailnews@mozilla.org#testOffline";
+ gAction.strValue = "true";
+ actionTestOffline.needsBody = true;
+ await setupTest(gFilter, gAction);
+ testCounts(true, 1, 1, 1);
+ },
+ /**/
+ endTest,
+];
+
+function run_test() {
+ Services.prefs.setBoolPref(
+ "mail.server.default.autosync_offline_stores",
+ false
+ );
+ gTestArray.forEach(x => add_task(x));
+ run_next_test();
+}
+
+function setupFilters() {
+ // Create a non-body filter.
+ let filterList = IMAPPump.incomingServer.getFilterList(null);
+ gFilter = filterList.createFilter("subject");
+ let searchTerm = gFilter.createTerm();
+ searchTerm.attrib = Subject;
+ searchTerm.op = Is;
+ var value = searchTerm.value;
+ value.attrib = Subject;
+ value.str = gMessageSubject;
+ searchTerm.value = value;
+ searchTerm.booleanAnd = false;
+ gFilter.appendTerm(searchTerm);
+ gFilter.filterType = Ci.nsMsgFilterType.PostPlugin;
+ gFilter.enabled = true;
+
+ // an action that can be modified by tests
+ gAction = gFilter.createAction();
+
+ MailServices.filters.addCustomAction(actionTestOffline);
+ MailServices.mailSession.AddFolderListener(
+ FolderListener,
+ Ci.nsIFolderListener.event
+ );
+ gSubfolder = localAccountUtils.rootFolder.createLocalSubfolder("Subfolder");
+ gPreviousUnread = 0;
+}
+
+/*
+ * functions used to support test setup and execution
+ */
+
+// basic preparation done for each test
+async function setupTest(aFilter, aAction) {
+ let filterList = IMAPPump.incomingServer.getFilterList(null);
+ while (filterList.filterCount) {
+ filterList.removeFilterAt(0);
+ }
+ if (aFilter) {
+ aFilter.clearActionList();
+ if (aAction) {
+ aFilter.appendAction(aAction);
+ filterList.insertFilterAt(0, aFilter);
+ }
+ }
+ if (gInboxListener) {
+ gDbService.unregisterPendingListener(gInboxListener);
+ }
+
+ gInboxListener = new DBListener();
+ gDbService.registerPendingListener(IMAPPump.inbox, gInboxListener);
+ IMAPPump.mailbox.addMessage(
+ new ImapMessage(specForFileName(gMessage), IMAPPump.mailbox.uidnext++, [])
+ );
+ let promiseUrlListener = new PromiseTestUtils.PromiseUrlListener();
+ IMAPPump.inbox.updateFolderWithListener(null, promiseUrlListener);
+ await promiseUrlListener.promise;
+ await PromiseTestUtils.promiseDelay(200);
+}
+
+// Cleanup, null out everything, close all cached connections and stop the
+// server
+function endTest() {
+ if (gInboxListener) {
+ gDbService.unregisterPendingListener(gInboxListener);
+ }
+ gInboxListener = null;
+ MailServices.mailSession.RemoveFolderListener(FolderListener);
+ teardownIMAPPump();
+}
+
+/*
+ * listener objects
+ */
+
+// nsIFolderListener implementation
+var FolderListener = {
+ onFolderEvent(aEventFolder, aEvent) {
+ dump(
+ "received folder event " + aEvent + " folder " + aEventFolder.name + "\n"
+ );
+ },
+};
+
+// nsIDBChangeListener implementation. Counts of calls are kept, but not
+// currently used in the tests. Current role is to provide a reference
+// to the new message header (plus give some examples of using db listeners
+// in javascript).
+function DBListener() {
+ this.counts = {};
+ let counts = this.counts;
+ counts.onHdrFlagsChanged = 0;
+ counts.onHdrDeleted = 0;
+ counts.onHdrAdded = 0;
+ counts.onParentChanged = 0;
+ counts.onAnnouncerGoingAway = 0;
+ counts.onReadChanged = 0;
+ counts.onJunkScoreChanged = 0;
+ counts.onHdrPropertyChanged = 0;
+ counts.onEvent = 0;
+}
+
+DBListener.prototype = {
+ onHdrFlagsChanged(aHdrChanged, aOldFlags, aNewFlags, aInstigator) {
+ this.counts.onHdrFlagsChanged++;
+ },
+
+ onHdrDeleted(aHdrChanged, aParentKey, Flags, aInstigator) {
+ this.counts.onHdrDeleted++;
+ },
+
+ onHdrAdded(aHdrChanged, aParentKey, aFlags, aInstigator) {
+ this.counts.onHdrAdded++;
+ gHeader = aHdrChanged;
+ },
+
+ onParentChanged(aKeyChanged, oldParent, newParent, aInstigator) {
+ this.counts.onParentChanged++;
+ },
+
+ onAnnouncerGoingAway(instigator) {
+ if (gInboxListener) {
+ try {
+ IMAPPump.inbox.msgDatabase.removeListener(gInboxListener);
+ } catch (e) {
+ dump(" listener not found\n");
+ }
+ }
+ this.counts.onAnnouncerGoingAway++;
+ },
+
+ onReadChanged(aInstigator) {
+ this.counts.onReadChanged++;
+ },
+
+ onJunkScoreChanged(aInstigator) {
+ this.counts.onJunkScoreChanged++;
+ },
+
+ onHdrPropertyChanged(aHdrToChange, aPreChange, aStatus, aInstigator) {
+ this.counts.onHdrPropertyChanged++;
+ },
+
+ onEvent(aDB, aEvent) {
+ this.counts.onEvent++;
+ },
+};
+
+/*
+ * helper functions
+ */
+
+// return the number of messages in a folder (and check that the
+// folder counts match the database counts)
+function folderCount(folder) {
+ // count using the database
+ let dbCount = [...folder.msgDatabase.enumerateMessages()].length;
+
+ // count using the folder
+ let count = folder.getTotalMessages(false);
+
+ // compare the two
+ Assert.equal(dbCount, count);
+ return dbCount;
+}
+
+// given a test file, return the file uri spec
+function specForFileName(aFileName) {
+ let file = do_get_file("../../../data/" + aFileName);
+ let msgfileuri = Services.io.newFileURI(file).QueryInterface(Ci.nsIFileURL);
+ return msgfileuri.spec;
+}
+
+// shorthand for the inbox message summary database
+function db() {
+ return IMAPPump.inbox.msgDatabase;
+}
+
+// static variables used in testCounts
+var gPreviousUnread;
+
+// Test various counts.
+//
+// aHasNew: folder hasNew flag
+// aUnreadDelta: change in unread count for the folder
+// aFolderNewDelta: change in new count for the folder
+// aDbNewDelta: change in new count for the database
+//
+function testCounts(aHasNew, aUnreadDelta, aFolderNewDelta, aDbNewDelta) {
+ try {
+ let folderNew = IMAPPump.inbox.getNumNewMessages(false);
+ let hasNew = IMAPPump.inbox.hasNewMessages;
+ let unread = IMAPPump.inbox.getNumUnread(false);
+ let arrayOut = db().getNewList();
+ let dbNew = arrayOut.length;
+ dump(
+ " hasNew: " +
+ hasNew +
+ " unread: " +
+ unread +
+ " folderNew: " +
+ folderNew +
+ " dbNew: " +
+ dbNew +
+ " prevUnread " +
+ gPreviousUnread +
+ "\n"
+ );
+ // Assert.equal(aHasNew, hasNew);
+ Assert.equal(aUnreadDelta, unread - gPreviousUnread);
+ gPreviousUnread = unread;
+ // This seems to be reset for each folder update.
+ //
+ // This check seems to be failing in SeaMonkey builds, yet I can see no ill
+ // effects of this in the actual program. Fixing this is complex because of
+ // the messiness of new count management (see bug 507638 for a
+ // refactoring proposal, and attachment 398899 on bug 514801 for one possible
+ // fix to this particular test). So I am disabling this.
+ // Assert.equal(aFolderNewDelta, folderNew);
+ // Assert.equal(aDbNewDelta, dbNew - gPreviousDbNew);
+ // gPreviousDbNew = dbNew;
+ } catch (e) {
+ dump(e);
+ }
+}
+
+// custom action to test offline status
+var actionTestOffline = {
+ id: "mailnews@mozilla.org#testOffline",
+ name: "test if offline",
+ applyAction(aMsgHdrs, aActionValue, aListener, aType, aMsgWindow) {
+ for (let msgHdr of aMsgHdrs) {
+ let isOffline = !!(msgHdr.flags & Ci.nsMsgMessageFlags.Offline);
+ dump(
+ "in actionTestOffline, flags are " +
+ msgHdr.flags +
+ " subject is " +
+ msgHdr.subject +
+ " isOffline is " +
+ isOffline +
+ "\n"
+ );
+ // XXX TODO: the offline flag is not set here when it should be in postplugin filters
+ // Assert.equal(isOffline, aActionValue == 'true');
+ Assert.equal(msgHdr.subject, gMessageSubject);
+ }
+ },
+ isValidForType(type, scope) {
+ return true;
+ },
+
+ validateActionValue(value, folder, type) {
+ return null;
+ },
+
+ allowDuplicates: false,
+
+ needsBody: true, // set during test setup
+};