diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js | |
parent | Initial commit. (diff) | |
download | thunderbird-upstream.tar.xz thunderbird-upstream.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js')
-rw-r--r-- | comm/mailnews/imap/test/unit/test_imapFilterActionsPostplugin.js | 428 |
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 +}; |