summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/search/test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 17:32:43 +0000
commit6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /comm/mailnews/search/test
parentInitial commit. (diff)
downloadthunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz
thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.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 '')
-rw-r--r--comm/mailnews/search/test/moz.build6
-rw-r--r--comm/mailnews/search/test/unit/head_mailbase.js23
-rw-r--r--comm/mailnews/search/test/unit/test_base64_decoding.js94
-rw-r--r--comm/mailnews/search/test/unit/test_bug366491.js110
-rw-r--r--comm/mailnews/search/test/unit/test_bug404489.js202
-rw-r--r--comm/mailnews/search/test/unit/test_copyThenMoveManual.js116
-rw-r--r--comm/mailnews/search/test/unit/test_junkWhitelisting.js204
-rw-r--r--comm/mailnews/search/test/unit/test_quarantineFilterMove.js181
-rw-r--r--comm/mailnews/search/test/unit/test_search.js623
-rw-r--r--comm/mailnews/search/test/unit/test_searchAddressInAb.js337
-rw-r--r--comm/mailnews/search/test/unit/test_searchBody.js294
-rw-r--r--comm/mailnews/search/test/unit/test_searchBoolean.js239
-rw-r--r--comm/mailnews/search/test/unit/test_searchChaining.js90
-rw-r--r--comm/mailnews/search/test/unit/test_searchCustomTerm.js112
-rw-r--r--comm/mailnews/search/test/unit/test_searchJunk.js322
-rw-r--r--comm/mailnews/search/test/unit/test_searchLocalizationStrings.js61
-rw-r--r--comm/mailnews/search/test/unit/test_searchTag.js490
-rw-r--r--comm/mailnews/search/test/unit/test_searchUint32HdrProperty.js141
-rw-r--r--comm/mailnews/search/test/unit/xpcshell.ini20
19 files changed, 3665 insertions, 0 deletions
diff --git a/comm/mailnews/search/test/moz.build b/comm/mailnews/search/test/moz.build
new file mode 100644
index 0000000000..6b37fdbe09
--- /dev/null
+++ b/comm/mailnews/search/test/moz.build
@@ -0,0 +1,6 @@
+# vim: set filetype=python:
+# 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/.
+
+XPCSHELL_TESTS_MANIFESTS += ["unit/xpcshell.ini"]
diff --git a/comm/mailnews/search/test/unit/head_mailbase.js b/comm/mailnews/search/test/unit/head_mailbase.js
new file mode 100644
index 0000000000..9f37623291
--- /dev/null
+++ b/comm/mailnews/search/test/unit/head_mailbase.js
@@ -0,0 +1,23 @@
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+var { XPCOMUtils } = ChromeUtils.importESModule(
+ "resource://gre/modules/XPCOMUtils.sys.mjs"
+);
+var { mailTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/MailTestUtils.jsm"
+);
+var { localAccountUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/LocalAccountUtils.jsm"
+);
+
+var CC = Components.Constructor;
+
+// Ensure the profile directory is set up
+do_get_profile();
+
+var gDEPTH = "../../../../";
+
+registerCleanupFunction(function () {
+ load(gDEPTH + "mailnews/resources/mailShutdown.js");
+});
diff --git a/comm/mailnews/search/test/unit/test_base64_decoding.js b/comm/mailnews/search/test/unit/test_base64_decoding.js
new file mode 100644
index 0000000000..e0f7ddd94d
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_base64_decoding.js
@@ -0,0 +1,94 @@
+/* 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/. */
+
+// This tests that we do not crash when loading the email bodySearchCrash,
+// which was fixed in bug 465805
+
+/* import-globals-from ../../../test/resources/searchTestUtils.js */
+load("../../../resources/searchTestUtils.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var Contains = Ci.nsMsgSearchOp.Contains;
+var Body = Ci.nsMsgSearchAttrib.Body;
+
+var Files = [
+ "../../../data/bugmail1",
+ "../../../data/bodySearchCrash", // Test for bug 465805.
+ "../../../data/base64-with-whitespace.eml", // Test for bug 1487421.
+];
+
+var Tests = [
+ {
+ // this number appears in bugmail1
+ value: "432710",
+ attrib: Body,
+ op: Contains,
+ count: 1,
+ },
+ {
+ // this appears in base64-with-whitespace.eml
+ value: "abcdefghijklmnopqrstuvwxyz",
+ attrib: Body,
+ op: Contains,
+ count: 1,
+ },
+];
+
+function run_test() {
+ // Setup local mail accounts.
+ localAccountUtils.loadLocalMailAccount();
+
+ // Get a message into the local filestore. function testBodySearch() continues the testing after the copy.
+ do_test_pending();
+ copyListener.OnStopCopy(null);
+ return true;
+}
+
+var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {},
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ let fileName = Files.shift();
+ if (fileName) {
+ let file = do_get_file(fileName);
+ MailServices.copy.copyFileMessage(
+ file,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+ } else {
+ testBodySearch();
+ }
+ },
+};
+
+// Runs at completion of copy
+
+// process each test from queue, calls itself upon completion of each search
+function testBodySearch() {
+ print("Test Body Search");
+ var test = Tests.shift();
+ if (test) {
+ new TestSearch(
+ localAccountUtils.inboxFolder,
+ test.value,
+ test.attrib,
+ test.op,
+ test.count,
+ testBodySearch
+ );
+ } else {
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_bug366491.js b/comm/mailnews/search/test/unit/test_bug366491.js
new file mode 100644
index 0000000000..774e8932a3
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_bug366491.js
@@ -0,0 +1,110 @@
+/* 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/. */
+
+// tests return of junk percent from bayesian filter
+
+// main setup
+
+// only needed during debug
+// do_import_script("mailnews/extensions/bayesian-spam-filter/test/resources/trainingfile.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+// local constants
+var kUnclassified = MailServices.junk.UNCLASSIFIED;
+var kJunk = MailServices.junk.JUNK;
+var kGood = MailServices.junk.GOOD;
+
+/*
+ * This test is not intended to check the spam calculations,
+ * but only that the junk percent is transmitted (particularly
+ * for intermediate values). The test
+ * junkPercent values below were calculated by the plugin,
+ * not indepedently verified.
+ */
+
+var tests = [
+ {
+ fileName: "ham2.eml",
+ junkPercent: 8,
+ },
+ {
+ fileName: "spam2.eml",
+ junkPercent: 81,
+ },
+];
+
+var emails = [
+ {
+ fileName: "ham1.eml",
+ classification: kGood,
+ },
+ {
+ fileName: "spam1.eml",
+ classification: kJunk,
+ },
+];
+
+// main test
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+ do_test_pending();
+ doTestingListener.onMessageClassified(null, null, null);
+ return true;
+}
+
+var haveClassification = false;
+var doTestingListener = {
+ onMessageClassified(aMsgURI, aClassification, aJunkPercent) {
+ // Do we have more training emails? If so, train
+ var email = emails.shift();
+ if (email) {
+ MailServices.junk.setMessageClassification(
+ getSpec(email.fileName),
+ kUnclassified,
+ email.classification,
+ null,
+ doTestingListener
+ );
+ return;
+ }
+
+ if (!aMsgURI) {
+ // Ignore end of batch.
+ return;
+ }
+
+ // Have we completed a classification? If so, test
+ if (haveClassification) {
+ let test = tests.shift();
+ Assert.equal(getSpec(test.fileName), aMsgURI);
+ Assert.equal(test.junkPercent, aJunkPercent);
+ }
+
+ // Do we have more classifications to do? Then classify the first one.
+ if (tests.length) {
+ haveClassification = true;
+ MailServices.junk.classifyMessage(
+ getSpec(tests[0].fileName),
+ null,
+ doTestingListener
+ );
+ } else {
+ do_test_finished();
+ }
+ },
+};
+
+// helper functions
+
+function getSpec(aFileName) {
+ var file = do_get_file(
+ "../../../extensions/bayesian-spam-filter/test/unit/resources/" + aFileName
+ );
+ var uri = Services.io.newFileURI(file).QueryInterface(Ci.nsIURL);
+ uri = uri.mutate().setQuery("type=application/x-message-display").finalize();
+ return uri.spec;
+}
diff --git a/comm/mailnews/search/test/unit/test_bug404489.js b/comm/mailnews/search/test/unit/test_bug404489.js
new file mode 100644
index 0000000000..93ae2aac3c
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_bug404489.js
@@ -0,0 +1,202 @@
+/* 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/. */
+
+// Tests that custom headers like "Sender" work (bug 404489)
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var Contains = Ci.nsMsgSearchOp.Contains;
+var gArrayHdrs = ["X-Bugzilla-Who", "Sender"];
+var gFirstHeader = Ci.nsMsgSearchAttrib.OtherHeader + 1;
+var fileName = "../../../data/SenderHeader";
+
+var Tests = [
+ /* test header:
+ X-Bugzilla-Who: bugmail@example.org
+
+ This just shows that normal custom headers work
+ */
+ {
+ testValue: "bugmail",
+ attrib: gFirstHeader,
+ op: Contains,
+ count: 1,
+ },
+ {
+ testValue: "ThisIsNotThere",
+ attrib: gFirstHeader,
+ op: Contains,
+ count: 0,
+ },
+ /* test header:
+ Sender: iamthesender@example.com
+
+ This is the main fix of bug 404489, that we can use Sender as a header
+ */
+ {
+ testValue: "iamthesender",
+ attrib: gFirstHeader + 1,
+ op: Contains,
+ count: 1,
+ },
+ /* test header:
+ From: bugzilla-daemon@mozilla.invalid
+
+ Here we show that the "From" header does not fire tests for the
+ "Sender" arbitrary headers, but does fire the standard test
+ for nsMsgSenderAttrib.Sender
+ */
+ {
+ testValue: "bugzilla",
+ attrib: gFirstHeader + 1,
+ op: Contains,
+ count: 0,
+ },
+ {
+ testValue: "bugzilla",
+ attrib: Ci.nsMsgSearchAttrib.Sender,
+ op: Contains,
+ count: 1,
+ },
+];
+
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+
+ // add the custom headers into the preferences file, ":" delimited
+
+ var hdrs;
+ if (gArrayHdrs.length == 1) {
+ hdrs = gArrayHdrs;
+ } else {
+ hdrs = gArrayHdrs.join(": ");
+ }
+ Services.prefs.setCharPref("mailnews.customHeaders", hdrs);
+
+ // Get a message into the local filestore. function continue_test() continues the testing after the copy.
+ do_test_pending();
+ var file = do_get_file(fileName);
+ MailServices.copy.copyFileMessage(
+ file,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+ return true;
+}
+
+var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {},
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ continue_test();
+ },
+};
+
+// Runs at completion of each copy
+// process each test from queue, calls itself upon completion of each search
+function continue_test() {
+ var test = Tests.shift();
+ if (test) {
+ new TestSearchx(
+ localAccountUtils.inboxFolder,
+ test.testValue,
+ test.attrib,
+ test.op,
+ test.count,
+ continue_test
+ );
+ } else {
+ do_test_finished();
+ }
+}
+
+/*
+ * TestSearchx: Class to test number of search hits
+ *
+ * @param aFolder: the folder to search
+ * @param aValue: value used for the search
+ * The interpretation of aValue depends on aAttrib. It
+ * defaults to string, but for certain attributes other
+ * types are used.
+ * WARNING: not all attributes have been tested.
+ *
+ * @param aAttrib: attribute for the search (Ci.nsMsgSearchAttrib.Size, etc.)
+ * @param aOp: operation for the search (Ci.nsMsgSearchOp.Contains, etc.)
+ * @param aHitCount: expected number of search hits
+ * @param onDone: function to call on completion of search
+ *
+ */
+
+function TestSearchx(aFolder, aValue, aAttrib, aOp, aHitCount, onDone) {
+ var searchListener = {
+ onSearchHit(dbHdr, folder) {
+ hitCount++;
+ },
+ onSearchDone(status) {
+ print("Finished search does " + aHitCount + " equal " + hitCount + "?");
+ searchSession = null;
+ Assert.equal(aHitCount, hitCount);
+ if (onDone) {
+ onDone();
+ }
+ },
+ onNewSearch() {
+ hitCount = 0;
+ },
+ };
+
+ // define and initiate the search session
+
+ var hitCount;
+ var searchSession = Cc[
+ "@mozilla.org/messenger/searchSession;1"
+ ].createInstance(Ci.nsIMsgSearchSession);
+ searchSession.addScopeTerm(Ci.nsMsgSearchScope.offlineMail, aFolder);
+ var searchTerm = searchSession.createTerm();
+ searchTerm.attrib = aAttrib;
+
+ var value = searchTerm.value;
+ // This is tricky - value.attrib must be set before actual values
+ value.attrib = aAttrib;
+ if (aAttrib == Ci.nsMsgSearchAttrib.JunkPercent) {
+ value.junkPercent = aValue;
+ } else if (aAttrib == Ci.nsMsgSearchAttrib.Priority) {
+ value.priority = aValue;
+ } else if (aAttrib == Ci.nsMsgSearchAttrib.Date) {
+ value.date = aValue;
+ } else if (aAttrib == Ci.nsMsgSearchAttrib.MsgStatus) {
+ value.status = aValue;
+ } else if (aAttrib == Ci.nsMsgSearchAttrib.MessageKey) {
+ value.msgKey = aValue;
+ } else if (aAttrib == Ci.nsMsgSearchAttrib.Size) {
+ value.size = aValue;
+ } else if (aAttrib == Ci.nsMsgSearchAttrib.AgeInDays) {
+ value.age = aValue;
+ } else if (aAttrib == Ci.nsMsgSearchAttrib.JunkStatus) {
+ value.junkStatus = aValue;
+ } else if (aAttrib == Ci.nsMsgSearchAttrib.HasAttachmentStatus) {
+ value.status = Ci.nsMsgMessageFlags.Attachment;
+ } else {
+ value.str = aValue;
+ }
+ searchTerm.value = value;
+ if (aAttrib > Ci.nsMsgSearchAttrib.OtherHeader) {
+ searchTerm.arbitraryHeader =
+ gArrayHdrs[aAttrib - 1 - Ci.nsMsgSearchAttrib.OtherHeader];
+ }
+ searchTerm.op = aOp;
+ searchTerm.booleanAnd = false;
+ searchSession.appendTerm(searchTerm);
+ searchSession.registerListener(searchListener);
+ searchSession.search(null);
+}
diff --git a/comm/mailnews/search/test/unit/test_copyThenMoveManual.js b/comm/mailnews/search/test/unit/test_copyThenMoveManual.js
new file mode 100644
index 0000000000..ef34aeb3ca
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_copyThenMoveManual.js
@@ -0,0 +1,116 @@
+/*
+ * This file tests copy followed by a move in a single filter.
+ * Tests fix from bug 448337.
+ *
+ * Original author: Kent James <kent@caspia.com>
+ */
+
+/* import-globals-from ../../../test/resources/POP3pump.js */
+load("../../../resources/POP3pump.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+const { PromiseTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/PromiseTestUtils.jsm"
+);
+
+var gFiles = ["../../../data/bugmail1"];
+var gCopyFolder;
+var gMoveFolder;
+var gFilter; // the test filter
+var gFilterList;
+var gTestArray = [
+ function createFilters() {
+ // setup manual copy then move mail filters on the inbox
+ gFilterList = localAccountUtils.incomingServer.getFilterList(null);
+ gFilter = gFilterList.createFilter("copyThenMoveAll");
+ let searchTerm = gFilter.createTerm();
+ searchTerm.matchAll = true;
+ gFilter.appendTerm(searchTerm);
+ let copyAction = gFilter.createAction();
+ copyAction.type = Ci.nsMsgFilterAction.CopyToFolder;
+ copyAction.targetFolderUri = gCopyFolder.URI;
+ gFilter.appendAction(copyAction);
+ let moveAction = gFilter.createAction();
+ moveAction.type = Ci.nsMsgFilterAction.MoveToFolder;
+ moveAction.targetFolderUri = gMoveFolder.URI;
+ gFilter.appendAction(moveAction);
+ gFilter.enabled = true;
+ gFilter.filterType = Ci.nsMsgFilterType.Manual;
+ gFilterList.insertFilterAt(0, gFilter);
+ },
+ // just get a message into the local folder
+ async function getLocalMessages1() {
+ gPOP3Pump.files = gFiles;
+ await gPOP3Pump.run();
+ },
+ // test applying filters to a message header
+ async function applyFilters() {
+ let promiseFolderEvent = PromiseTestUtils.promiseFolderEvent(
+ localAccountUtils.inboxFolder,
+ "DeleteOrMoveMsgCompleted"
+ );
+ MailServices.filters.applyFilters(
+ Ci.nsMsgFilterType.Manual,
+ [localAccountUtils.inboxFolder.firstNewMessage],
+ localAccountUtils.inboxFolder,
+ null
+ );
+ await promiseFolderEvent;
+ },
+ function verifyFolders1() {
+ // Copy and Move should each now have 1 message in them.
+ Assert.equal(folderCount(gCopyFolder), 1);
+ Assert.equal(folderCount(gMoveFolder), 1);
+ // the local inbox folder should now be empty, since the second
+ // operation was a move
+ Assert.equal(folderCount(localAccountUtils.inboxFolder), 0);
+ },
+ // just get a message into the local folder
+ async function getLocalMessages2() {
+ gPOP3Pump.files = gFiles;
+ await gPOP3Pump.run();
+ },
+ // use the alternate call into the filter service
+ async function applyFiltersToFolders() {
+ let folders = [localAccountUtils.inboxFolder];
+ let promiseFolderEvent = PromiseTestUtils.promiseFolderEvent(
+ localAccountUtils.inboxFolder,
+ "DeleteOrMoveMsgCompleted"
+ );
+ MailServices.filters.applyFiltersToFolders(gFilterList, folders, null);
+ await promiseFolderEvent;
+ },
+ function verifyFolders2() {
+ // Copy and Move should each now have 2 message in them.
+ Assert.equal(folderCount(gCopyFolder), 2);
+ Assert.equal(folderCount(gMoveFolder), 2);
+ // the local inbox folder should now be empty, since the second
+ // operation was a move
+ Assert.equal(folderCount(localAccountUtils.inboxFolder), 0);
+ },
+ function endTest() {
+ // Cleanup, null out everything, close all cached connections and stop the
+ // server
+ dump(" Exiting mail tests\n");
+ gPOP3Pump = null;
+ },
+];
+
+function folderCount(folder) {
+ return [...folder.msgDatabase.enumerateMessages()].length;
+}
+
+function run_test() {
+ if (!localAccountUtils.inboxFolder) {
+ localAccountUtils.loadLocalMailAccount();
+ }
+
+ gCopyFolder = localAccountUtils.rootFolder.createLocalSubfolder("CopyFolder");
+ gMoveFolder = localAccountUtils.rootFolder.createLocalSubfolder("MoveFolder");
+
+ gTestArray.forEach(x => add_task(x));
+
+ run_next_test();
+}
diff --git a/comm/mailnews/search/test/unit/test_junkWhitelisting.js b/comm/mailnews/search/test/unit/test_junkWhitelisting.js
new file mode 100644
index 0000000000..9263de68a2
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_junkWhitelisting.js
@@ -0,0 +1,204 @@
+/* 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/. */
+
+/*
+ * Testing of junk whitelisting
+ */
+
+// add address book setup
+/* import-globals-from ../../../test/resources/abSetup.js */
+load("../../../resources/abSetup.js");
+
+// add fake POP3 server driver
+/* import-globals-from ../../../test/resources/POP3pump.js */
+load("../../../resources/POP3pump.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+/*
+ * The address available in the test address book is "PrimaryEmail1@test.invalid"
+ * Test emails may also include the address "invalid@example.com"
+ *
+ * Map of test email contents: (P is "Prim...", I is "inva.." address)
+ *
+ * Index Bugmail# From
+ * 0 1 P
+ * 1 3 I
+ *
+ */
+
+// indices into hdrs[] of email by domain
+var kDomainTest = 0;
+var kDomainExample = 1;
+
+var Files = ["../../../data/bugmail1", "../../../data/bugmail3"];
+
+var hdrs = [];
+
+function run_test() {
+ loadABFile(
+ "../../../addrbook/test/unit/data/cardForEmail",
+ kPABData.fileName
+ );
+
+ do_test_pending();
+
+ // kick off copying
+ gPOP3Pump.files = Files;
+ gPOP3Pump.onDone = continueTest;
+ gPOP3Pump.run();
+}
+
+function continueTest() {
+ // get the message headers
+ for (let header of localAccountUtils.inboxFolder.messages) {
+ hdrs.push(header);
+ }
+
+ // check with spam properties set on the local server
+ doChecks(localAccountUtils.incomingServer);
+
+ // Free our globals
+ hdrs = null;
+ gPOP3Pump = null;
+ do_test_finished();
+}
+
+function doChecks(server) {
+ let spamSettings = server.spamSettings;
+
+ // default is to use the whitelist
+ Assert.ok(spamSettings.useWhiteList);
+
+ // check email with the address PrimaryEmail1@test.invalid
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // check email without the address
+ Assert.ok(!spamSettings.checkWhiteList(hdrs[kDomainExample]));
+
+ //
+ // check changes in server-level settings. Although the spamSettings object
+ // has methods to set these, those methods are not persistent (which seems
+ // strange). You need to set the actual preference, and call initialize on
+ // spam settings, to get the settings to be saved persistently and stick, then
+ // be recalled into the program. So that's the way that I will test it.
+ //
+
+ // disable whitelisting
+ server.setBoolValue("useWhiteList", false);
+ spamSettings.initialize(server);
+
+ // check that the change was propagated to spamSettings
+ Assert.ok(!spamSettings.useWhiteList);
+
+ // and affects whitelisting calculationss
+ Assert.ok(!spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // re-enable whitelisting
+ server.setBoolValue("useWhiteList", true);
+ spamSettings.initialize(server);
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // Set an empty white list.
+ // To really empty this, I have to change the default value as well
+ Services.prefs.setCharPref("mail.server.default.whiteListAbURI", "");
+ server.setCharValue("whiteListAbURI", "");
+ spamSettings.initialize(server);
+ Assert.ok(!spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // add a trusted domain. This is a global preference
+ Services.prefs.setCharPref("mail.trusteddomains", "example.com");
+ spamSettings.initialize(server);
+
+ // check email with the address invalid@example.com, a trusted domain
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainExample]));
+
+ // check email without the address
+ Assert.ok(!spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // disable the trusted domain
+ Services.prefs.setCharPref("mail.trusteddomains", "");
+ spamSettings.initialize(server);
+ Assert.ok(!spamSettings.checkWhiteList(hdrs[kDomainExample]));
+
+ // add back the Personal Address Book
+ server.setCharValue("whiteListAbURI", kPABData.URI);
+ spamSettings.initialize(server);
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ /*
+ * tests of whitelist suppression by identity
+ */
+
+ // setup
+ let account = MailServices.accounts.FindAccountForServer(server);
+ let identity = MailServices.accounts.createIdentity();
+ // start with an email that does not match
+ identity.email = "iAmNotTheSender@test.invalid";
+ account.addIdentity(identity);
+
+ // setup account and identify for the deferred-from fake server
+ let fakeAccount = MailServices.accounts.createAccount();
+ fakeAccount.incomingServer = gPOP3Pump.fakeServer;
+ let fakeIdentity = MailServices.accounts.createIdentity();
+ // start with an email that does not match
+ fakeIdentity.email = "iAmNotTheSender@wrong.invalid";
+ fakeAccount.addIdentity(fakeIdentity);
+
+ // gPOP3Pump delivers messages to the local inbox regardless of other
+ // settings. But because we are testing here one of those other settings,
+ // let's just pretend that it works like the real POP3 stuff, and set
+ // the correct setting for deferring.
+ gPOP3Pump.fakeServer.setCharValue("deferred_to_account", "account1");
+
+ // suppress whitelisting for sender
+ server.setBoolValue("inhibitWhiteListingIdentityUser", true);
+ spamSettings.initialize(server);
+ // (email does not match yet though)
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // add a matching email (mixing case)
+ identity.email = "PrimaryEMAIL1@test.INVALID";
+ spamSettings.initialize(server);
+ Assert.ok(!spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // remove the matching email
+ identity.email = "iAmNotTheSender@test.invalid";
+ spamSettings.initialize(server);
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // add the email to the deferred-from server
+ fakeIdentity.email = "PrimaryEMAIL1@test.INVALID";
+ spamSettings.initialize(server);
+ Assert.ok(!spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // stop suppressing identity users
+ server.setBoolValue("inhibitWhiteListingIdentityUser", false);
+ spamSettings.initialize(server);
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // remove the matching email from the fake identity
+ fakeIdentity.email = "iAmNotTheSender@wrong.invalid";
+
+ // add a fully non-matching domain to the identity
+ identity.email = "PrimaryEmail1@wrong.invalid";
+
+ // suppress whitelist by matching domain
+ server.setBoolValue("inhibitWhiteListingIdentityDomain", true);
+ spamSettings.initialize(server);
+ // but domain still does not match
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // add a matching email to the identity, in the domain (mixing case)
+ identity.email = "iAmNotTheSender@TEST.invalid";
+ spamSettings.initialize(server);
+ Assert.ok(!spamSettings.checkWhiteList(hdrs[kDomainTest]));
+
+ // stop suppressing whitelist by domain
+ server.setBoolValue("inhibitWhiteListingIdentityDomain", false);
+ spamSettings.initialize(server);
+ Assert.ok(spamSettings.checkWhiteList(hdrs[kDomainTest]));
+}
diff --git a/comm/mailnews/search/test/unit/test_quarantineFilterMove.js b/comm/mailnews/search/test/unit/test_quarantineFilterMove.js
new file mode 100644
index 0000000000..853a3980f4
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_quarantineFilterMove.js
@@ -0,0 +1,181 @@
+/* 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/. */
+
+/*
+ * tests message moves with filter and quarantine enabled per bug 582918.
+ * It then tests that subsequent moves of the filtered messages work.
+ *
+ * adapted from test_copyThenMoveManual.js
+ */
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+const { PromiseTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/PromiseTestUtils.jsm"
+);
+
+/* import-globals-from ../../../test/resources/POP3pump.js */
+load("../../../resources/POP3pump.js");
+
+var gFiles = ["../../../data/bugmail1", "../../../data/bugmail10"];
+
+var gMoveFolder, gMoveFolder2;
+var gFilter; // the test filter
+var gFilterList;
+var gTestArray = [
+ function createFilters() {
+ gFilterList = gPOP3Pump.fakeServer.getFilterList(null);
+ gFilter = gFilterList.createFilter("MoveAll");
+ let searchTerm = gFilter.createTerm();
+ searchTerm.matchAll = true;
+ gFilter.appendTerm(searchTerm);
+ let moveAction = gFilter.createAction();
+ moveAction.type = Ci.nsMsgFilterAction.MoveToFolder;
+ moveAction.targetFolderUri = gMoveFolder.URI;
+ gFilter.appendAction(moveAction);
+ gFilter.enabled = true;
+ gFilter.filterType = Ci.nsMsgFilterType.InboxRule;
+ gFilterList.insertFilterAt(0, gFilter);
+ },
+ // just get a message into the local folder
+ async function getLocalMessages1() {
+ gPOP3Pump.files = gFiles;
+ let promise1 = PromiseTestUtils.promiseFolderNotification(
+ gMoveFolder,
+ "msgsClassified"
+ );
+ let promise2 = gPOP3Pump.run();
+ await Promise.all([promise1, promise2]);
+ },
+ async function verifyFolders1() {
+ Assert.equal(folderCount(gMoveFolder), 2);
+ // the local inbox folder should now be empty, since the second
+ // operation was a move
+ Assert.equal(folderCount(localAccountUtils.inboxFolder), 0);
+
+ let msgs = [...gMoveFolder.msgDatabase.enumerateMessages()];
+ let firstMsgHdr = msgs[0];
+ let secondMsgHdr = msgs[1];
+ // Check that the messages have content
+ let messageContent = await getContentFromMessage(firstMsgHdr);
+ Assert.ok(
+ messageContent.includes("Some User <bugmail@example.org> changed")
+ );
+ messageContent = await getContentFromMessage(secondMsgHdr);
+ Assert.ok(
+ messageContent.includes(
+ "https://bugzilla.mozilla.org/show_bug.cgi?id=436880"
+ )
+ );
+ },
+ async function copyMovedMessages() {
+ let msgs = [...gMoveFolder.msgDatabase.enumerateMessages()];
+ let firstMsgHdr = msgs[0];
+ let secondMsgHdr = msgs[1];
+ let promiseCopyListener = new PromiseTestUtils.PromiseCopyListener();
+ MailServices.copy.copyMessages(
+ gMoveFolder,
+ [firstMsgHdr, secondMsgHdr],
+ gMoveFolder2,
+ false,
+ promiseCopyListener,
+ null,
+ false
+ );
+ let promiseMoveMsg = PromiseTestUtils.promiseFolderEvent(
+ gMoveFolder,
+ "DeleteOrMoveMsgCompleted"
+ );
+ await Promise.all([promiseCopyListener.promise, promiseMoveMsg]);
+ },
+ async function verifyFolders2() {
+ Assert.equal(folderCount(gMoveFolder2), 2);
+
+ let msgs = [...gMoveFolder2.msgDatabase.enumerateMessages()];
+ let firstMsgHdr = msgs[0];
+ let secondMsgHdr = msgs[1];
+ // Check that the messages have content
+ let messageContent = await getContentFromMessage(firstMsgHdr);
+ Assert.ok(
+ messageContent.includes("Some User <bugmail@example.org> changed")
+ );
+ messageContent = await getContentFromMessage(secondMsgHdr);
+ Assert.ok(
+ messageContent.includes(
+ "https://bugzilla.mozilla.org/show_bug.cgi?id=436880"
+ )
+ );
+ },
+ function endTest() {
+ dump("Exiting mail tests\n");
+ gPOP3Pump = null;
+ },
+];
+
+function folderCount(folder) {
+ return [...folder.msgDatabase.enumerateMessages()].length;
+}
+
+function run_test() {
+ /* may not work in Linux */
+ // if ("@mozilla.org/gnome-gconf-service;1" in Cc)
+ // return;
+ /**/
+ // quarantine messages
+ Services.prefs.setBoolPref("mailnews.downloadToTempFile", true);
+ if (!localAccountUtils.inboxFolder) {
+ localAccountUtils.loadLocalMailAccount();
+ }
+
+ gMoveFolder = localAccountUtils.rootFolder.createLocalSubfolder("MoveFolder");
+ gMoveFolder2 =
+ localAccountUtils.rootFolder.createLocalSubfolder("MoveFolder2");
+
+ gTestArray.forEach(x => add_task(x));
+ run_next_test();
+}
+
+/**
+ * Get the full message content.
+ *
+ * @param aMsgHdr - nsIMsgDBHdr object whose text body will be read.
+ * @returns {Promise<string>} full message contents.
+ */
+function getContentFromMessage(aMsgHdr) {
+ let msgFolder = aMsgHdr.folder;
+ let msgUri = msgFolder.getUriForMsg(aMsgHdr);
+
+ return new Promise((resolve, reject) => {
+ let streamListener = {
+ QueryInterface: ChromeUtils.generateQI(["nsIStreamListener"]),
+ sis: Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
+ Ci.nsIScriptableInputStream
+ ),
+ content: "",
+ onDataAvailable(request, inputStream, offset, count) {
+ this.sis.init(inputStream);
+ this.content += this.sis.read(count);
+ },
+ onStartRequest(request) {},
+ onStopRequest(request, statusCode) {
+ this.sis.close();
+ if (Components.isSuccessCode(statusCode)) {
+ resolve(this.content);
+ } else {
+ reject(new Error(statusCode));
+ }
+ },
+ };
+ MailServices.messageServiceFromURI(msgUri).streamMessage(
+ msgUri,
+ streamListener,
+ null,
+ null,
+ false,
+ "",
+ false
+ );
+ });
+}
diff --git a/comm/mailnews/search/test/unit/test_search.js b/comm/mailnews/search/test/unit/test_search.js
new file mode 100644
index 0000000000..98e8874fd3
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_search.js
@@ -0,0 +1,623 @@
+/* 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/. */
+
+/*
+ * Testing of general mail search features.
+ *
+ * This tests some search attributes not tested by other specific tests,
+ * e.g., test_searchTag.js or test_searchJunk.js
+ */
+/* import-globals-from ../../../test/resources/searchTestUtils.js */
+load("../../../resources/searchTestUtils.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var Isnt = Ci.nsMsgSearchOp.Isnt;
+var Is = Ci.nsMsgSearchOp.Is;
+var Contains = Ci.nsMsgSearchOp.Contains;
+var DoesntContain = Ci.nsMsgSearchOp.DoesntContain;
+var BeginsWith = Ci.nsMsgSearchOp.BeginsWith;
+var EndsWith = Ci.nsMsgSearchOp.EndsWith;
+var IsBefore = Ci.nsMsgSearchOp.IsBefore; // control entry not enabled
+var IsAfter = Ci.nsMsgSearchOp.IsAfter;
+var IsHigherThan = Ci.nsMsgSearchOp.IsHigherThan;
+var IsLowerThan = Ci.nsMsgSearchOp.IsLowerThan;
+
+var OtherHeader = Ci.nsMsgSearchAttrib.OtherHeader;
+var From = Ci.nsMsgSearchAttrib.Sender;
+var Subject = Ci.nsMsgSearchAttrib.Subject;
+var Priority = Ci.nsMsgSearchAttrib.Priority;
+var SDate = Ci.nsMsgSearchAttrib.Date;
+
+var Tests = [
+ // test the To: header
+ {
+ testString: "PrimaryEmail1@test.invalid",
+ testAttribute: From,
+ op: Is,
+ count: 1,
+ },
+ {
+ testString: "PrimaryEmail1@test.invalid",
+ testAttribute: From,
+ op: Isnt,
+ count: 0,
+ },
+ {
+ testString: "PrimaryEmail",
+ testAttribute: From,
+ op: BeginsWith,
+ count: 1,
+ },
+ {
+ testString: "invalid",
+ testAttribute: From,
+ op: BeginsWith,
+ count: 0,
+ },
+ {
+ testString: "invalid",
+ testAttribute: From,
+ op: EndsWith,
+ count: 1,
+ },
+ {
+ testString: "Primary",
+ testAttribute: From,
+ op: EndsWith,
+ count: 0,
+ },
+ {
+ testString: "QAContact",
+ testAttribute: OtherHeader,
+ op: BeginsWith,
+ count: 1,
+ },
+ {
+ testString: "filters",
+ testAttribute: OtherHeader,
+ op: BeginsWith,
+ count: 0,
+ },
+ {
+ testString: "mail.bugs",
+ testAttribute: OtherHeader,
+ op: EndsWith,
+ count: 1,
+ },
+ {
+ testString: "QAContact",
+ testAttribute: OtherHeader,
+ op: EndsWith,
+ count: 0,
+ },
+ {
+ testString: "QAcontact filters@mail.bugs",
+ testAttribute: OtherHeader,
+ op: Is,
+ count: 1,
+ },
+ {
+ testString: "filters@mail.bugs",
+ testAttribute: OtherHeader,
+ op: Is,
+ count: 0,
+ },
+ {
+ testString: "QAcontact filters@mail.bugs",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ count: 0,
+ },
+ {
+ testString: "QAcontact",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ testString: "filters",
+ testAttribute: OtherHeader,
+ op: Contains,
+ count: 1,
+ },
+ {
+ testString: "foobar",
+ testAttribute: OtherHeader,
+ op: Contains,
+ count: 0,
+ },
+ // test header with multiple occurrences
+ {
+ testString: "one value",
+ testAttribute: OtherHeader,
+ op: Is,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "second",
+ testAttribute: OtherHeader,
+ op: Is,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "third value for test purposes",
+ testAttribute: OtherHeader,
+ op: Is,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "multiline value that needs to be handled.",
+ testAttribute: OtherHeader,
+ op: Is,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "one value",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ customHeader: "X-Duplicated-Header",
+ count: 0,
+ },
+ {
+ testString: "second",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ customHeader: "X-Duplicated-Header",
+ count: 0,
+ },
+ {
+ testString: "third value for test purposes",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ customHeader: "X-Duplicated-Header",
+ count: 0,
+ },
+ {
+ testString: "multiline value that needs to be handled.",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ customHeader: "X-Duplicated-Header",
+ count: 0,
+ },
+ {
+ testString: "one",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "second",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "purposes",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "value",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "that needs to be",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "fifth",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "is the end my",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "the end",
+ testAttribute: OtherHeader,
+ op: EndsWith,
+ customHeader: "X-Duplicated-Header",
+ count: 0,
+ },
+ {
+ testString: "handled.",
+ testAttribute: OtherHeader,
+ op: EndsWith,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "one value",
+ testAttribute: OtherHeader,
+ op: EndsWith,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "third",
+ testAttribute: OtherHeader,
+ op: BeginsWith,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "This is",
+ testAttribute: OtherHeader,
+ op: BeginsWith,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+
+ {
+ testString: "nothing",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header",
+ count: 0,
+ },
+ {
+ testString: "nothing",
+ testAttribute: OtherHeader,
+ op: DoesntContain,
+ customHeader: "X-Duplicated-Header",
+ count: 1,
+ },
+ {
+ testString: "this header tests DB string properties",
+ testAttribute: OtherHeader,
+ op: Is,
+ customHeader: "X-Duplicated-Header-DB",
+ count: 1,
+ },
+ {
+ testString: "which can be handled",
+ testAttribute: OtherHeader,
+ op: Is,
+ customHeader: "X-Duplicated-Header-DB",
+ count: 1,
+ },
+ {
+ testString: "differently than X-Duplicated-Header, so better test it",
+ testAttribute: OtherHeader,
+ op: Is,
+ customHeader: "X-Duplicated-Header-DB",
+ count: 1,
+ },
+ {
+ testString: "this header tests DB string properties",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ customHeader: "X-Duplicated-Header-DB",
+ count: 0,
+ },
+ {
+ testString: "which can be handled",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ customHeader: "X-Duplicated-Header-DB",
+ count: 0,
+ },
+ {
+ testString: "differently than X-Duplicated-Header, so better test it",
+ testAttribute: OtherHeader,
+ op: Isnt,
+ customHeader: "X-Duplicated-Header-DB",
+ count: 0,
+ },
+ {
+ testString: "than X-Duplicated-Header,",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Duplicated-Header-DB",
+ count: 1,
+ },
+ {
+ testString: "than X-Duplicated-Header, so",
+ testAttribute: OtherHeader,
+ op: DoesntContain,
+ customHeader: "X-Duplicated-Header-DB",
+ count: 0,
+ },
+ // test accumulation of received header
+ {
+ // only in first received
+ testString: "caspiaco",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "Received",
+ count: 1,
+ },
+ {
+ // only in second
+ testString: "webapp01.sj.mozilla.com",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "received",
+ count: 1,
+ },
+ {
+ // in neither
+ testString: "not there",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "received",
+ count: 0,
+ },
+ {
+ // not on first line of received
+ testString: "m47LtAFJ007547",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "received",
+ count: 1,
+ },
+ // test multiple line arbitrary headers
+ {
+ // in the first line
+ testString: "SpamAssassin 3.2.3",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Spam-Checker-Version",
+ count: 1,
+ },
+ {
+ // in the second line
+ testString: "host29.example.com",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Spam-Checker-Version",
+ count: 1,
+ },
+ {
+ // spans two lines with space
+ testString: "on host29.example.com",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "X-Spam-Checker-Version",
+ count: 1,
+ },
+ // subject spanning several lines
+ {
+ // on the first line
+ testString: "A filter will",
+ testAttribute: Subject,
+ op: Contains,
+ count: 1,
+ },
+ {
+ testString: "I do not exist",
+ testAttribute: Subject,
+ op: Contains,
+ count: 0,
+ },
+ {
+ // on the second line
+ testString: "this message",
+ testAttribute: Subject,
+ op: Contains,
+ count: 1,
+ },
+ {
+ // spanning second and third line
+ testString: "over many",
+ testAttribute: Subject,
+ op: Contains,
+ count: 1,
+ },
+ // tests of custom headers db values
+ {
+ testString: "a one line header",
+ dbHeader: "oneliner",
+ },
+ {
+ testString: "a two line header",
+ dbHeader: "twoliner",
+ },
+ {
+ testString: "a three line header with lotsa space and tabs",
+ dbHeader: "threeliner",
+ },
+ {
+ testString: "I have no space",
+ dbHeader: "nospace",
+ },
+ {
+ testString: "too much space",
+ dbHeader: "withspace",
+ },
+ // tests of custom db headers in a search
+ {
+ testString: "one line",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "oneliner",
+ count: 1,
+ },
+ {
+ testString: "two line header",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "twoliner",
+ count: 1,
+ },
+ {
+ testString: "three line header with lotsa",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "threeliner",
+ count: 1,
+ },
+ {
+ testString: "I have no space",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "nospace",
+ count: 1,
+ },
+ {
+ testString: "too much space",
+ testAttribute: OtherHeader,
+ op: Contains,
+ customHeader: "withspace",
+ count: 1,
+ },
+ // test for priority
+ {
+ testString: Ci.nsMsgPriority.lowest,
+ testAttribute: Priority,
+ op: IsHigherThan,
+ count: 1,
+ },
+ {
+ testString: Ci.nsMsgPriority.low,
+ testAttribute: Priority,
+ op: Is,
+ count: 1,
+ },
+ {
+ testString: Ci.nsMsgPriority.normal,
+ testAttribute: Priority,
+ op: IsLowerThan,
+ count: 1,
+ },
+ {
+ testString: Ci.nsMsgPriority.lowest,
+ testAttribute: Priority,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ testString: Ci.nsMsgPriority.low,
+ testAttribute: Priority,
+ op: Isnt,
+ count: 0,
+ },
+
+ // tests of Date header
+ // The internal value of date in the search is PRTime (nanoseconds since Epoch).
+ // Date().getTime() returns milliseconds since Epoch.
+ // The dates used here are tailored for the ../../../data/bugmail12 message.
+ {
+ testString: new Date("Wed, 7 May 2008 14:55:10 -0700").getTime() * 1000,
+ testAttribute: SDate,
+ op: Is,
+ count: 1,
+ },
+ {
+ testString: new Date("Thu, 8 May 2008 14:55:10 -0700").getTime() * 1000,
+ testAttribute: SDate,
+ op: IsBefore,
+ count: 1,
+ },
+ {
+ testString: new Date("Tue, 6 May 2008 14:55:10 -0700").getTime() * 1000,
+ testAttribute: SDate,
+ op: IsAfter,
+ count: 1,
+ },
+ {
+ testString: new Date("Tue, 6 May 2008 14:55:10 -0700").getTime() * 1000,
+ testAttribute: SDate,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ // check bug 248808
+ testString: new Date("Wed, 7 May 2008 14:55:10 -0700").getTime() * 1000,
+ testAttribute: SDate,
+ op: IsBefore,
+ count: 0,
+ },
+ {
+ testString: new Date("Wed, 7 May 2008 14:55:10 -0700").getTime() * 1000,
+ testAttribute: SDate,
+ op: IsAfter,
+ count: 0,
+ },
+];
+
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+
+ var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {},
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ testSearch();
+ },
+ };
+
+ // set value of headers we want parsed into the db
+ Services.prefs.setCharPref(
+ "mailnews.customDBHeaders",
+ "oneLiner twoLiner threeLiner noSpace withSpace X-Duplicated-Header-DB"
+ );
+ // Get a message into the local filestore. function testSearch() continues
+ // the testing after the copy.
+ var bugmail12 = do_get_file("../../../data/bugmail12");
+ do_test_pending();
+ MailServices.copy.copyFileMessage(
+ bugmail12,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+}
+
+// process each test from queue, calls itself upon completion of each search
+function testSearch() {
+ var test = Tests.shift();
+ if (test && test.dbHeader) {
+ // test of a custom db header
+ dump("testing dbHeader " + test.dbHeader + "\n");
+ let customValue = mailTestUtils
+ .firstMsgHdr(localAccountUtils.inboxFolder)
+ .getStringProperty(test.dbHeader);
+ Assert.equal(customValue, test.testString);
+ do_timeout(0, testSearch);
+ } else if (test) {
+ dump("testing for string '" + test.testString + "'\n");
+ new TestSearch(
+ localAccountUtils.inboxFolder,
+ test.testString,
+ test.testAttribute,
+ test.op,
+ test.count,
+ testSearch,
+ null,
+ test.customHeader ? test.customHeader : "X-Bugzilla-Watch-Reason"
+ );
+ } else {
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_searchAddressInAb.js b/comm/mailnews/search/test/unit/test_searchAddressInAb.js
new file mode 100644
index 0000000000..a93f405047
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchAddressInAb.js
@@ -0,0 +1,337 @@
+/* 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/. */
+
+// Testing of to, cc, toorcc in addressbook search features added in bug 187768
+// Added testing of AllAddresses from bug 310359
+
+/* import-globals-from ../../../test/resources/searchTestUtils.js */
+load("../../../resources/searchTestUtils.js");
+
+// add address book setup
+/* import-globals-from ../../../test/resources/abSetup.js */
+load("../../../resources/abSetup.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var ABUri = kPABData.URI;
+
+var IsntInAB = Ci.nsMsgSearchOp.IsntInAB;
+var IsInAB = Ci.nsMsgSearchOp.IsInAB;
+var IsBefore = Ci.nsMsgSearchOp.IsBefore; // control entry that is not enabled
+var Is = Ci.nsMsgSearchOp.Is;
+var Isnt = Ci.nsMsgSearchOp.Isnt;
+
+var offlineMail = Ci.nsMsgSearchScope.offlineMail;
+var onlineMail = Ci.nsMsgSearchScope.onlineMail;
+var offlineMailFilter = Ci.nsMsgSearchScope.offlineMailFilter;
+var onlineMailFilter = Ci.nsMsgSearchScope.onlineMailFilter;
+var news = Ci.nsMsgSearchScope.news; // control entry that is not enabled
+
+var Sender = Ci.nsMsgSearchAttrib.Sender;
+var To = Ci.nsMsgSearchAttrib.To;
+var CCopy = Ci.nsMsgSearchAttrib.CC;
+var ToOrCC = Ci.nsMsgSearchAttrib.ToOrCC;
+var AllAddresses = Ci.nsMsgSearchAttrib.AllAddresses;
+var Keywords = Ci.nsMsgSearchAttrib.Keywords; // control entry that is not enabled
+
+/*
+ * The address available in the test address book is "PrimaryEmail1@test.invalid"
+ * Test emails may also include the address "invalid@example.com"
+ *
+ *
+ * Map of test email contents: (P is "Prim...", I is "inva.." address, N is none)
+ *
+ *
+ * Email From To CC BCC
+ * 1 P I I N
+ * 2 P P P N
+ * 3 I P I N
+ * 4 I I P N
+ * 5 P I P N
+ * 6 I I,P P,I N
+ * 7 I I I P
+ * 8 I P P N
+ *
+ */
+
+var Tests = [
+ {
+ value: ABUri,
+ attrib: Sender,
+ op: IsInAB,
+ count: 3,
+ },
+ {
+ value: ABUri,
+ attrib: To,
+ op: IsInAB,
+ count: 4,
+ },
+ {
+ value: ABUri,
+ attrib: ToOrCC,
+ op: IsInAB,
+ count: 6,
+ },
+ {
+ value: ABUri,
+ attrib: AllAddresses,
+ op: IsInAB,
+ count: 8,
+ },
+ {
+ value: ABUri,
+ attrib: CCopy,
+ op: IsInAB,
+ count: 5,
+ },
+ {
+ value: ABUri,
+ attrib: Sender,
+ op: IsntInAB,
+ count: 5,
+ },
+ {
+ value: ABUri,
+ attrib: To,
+ op: IsntInAB,
+ count: 5,
+ },
+ {
+ value: ABUri,
+ attrib: ToOrCC,
+ op: IsntInAB,
+ count: 6,
+ },
+ {
+ value: ABUri,
+ attrib: AllAddresses,
+ op: IsntInAB,
+ count: 7,
+ },
+ {
+ value: ABUri,
+ attrib: CCopy,
+ op: IsntInAB,
+ count: 4,
+ },
+ {
+ value: "PrimaryEmail1@test.invalid",
+ attrib: AllAddresses,
+ op: Is,
+ count: 8,
+ },
+ {
+ value: "PrimaryEmail1@test.invalid",
+ attrib: AllAddresses,
+ op: Isnt,
+ count: 0,
+ },
+ {
+ value: "invalid@example.com",
+ attrib: AllAddresses,
+ op: Is,
+ count: 7,
+ },
+ {
+ value: "invalid@example.com",
+ attrib: AllAddresses,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ value: "PrimaryEmail1@test.invalid",
+ attrib: ToOrCC,
+ op: Is,
+ count: 6,
+ },
+ {
+ value: "PrimaryEmail1@test.invalid",
+ attrib: ToOrCC,
+ op: Isnt,
+ count: 2,
+ },
+ {
+ value: "invalid@example.com",
+ attrib: ToOrCC,
+ op: Is,
+ count: 6,
+ },
+ {
+ value: "invalid@example.com",
+ attrib: ToOrCC,
+ op: Isnt,
+ count: 2,
+ },
+];
+
+var Files = [
+ "../../../data/bugmail1",
+ "../../../data/bugmail2",
+ "../../../data/bugmail3",
+ "../../../data/bugmail4",
+ "../../../data/bugmail5",
+ "../../../data/bugmail6",
+ "../../../data/bugmail7",
+ "../../../data/bugmail8",
+];
+
+function run_test() {
+ // Setup local mail accounts.
+ localAccountUtils.loadLocalMailAccount();
+
+ loadABFile(
+ "../../../addrbook/test/unit/data/cardForEmail",
+ kPABData.fileName
+ );
+
+ // test that validity table terms are valid
+
+ // offline mail table
+ testValidityTable(offlineMail, IsInAB, Sender, true);
+ testValidityTable(offlineMail, IsInAB, To, true);
+ testValidityTable(offlineMail, IsInAB, ToOrCC, true);
+ testValidityTable(offlineMail, IsInAB, AllAddresses, true);
+ testValidityTable(offlineMail, IsInAB, CCopy, true);
+ testValidityTable(offlineMail, IsInAB, Keywords, false);
+ testValidityTable(offlineMail, IsntInAB, Sender, true);
+ testValidityTable(offlineMail, IsntInAB, To, true);
+ testValidityTable(offlineMail, IsntInAB, ToOrCC, true);
+ testValidityTable(offlineMail, IsntInAB, AllAddresses, true);
+ testValidityTable(offlineMail, IsntInAB, CCopy, true);
+ testValidityTable(offlineMail, IsntInAB, Keywords, false);
+ testValidityTable(offlineMail, IsBefore, Sender, false);
+ testValidityTable(offlineMail, IsBefore, To, false);
+ testValidityTable(offlineMail, IsBefore, ToOrCC, false);
+ testValidityTable(offlineMail, IsBefore, AllAddresses, false);
+ testValidityTable(offlineMail, IsBefore, CCopy, false);
+ testValidityTable(offlineMail, IsBefore, Keywords, false);
+ testValidityTable(offlineMail, Is, AllAddresses, true);
+ testValidityTable(offlineMail, Isnt, AllAddresses, true);
+
+ // offline mail filter table
+ testValidityTable(offlineMailFilter, IsInAB, Sender, true);
+ testValidityTable(offlineMailFilter, IsInAB, To, true);
+ testValidityTable(offlineMailFilter, IsInAB, ToOrCC, true);
+ testValidityTable(offlineMailFilter, IsInAB, AllAddresses, true);
+ testValidityTable(offlineMailFilter, IsInAB, CCopy, true);
+ testValidityTable(offlineMailFilter, IsInAB, Keywords, false);
+ testValidityTable(offlineMailFilter, IsntInAB, Sender, true);
+ testValidityTable(offlineMailFilter, IsntInAB, To, true);
+ testValidityTable(offlineMailFilter, IsntInAB, AllAddresses, true);
+ testValidityTable(offlineMailFilter, IsntInAB, ToOrCC, true);
+ testValidityTable(offlineMailFilter, IsntInAB, CCopy, true);
+ testValidityTable(offlineMailFilter, IsntInAB, Keywords, false);
+ testValidityTable(offlineMailFilter, IsBefore, Sender, false);
+ testValidityTable(offlineMailFilter, IsBefore, To, false);
+ testValidityTable(offlineMailFilter, IsBefore, ToOrCC, false);
+ testValidityTable(offlineMailFilter, IsBefore, AllAddresses, false);
+ testValidityTable(offlineMailFilter, IsBefore, CCopy, false);
+ testValidityTable(offlineMailFilter, IsBefore, Keywords, false);
+ testValidityTable(offlineMailFilter, Is, AllAddresses, true);
+ testValidityTable(offlineMailFilter, Isnt, AllAddresses, true);
+
+ // online mail
+ testValidityTable(onlineMail, IsInAB, Sender, false);
+ testValidityTable(onlineMail, IsInAB, To, false);
+ testValidityTable(onlineMail, IsInAB, ToOrCC, false);
+ testValidityTable(onlineMail, IsInAB, CCopy, false);
+ testValidityTable(onlineMail, IsInAB, Keywords, false);
+ testValidityTable(onlineMail, IsntInAB, Sender, false);
+ testValidityTable(onlineMail, IsntInAB, To, false);
+ testValidityTable(onlineMail, IsntInAB, ToOrCC, false);
+ testValidityTable(onlineMail, IsntInAB, CCopy, false);
+ testValidityTable(onlineMail, IsntInAB, Keywords, false);
+ testValidityTable(onlineMail, IsBefore, Sender, false);
+ testValidityTable(onlineMail, IsBefore, To, false);
+ testValidityTable(onlineMail, IsBefore, ToOrCC, false);
+ testValidityTable(onlineMail, IsBefore, CCopy, false);
+ testValidityTable(onlineMail, IsBefore, Keywords, false);
+
+ // online mail filter
+ testValidityTable(onlineMailFilter, IsInAB, Sender, true);
+ testValidityTable(onlineMailFilter, IsInAB, To, true);
+ testValidityTable(onlineMailFilter, IsInAB, ToOrCC, true);
+ testValidityTable(onlineMailFilter, IsInAB, CCopy, true);
+ testValidityTable(onlineMailFilter, IsInAB, Keywords, false);
+ testValidityTable(onlineMailFilter, IsntInAB, Sender, true);
+ testValidityTable(onlineMailFilter, IsntInAB, To, true);
+ testValidityTable(onlineMailFilter, IsntInAB, ToOrCC, true);
+ testValidityTable(onlineMailFilter, IsntInAB, CCopy, true);
+ testValidityTable(onlineMailFilter, IsntInAB, Keywords, false);
+ testValidityTable(onlineMailFilter, IsBefore, Sender, false);
+ testValidityTable(onlineMailFilter, IsBefore, To, false);
+ testValidityTable(onlineMailFilter, IsBefore, ToOrCC, false);
+ testValidityTable(onlineMailFilter, IsBefore, CCopy, false);
+ testValidityTable(onlineMailFilter, IsBefore, Keywords, false);
+
+ // news
+ testValidityTable(news, IsInAB, Sender, false);
+ testValidityTable(news, IsInAB, To, false);
+ testValidityTable(news, IsInAB, ToOrCC, false);
+ testValidityTable(news, IsInAB, CCopy, false);
+ testValidityTable(news, IsInAB, Keywords, false);
+ testValidityTable(news, IsntInAB, Sender, false);
+ testValidityTable(news, IsntInAB, To, false);
+ testValidityTable(news, IsntInAB, ToOrCC, false);
+ testValidityTable(news, IsntInAB, CCopy, false);
+ testValidityTable(news, IsntInAB, Keywords, false);
+ testValidityTable(news, IsBefore, Sender, false);
+ testValidityTable(news, IsBefore, To, false);
+ testValidityTable(news, IsBefore, ToOrCC, false);
+ testValidityTable(news, IsBefore, CCopy, false);
+ testValidityTable(news, IsBefore, Keywords, false);
+
+ // Get a message into the local filestore. function testAbSearch() continues the testing after the copy.
+ do_test_pending();
+ copyListener.OnStopCopy(null);
+ return true;
+}
+
+var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {},
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ var fileName = Files.shift();
+ if (fileName) {
+ var file = do_get_file(fileName);
+ MailServices.copy.copyFileMessage(
+ file,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+ } else {
+ testAbSearch();
+ }
+ },
+};
+
+// Runs at completion of copy
+
+// process each test from queue, calls itself upon completion of each search
+function testAbSearch() {
+ print("Test AbSearch");
+ var test = Tests.shift();
+ if (test) {
+ new TestSearch(
+ localAccountUtils.inboxFolder,
+ test.value,
+ test.attrib,
+ test.op,
+ test.count,
+ testAbSearch
+ );
+ } else {
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_searchBody.js b/comm/mailnews/search/test/unit/test_searchBody.js
new file mode 100644
index 0000000000..c2ec73c115
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchBody.js
@@ -0,0 +1,294 @@
+/* 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/. */
+
+/*
+ * This tests various body search criteria.
+ */
+/* import-globals-from ../../../test/resources/searchTestUtils.js */
+load("../../../resources/searchTestUtils.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var Isnt = Ci.nsMsgSearchOp.Isnt;
+var Is = Ci.nsMsgSearchOp.Is;
+var IsEmpty = Ci.nsMsgSearchOp.IsEmpty;
+var IsntEmpty = Ci.nsMsgSearchOp.IsntEmpty;
+var Contains = Ci.nsMsgSearchOp.Contains;
+var DoesntContain = Ci.nsMsgSearchOp.DoesntContain;
+var IsBefore = Ci.nsMsgSearchOp.IsBefore; // control entry not enabled
+
+var offlineMail = Ci.nsMsgSearchScope.offlineMail;
+var onlineMail = Ci.nsMsgSearchScope.onlineMail;
+var offlineMailFilter = Ci.nsMsgSearchScope.offlineMailFilter;
+var news = Ci.nsMsgSearchScope.news; // control entry not enabled
+
+var Body = Ci.nsMsgSearchAttrib.Body;
+
+var Files = [
+ "../../../data/base64-1",
+ "../../../data/basic1",
+ "../../../data/multipart-base64-2",
+ "../../../data/bug132340",
+ "../../../data/bad-charset.eml",
+ "../../../data/HTML-with-split-tag1.eml",
+ "../../../data/HTML-with-split-tag2.eml",
+
+ // Base64 encoded bodies.
+ "../../../data/01-plaintext.eml",
+ "../../../data/02-plaintext+attachment.eml",
+ "../../../data/03-HTML.eml",
+ "../../../data/04-HTML+attachment.eml",
+ "../../../data/05-HTML+embedded-image.eml",
+ "../../../data/06-plaintext+HMTL.eml",
+ "../../../data/07-plaintext+(HTML+embedded-image).eml",
+ "../../../data/08-plaintext+HTML+attachment.eml",
+ "../../../data/09-(HTML+embedded-image)+attachment.eml",
+ "../../../data/10-plaintext+(HTML+embedded-image)+attachment.eml",
+
+ // Bodies with non-ASCII characters in UTF-8 and other charsets.
+ "../../../data/11-plaintext.eml",
+ "../../../data/12-plaintext+attachment.eml", // using ISO-8859-7 (Greek)
+ "../../../data/13-HTML.eml",
+ "../../../data/14-HTML+attachment.eml",
+ "../../../data/15-HTML+embedded-image.eml",
+ "../../../data/16-plaintext+HMTL.eml", // text part is base64 encoded
+ "../../../data/17-plaintext+(HTML+embedded-image).eml", // HTML part is base64 encoded
+ "../../../data/18-plaintext+HTML+attachment.eml",
+ "../../../data/19-(HTML+embedded-image)+attachment.eml",
+ "../../../data/20-plaintext+(HTML+embedded-image)+attachment.eml", // using windows-1252
+
+ // Bodies with non-ASCII characters in UTF-8 and other charsets, all encoded with quoted printable.
+ "../../../data/21-plaintext.eml",
+ "../../../data/22-plaintext+attachment.eml", // using ISO-8859-7 (Greek)
+ "../../../data/23-HTML.eml",
+ "../../../data/24-HTML+attachment.eml",
+ "../../../data/25-HTML+embedded-image.eml",
+ "../../../data/26-plaintext+HMTL.eml", // text part is base64 encoded
+ "../../../data/27-plaintext+(HTML+embedded-image).eml", // HTML part is base64 encoded
+ "../../../data/28-plaintext+HTML+attachment.eml",
+ "../../../data/29-(HTML+embedded-image)+attachment.eml",
+ "../../../data/30-plaintext+(HTML+embedded-image)+attachment.eml", // using windows-1252
+
+ // Messages with message attachments, Content-Type: message/rfc822.
+ "../../../data/multipart-message-1.eml", // plaintext, has "bodyOfAttachedMessagePlain"
+ "../../../data/multipart-message-2.eml", // plaintext, base64, non-ASCII, has "bodyOfAttachedMessagePläin"
+ "../../../data/multipart-message-3.eml", // plaintext+HTML, non-ASCII in plaintext, has "bodyOfAttachedMessagePläin"
+ "../../../data/multipart-message-4.eml", // plaintext+HTML, non-ASCII in HTML, has "bodyOfAttachedMessägeHTML"
+
+ // Message using ISO-2022-JP and CTE: quoted-printable.
+ "../../../data/iso-2022-jp-qp.eml", // plaintext, has 日本 (Japan), we shouldn't find =1B$BF|K.
+
+ // Message using ISO-2022-JP and 7bit, but containing something that looks like quoted-printable.
+ // (bug 314637).
+ "../../../data/iso-2022-jp-not-qp.eml", // plaintext, has 現況 which contains =67.
+];
+var Tests = [
+ /* Translate Base64 messages */
+ // "World!" is contained in three messages, but in bug132340 it's not in a text
+ // part and should not be found.
+ { value: "World!", op: Contains, count: 2 },
+ /* Don't match the base64 text */
+ { value: "DQp", op: Contains, count: 0 },
+ /* Nested multipart/mixed, don't match */
+ { value: "PGh", op: Contains, count: 0 },
+ /* An encoded base-64 text/plain match */
+ { value: "base 64 text", op: Contains, count: 1 },
+
+ // From the message with the bad charset.
+ { value: "Mätterhorn", op: Contains, count: 1 },
+ { value: "Matterhörn", op: Contains, count: 1 },
+
+ // Comprehensive test of various MIME structures, messages 01 to 10.
+ // Messages 01 to 10 contain "huhu" once.
+ { value: "huhu", op: Contains, count: 10 },
+
+ // Messages 06, 07, 08, 10 contain "hihi" in the plaintext part.
+ { value: "hihi", op: Contains, count: 4 },
+
+ // The base64 of embedded images and attachments contains "iVBORw" and we don't
+ // want to find that.
+ { value: "iVBORw", op: Contains, count: 0 },
+
+ // The base64 of attachments contains "wMA005J0z" and we don't want to find that.
+ { value: "wMA005J0z", op: Contains, count: 0 },
+
+ // The base64 of the plaintext and HTML parts contains "U2VhcmNoIGZ"
+ // and we don't want to find that.
+ { value: "U2VhcmNoIGZ", op: Contains, count: 0 },
+
+ // Messages 11 and 13 to 20 contain "hühü" once.
+ { value: "hühü", op: Contains, count: 9 },
+ // Message 12 contains Καλησπέρα (good evening in Greek).
+ { value: "Καλησπέρα", op: Contains, count: 1 },
+
+ // Messages 16, 17, 18, 20 contain "hïhï" in the plaintext part.
+ { value: "hïhï", op: Contains, count: 4 },
+
+ // Messages 21 and 23 to 30 contain "höhö" once.
+ { value: "höhö", op: Contains, count: 9 },
+ // Message 22 contains Καλημέρα (good morning in Greek).
+ { value: "Καλημέρα", op: Contains, count: 1 },
+
+ // Messages 21, 23 and 24 contain "softbreak" broken by a soft line break.
+ { value: "softbreak", op: Contains, count: 3 },
+
+ // Messages 16, 17, 18, 20 contain "hähä" in the plaintext part.
+ { value: "hähä", op: Contains, count: 4 },
+
+ // The four messages with message/rfc822 attachment contain "bodyOfAttachedMessagePlain"
+ // or "bodyOfAttachedMessagePläin" in the plaintext part and "bodyOfAttachedMessageHTML"
+ // or "bodyOfAttachedMessägeHTML" in the HTML part.
+ { value: "bodyOfAttachedMessagePlain", op: Contains, count: 2 },
+ { value: "bodyOfAttachedMessagePläin", op: Contains, count: 2 },
+ { value: "bodyOfAttachedMessageHTML", op: Contains, count: 1 },
+ { value: "bodyOfAttachedMessägeHTML", op: Contains, count: 1 },
+
+ // Test that we don't find anything in HTML tags.
+ { value: "ShouldNotFindThis", op: Contains, count: 0 },
+ { value: "ShouldntFindThisEither", op: Contains, count: 0 },
+ { value: "ShouldntFindHref", op: Contains, count: 0 },
+ { value: "ShouldNotFindAcrossLines", op: Contains, count: 0 },
+ { value: "ShouldFindThisAgain", op: Contains, count: 2 },
+ { value: "ShouldFind AcrossLines", op: Contains, count: 2 },
+
+ // Test for ISO-2022-JP and CTE: quoted-printable, also 7bit looking like quoted-printable.
+ { value: "日本", op: Contains, count: 1 },
+ { value: "=1B$BF|K", op: Contains, count: 0 },
+ { value: "現況", op: Contains, count: 1 },
+];
+
+function fixFile(file) {
+ var fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(
+ Ci.nsIFileInputStream
+ );
+ fstream.init(file, -1, -1, Ci.nsIFileInputStream.CLOSE_ON_EOF);
+ var sstream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(
+ Ci.nsIScriptableInputStream
+ );
+ sstream.init(fstream);
+
+ var str = sstream.read(4096);
+ if (str.startsWith("From ")) {
+ sstream.close();
+ fstream.close();
+ return file;
+ }
+ var data = "From - Tue Oct 02 00:26:47 2007\r\n";
+ do {
+ data += str;
+ str = sstream.read(4096);
+ } while (str.length > 0);
+
+ sstream.close();
+ fstream.close();
+
+ let targetFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+ targetFile.initWithFile(do_get_profile());
+ targetFile.append(file.leafName);
+ let ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(
+ Ci.nsIFileOutputStream
+ );
+ ostream.init(targetFile, -1, -1, 0);
+ ostream.write(data, data.length);
+ ostream.close();
+ return targetFile;
+}
+
+var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {},
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ var fileName = Files.shift();
+ if (fileName) {
+ var file = fixFile(do_get_file(fileName));
+ MailServices.copy.copyFileMessage(
+ file,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+ } else {
+ testBodySearch();
+ }
+ },
+};
+
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+
+ // test that validity table terms are valid
+
+ // offline mail table
+ testValidityTable(offlineMail, Contains, Body, true);
+ testValidityTable(offlineMail, DoesntContain, Body, true);
+ testValidityTable(offlineMail, Is, Body, true);
+ testValidityTable(offlineMail, Isnt, Body, true);
+ testValidityTable(offlineMail, IsEmpty, Body, false);
+ testValidityTable(offlineMail, IsntEmpty, Body, false);
+ testValidityTable(offlineMail, IsBefore, Body, false);
+
+ // offline mail filter table
+ testValidityTable(offlineMailFilter, Contains, Body, true);
+ testValidityTable(offlineMailFilter, DoesntContain, Body, true);
+ testValidityTable(offlineMailFilter, Is, Body, true);
+ testValidityTable(offlineMailFilter, Isnt, Body, true);
+ testValidityTable(offlineMailFilter, IsEmpty, Body, false);
+ testValidityTable(offlineMailFilter, IsntEmpty, Body, false);
+ testValidityTable(offlineMailFilter, IsBefore, Body, false);
+
+ // online mail
+ testValidityTable(onlineMail, Contains, Body, true);
+ testValidityTable(onlineMail, DoesntContain, Body, true);
+ testValidityTable(onlineMail, Is, Body, false);
+ testValidityTable(onlineMail, Isnt, Body, false);
+ testValidityTable(onlineMail, IsEmpty, Body, false);
+ testValidityTable(onlineMail, IsntEmpty, Body, false);
+ testValidityTable(onlineMail, IsBefore, Body, false);
+
+ // online mail filter
+ /* testValidityTable(onlineMailFilter, Contains, Body, true);
+ testValidityTable(onlineMailFilter, DoesntContain, Body, true);
+ testValidityTable(onlineMailFilter, Is, Body, false);
+ testValidityTable(onlineMailFilter, Isnt, Body, false);
+ testValidityTable(onlineMailFilter, IsEmpty, Body, false);
+ testValidityTable(onlineMailFilter, IsntEmpty, Body, false);
+ testValidityTable(onlineMailFilter, IsBefore, Body, false);*/
+
+ // News does not support body tests
+ testValidityTable(news, Contains, Body, false);
+ testValidityTable(news, DoesntContain, Body, false);
+ testValidityTable(news, Is, Body, false);
+ testValidityTable(news, Isnt, Body, false);
+ testValidityTable(news, IsEmpty, Body, false);
+ testValidityTable(news, IsntEmpty, Body, false);
+ testValidityTable(news, IsBefore, Body, false);
+
+ do_test_pending();
+ copyListener.OnStopCopy(null);
+}
+
+// process each test from queue, calls itself upon completion of each search
+function testBodySearch() {
+ var test = Tests.shift();
+ if (test) {
+ new TestSearch(
+ localAccountUtils.inboxFolder,
+ test.value,
+ Body,
+ test.op,
+ test.count,
+ testBodySearch
+ );
+ } else {
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_searchBoolean.js b/comm/mailnews/search/test/unit/test_searchBoolean.js
new file mode 100644
index 0000000000..132acad4a3
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchBoolean.js
@@ -0,0 +1,239 @@
+/* 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/. */
+
+/*
+ * Demonstrates and tests the use of grouped boolean expressions in search terms
+ */
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var gSearchSession = Cc[
+ "@mozilla.org/messenger/searchSession;1"
+].createInstance(Ci.nsIMsgSearchSession);
+
+var gHdr; // the message header for the one mailbox message
+
+var Tests = [
+ {
+ A: false,
+ B: false,
+ C: false,
+ D: false,
+ matches: false,
+ },
+ {
+ A: false,
+ B: false,
+ C: false,
+ D: true,
+ matches: false,
+ },
+ {
+ A: false,
+ B: false,
+ C: true,
+ D: false,
+ matches: false,
+ },
+ {
+ A: false,
+ B: false,
+ C: true,
+ D: true,
+ matches: false,
+ },
+ {
+ A: false,
+ B: true,
+ C: false,
+ D: false,
+ matches: false,
+ },
+ {
+ A: false,
+ B: true,
+ C: false,
+ D: true,
+ matches: true,
+ },
+ {
+ A: false,
+ B: true,
+ C: true,
+ D: false,
+ matches: true,
+ },
+ {
+ A: false,
+ B: true,
+ C: true,
+ D: true,
+ matches: true,
+ },
+ {
+ A: true,
+ B: false,
+ C: false,
+ D: false,
+ matches: false,
+ },
+ {
+ A: true,
+ B: false,
+ C: false,
+ D: true,
+ matches: true,
+ },
+ {
+ A: true,
+ B: false,
+ C: true,
+ D: false,
+ matches: true,
+ },
+ {
+ A: true,
+ B: false,
+ C: true,
+ D: true,
+ matches: true,
+ },
+ {
+ A: true,
+ B: true,
+ C: false,
+ D: false,
+ matches: false,
+ },
+ {
+ A: true,
+ B: true,
+ C: false,
+ D: true,
+ matches: true,
+ },
+ {
+ A: true,
+ B: true,
+ C: true,
+ D: false,
+ matches: true,
+ },
+ {
+ A: true,
+ B: true,
+ C: true,
+ D: true,
+ matches: true,
+ },
+];
+
+var gHitCount = 0;
+var searchListener = {
+ onSearchHit(dbHdr, folder) {
+ gHitCount++;
+ },
+ onSearchDone(status) {
+ testSearch();
+ },
+ onNewSearch() {
+ gHitCount = 0;
+ },
+};
+
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+
+ /*
+ * I want to create and test a search term that uses this expression:
+ * (A || B ) && (C || D)
+ *
+ * The logical expressions A, B, C, and D will be represented by header
+ * string properties with values of T (true) or F (false).
+ *
+ */
+
+ // add a search term HdrProperty (some string) Is "T", with grouping
+ function addSearchTerm(aHdrProperty, aBeginGrouping, aEndGrouping, aBoolAnd) {
+ let searchTerm = gSearchSession.createTerm();
+ searchTerm.attrib = Ci.nsMsgSearchAttrib.HdrProperty;
+
+ let value = searchTerm.value;
+ // This is tricky - value.attrib must be set before actual values
+ value.attrib = Ci.nsMsgSearchAttrib.HdrProperty;
+ value.str = "T";
+ searchTerm.value = value;
+
+ searchTerm.op = Ci.nsMsgSearchOp.Is;
+ searchTerm.booleanAnd = aBoolAnd;
+ searchTerm.beginsGrouping = aBeginGrouping;
+ searchTerm.endsGrouping = aEndGrouping;
+ searchTerm.hdrProperty = aHdrProperty;
+ gSearchSession.appendTerm(searchTerm);
+ }
+
+ gSearchSession.addScopeTerm(
+ Ci.nsMsgSearchScope.offlineMail,
+ localAccountUtils.inboxFolder
+ );
+ gSearchSession.registerListener(searchListener);
+ // I tried using capital "A" but something makes it lower case internally, so it failed
+ addSearchTerm("a", true, false, true); // "(A"
+ addSearchTerm("b", false, true, false); // " || B)"
+ addSearchTerm("c", true, false, true); // " && (C"
+ addSearchTerm("d", false, true, false); // " || D)"
+
+ var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {
+ gHdr = localAccountUtils.inboxFolder.GetMessageHeader(aKey);
+ },
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ testSearch();
+ },
+ };
+
+ // Get a message into the local filestore. function testSearch() continues
+ // the testing after the copy.
+ var bugmail1 = do_get_file("../../../data/bugmail1");
+ do_test_pending();
+ MailServices.copy.copyFileMessage(
+ bugmail1,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+}
+
+var gTest = null;
+// process each test from queue, calls itself upon completion of each search
+function testSearch() {
+ // tests the previous search
+ if (gTest) {
+ Assert.equal(gHitCount, gTest.matches ? 1 : 0);
+ }
+ gTest = Tests.shift();
+ if (gTest) {
+ gHdr.setStringProperty("a", gTest.A ? "T" : "F");
+ gHdr.setStringProperty("b", gTest.B ? "T" : "F");
+ gHdr.setStringProperty("c", gTest.C ? "T" : "F");
+ gHdr.setStringProperty("d", gTest.D ? "T" : "F");
+ try {
+ gSearchSession.search(null);
+ } catch (e) {
+ dump(e);
+ }
+ } else {
+ gSearchSession.unregisterListener(searchListener);
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_searchChaining.js b/comm/mailnews/search/test/unit/test_searchChaining.js
new file mode 100644
index 0000000000..4bdbebab57
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchChaining.js
@@ -0,0 +1,90 @@
+/* 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/. */
+
+// Test of chaining of search scopes in a search session. In particular,
+// Bug 541969 made us not search an imap folder if the search scope before it
+// there was an empty local folder.
+
+// main test
+
+/* import-globals-from ../../../test/resources/MessageGenerator.jsm */
+load("../../../resources/MessageGenerator.jsm");
+
+var { IMAPPump, setupIMAPPump, teardownIMAPPump } = ChromeUtils.import(
+ "resource://testing-common/mailnews/IMAPpump.jsm"
+);
+var { ImapMessage } = ChromeUtils.import(
+ "resource://testing-common/mailnews/Imapd.jsm"
+);
+const { PromiseTestUtils } = ChromeUtils.import(
+ "resource://testing-common/mailnews/PromiseTestUtils.jsm"
+);
+
+async function setupFolder() {
+ // add a single message to the imap inbox.
+ let messages = [];
+ let messageGenerator = new MessageGenerator();
+ messages = messages.concat(messageGenerator.makeMessage());
+ let synthMessage = messages[0];
+
+ let msgURI = Services.io.newURI(
+ "data:text/plain;base64," + btoa(synthMessage.toMessageString())
+ );
+ let message = new ImapMessage(msgURI.spec, IMAPPump.mailbox.uidnext++, []);
+ IMAPPump.mailbox.addMessage(message);
+
+ // update folder to download header.
+ let listener = new PromiseTestUtils.PromiseUrlListener();
+ IMAPPump.inbox.updateFolderWithListener(null, listener);
+ await listener.promise;
+}
+
+async function searchTest() {
+ // Get the IMAP inbox...
+ var emptyLocal1 =
+ localAccountUtils.rootFolder.createLocalSubfolder("empty 1");
+
+ let searchSession = Cc[
+ "@mozilla.org/messenger/searchSession;1"
+ ].createInstance(Ci.nsIMsgSearchSession);
+
+ let searchTerm = searchSession.createTerm();
+ searchTerm.matchAll = true;
+ searchSession.appendTerm(searchTerm);
+ searchSession.addScopeTerm(Ci.nsMsgSearchScope.offlineMail, emptyLocal1);
+ searchSession.addScopeTerm(Ci.nsMsgSearchScope.onlineMail, IMAPPump.inbox);
+ let listener = new PromiseTestUtils.PromiseSearchNotify(
+ searchSession,
+ searchListener
+ );
+ searchSession.search(null);
+ await listener.promise;
+
+ // After the search completes, there still seem to be active URLs, so we
+ // have to wait before we are done and clear.
+ await PromiseTestUtils.promiseDelay(1000);
+}
+
+// nsIMsgSearchNotify implementation
+var searchListener = {
+ numTotalMessages: 0,
+ QueryInterface: ChromeUtils.generateQI(["nsIMsgSearchNotify"]),
+ onNewSearch() {
+ this.numTotalMessages = 0;
+ },
+ onSearchHit(dbHdr, folder) {
+ this.numTotalMessages++;
+ },
+ onSearchDone(status) {
+ Assert.equal(this.numTotalMessages, 1);
+ return true;
+ },
+};
+
+var tests = [setupIMAPPump, setupFolder, searchTest, teardownIMAPPump];
+
+function run_test() {
+ tests.forEach(x => add_task(x));
+ run_next_test();
+}
diff --git a/comm/mailnews/search/test/unit/test_searchCustomTerm.js b/comm/mailnews/search/test/unit/test_searchCustomTerm.js
new file mode 100644
index 0000000000..baea69767b
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchCustomTerm.js
@@ -0,0 +1,112 @@
+/* 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/. */
+
+/*
+ * Testing of custom search features.
+ *
+ */
+/* import-globals-from ../../../test/resources/searchTestUtils.js */
+load("../../../resources/searchTestUtils.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var kCustomId = "xpcomtest@mozilla.org#test";
+var gHdr;
+
+var Tests = [
+ {
+ setValue: "iamgood",
+ testValue: "iamnotgood",
+ op: Ci.nsMsgSearchOp.Is,
+ count: 0,
+ },
+ {
+ setValue: "iamgood",
+ testValue: "iamgood",
+ op: Ci.nsMsgSearchOp.Is,
+ count: 1,
+ },
+];
+
+// nsIMsgSearchCustomTerm object
+var customTerm = {
+ id: kCustomId,
+ name: "term name",
+ getEnabled(scope, op) {
+ return (
+ scope == Ci.nsMsgSearchScope.offlineMail && op == Ci.nsMsgSearchOp.Is
+ );
+ },
+ getAvailable(scope, op) {
+ return (
+ scope == Ci.nsMsgSearchScope.offlineMail && op == Ci.nsMsgSearchOp.Is
+ );
+ },
+ getAvailableOperators(scope) {
+ return [Ci.nsMsgSearchOp.Is];
+ },
+ match(msgHdr, searchValue, searchOp) {
+ switch (searchOp) {
+ case Ci.nsMsgSearchOp.Is:
+ if (msgHdr.getStringProperty("theTestProperty") == searchValue) {
+ return true;
+ }
+ }
+ return false;
+ },
+};
+
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+ MailServices.filters.addCustomTerm(customTerm);
+
+ var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {
+ gHdr = localAccountUtils.inboxFolder.GetMessageHeader(aKey);
+ },
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ doTest();
+ },
+ };
+
+ // Get a message into the local filestore.
+ // function testSearch() continues the testing after the copy.
+ let bugmail1 = do_get_file("../../../data/bugmail1");
+ do_test_pending();
+
+ MailServices.copy.copyFileMessage(
+ bugmail1,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+}
+
+function doTest() {
+ let test = Tests.shift();
+ if (test) {
+ gHdr.setStringProperty("theTestProperty", test.setValue);
+ new TestSearch(
+ localAccountUtils.inboxFolder,
+ test.testValue,
+ Ci.nsMsgSearchAttrib.Custom,
+ test.op,
+ test.count,
+ doTest,
+ kCustomId
+ );
+ } else {
+ gHdr = null;
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_searchJunk.js b/comm/mailnews/search/test/unit/test_searchJunk.js
new file mode 100644
index 0000000000..fdffd96165
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchJunk.js
@@ -0,0 +1,322 @@
+/* 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/. */
+
+// Testing of search by junk percent and junk score origin
+
+/* import-globals-from ../../../test/resources/searchTestUtils.js */
+load("../../../resources/searchTestUtils.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var IsGreaterThan = Ci.nsMsgSearchOp.IsGreaterThan;
+var IsLessThan = Ci.nsMsgSearchOp.IsLessThan;
+var Is = Ci.nsMsgSearchOp.Is;
+var Isnt = Ci.nsMsgSearchOp.Isnt;
+var IsEmpty = Ci.nsMsgSearchOp.IsEmpty;
+var IsntEmpty = Ci.nsMsgSearchOp.IsntEmpty;
+
+var offlineMail = Ci.nsMsgSearchScope.offlineMail;
+
+var JunkScoreOrigin = Ci.nsMsgSearchAttrib.JunkScoreOrigin;
+var JunkPercent = Ci.nsMsgSearchAttrib.JunkPercent;
+var JunkStatus = Ci.nsMsgSearchAttrib.JunkStatus;
+
+var fileName = "../../../data/bugmail1";
+
+/*
+ * The search for junkpercent is defined as the effective value,
+ * while the "junkpercent" database term is always the result
+ * from the bayes filter. This is optimized to make views that
+ * rely on junk percent search work with the best value for junk
+ * percent, while allowing junk percent from the bayes filter
+ * to be saved for analysis.
+ *
+ * This means that the search for "junk percent" only uses the
+ * database junkpercent value if junkscoreorigin is "plugin".
+ * Otherwise, it uses junkstatus (if set) or defaults to 0
+ * (not junk) if the message is unclassified.
+ */
+
+var Tests = [
+ {
+ // test empty junk status
+ junkScore: false,
+ testValue: 90,
+ attrib: JunkStatus,
+ op: IsEmpty,
+ count: 1,
+ },
+ {
+ junkScore: false,
+ testValue: 90,
+ attrib: JunkStatus,
+ op: IsntEmpty,
+ count: 0,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "10",
+ testValue: 90,
+ attrib: JunkStatus,
+ op: IsntEmpty,
+ count: 1,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "10",
+ testValue: 90,
+ attrib: JunkStatus,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ junkScore: "100",
+ junkScoreOrigin: "plugin",
+ junkPercent: "10",
+ testValue: 90,
+ attrib: JunkStatus,
+ op: IsntEmpty,
+ count: 1,
+ },
+ {
+ junkScore: "100",
+ junkScoreOrigin: "plugin",
+ junkPercent: "10",
+ testValue: 90,
+ attrib: JunkStatus,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ // Use junkpercent from database
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "10",
+ testValue: 90,
+ attrib: JunkPercent,
+ op: IsGreaterThan,
+ count: 0,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "10",
+ testValue: 90,
+ attrib: JunkPercent,
+ op: IsLessThan,
+ count: 1,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "10",
+ testValue: 90,
+ attrib: JunkPercent,
+ op: Is,
+ count: 0,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "90",
+ testValue: 10,
+ attrib: JunkPercent,
+ op: IsGreaterThan,
+ count: 1,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "90",
+ testValue: 10,
+ attrib: JunkPercent,
+ op: IsLessThan,
+ count: 0,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "10",
+ testValue: 10,
+ attrib: JunkPercent,
+ op: Is,
+ count: 1,
+ },
+ {
+ // values set by user, use junkscore not junkpercent
+ junkScore: "0",
+ junkScoreOrigin: "user",
+ junkPercent: "90",
+ testValue: 50,
+ attrib: JunkPercent,
+ op: IsGreaterThan,
+ count: 0,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "user",
+ junkPercent: "90",
+ testValue: 50,
+ attrib: JunkPercent,
+ op: IsLessThan,
+ count: 1,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "user",
+ junkPercent: "90",
+ testValue: 50,
+ attrib: JunkPercent,
+ op: Is,
+ count: 0,
+ },
+ {
+ junkScore: "100",
+ junkScoreOrigin: "user",
+ junkPercent: "10",
+ testValue: 50,
+ attrib: JunkPercent,
+ op: IsGreaterThan,
+ count: 1,
+ },
+ {
+ junkScore: "100",
+ junkScoreOrigin: "user",
+ junkPercent: "10",
+ testValue: 50,
+ attrib: JunkPercent,
+ op: IsLessThan,
+ count: 0,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "user",
+ junkPercent: "90",
+ testValue: 0,
+ attrib: JunkPercent,
+ op: Is,
+ count: 1,
+ },
+ {
+ // default to 0 when nothing set
+ junkScore: "",
+ junkScoreOrigin: "",
+ junkPercent: "",
+ testValue: 0,
+ attrib: JunkPercent,
+ op: Is,
+ count: 1,
+ },
+ {
+ // junkscoreorigin search tests
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "50",
+ testValue: "plugin",
+ attrib: JunkScoreOrigin,
+ op: Is,
+ count: 1,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "plugin",
+ junkPercent: "50",
+ testValue: "plugin",
+ attrib: JunkScoreOrigin,
+ op: Isnt,
+ count: 0,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "filter",
+ junkPercent: "50",
+ testValue: "plugin",
+ attrib: JunkScoreOrigin,
+ op: Is,
+ count: 0,
+ },
+ {
+ junkScore: "0",
+ junkScoreOrigin: "filter",
+ junkPercent: "50",
+ testValue: "plugin",
+ attrib: JunkScoreOrigin,
+ op: Isnt,
+ count: 1,
+ },
+];
+
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+
+ // test that validity table terms are valid
+
+ // offline mail table
+ testValidityTable(offlineMail, Is, JunkPercent, true);
+ testValidityTable(offlineMail, Isnt, JunkPercent, false);
+ testValidityTable(offlineMail, IsGreaterThan, JunkPercent, true);
+ testValidityTable(offlineMail, IsLessThan, JunkPercent, true);
+
+ testValidityTable(offlineMail, Is, JunkScoreOrigin, true);
+ testValidityTable(offlineMail, Isnt, JunkScoreOrigin, true);
+ testValidityTable(offlineMail, IsGreaterThan, JunkScoreOrigin, false);
+ testValidityTable(offlineMail, IsLessThan, JunkScoreOrigin, false);
+
+ // Get a message into the local filestore. function testJunkSearch() continues the testing after the copy.
+ do_test_pending();
+ var file = do_get_file(fileName);
+ MailServices.copy.copyFileMessage(
+ file,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+ return true;
+}
+
+var hdr;
+var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {
+ hdr = localAccountUtils.inboxFolder.GetMessageHeader(aKey);
+ },
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ testJunkSearch();
+ },
+};
+
+// Runs at completion of each copy
+// process each test from queue, calls itself upon completion of each search
+function testJunkSearch() {
+ var test = Tests.shift();
+ if (test) {
+ if (test.junkScore) {
+ hdr.setStringProperty("junkpercent", test.junkPercent);
+ hdr.setStringProperty("junkscoreorigin", test.junkScoreOrigin);
+ hdr.setStringProperty("junkscore", test.junkScore);
+ }
+
+ new TestSearch(
+ localAccountUtils.inboxFolder,
+ test.testValue,
+ test.attrib,
+ test.op,
+ test.count,
+ testJunkSearch
+ );
+ } else {
+ hdr = null;
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_searchLocalizationStrings.js b/comm/mailnews/search/test/unit/test_searchLocalizationStrings.js
new file mode 100644
index 0000000000..9de9b7eb0e
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchLocalizationStrings.js
@@ -0,0 +1,61 @@
+/* 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/. */
+
+// tests that localization strings added in bug 484147 are defined in preferences
+
+var gValidityManager = Cc[
+ "@mozilla.org/mail/search/validityManager;1"
+].getService(Ci.nsIMsgSearchValidityManager);
+
+var gStringBundle = Services.strings.createBundle(
+ "chrome://messenger/locale/search-attributes.properties"
+);
+
+// The following table of valid table scopes matches the allowable table
+// scopes in nsMsgSearchValidityManager::GetTable
+var kValidScopes = [
+ Ci.nsMsgSearchScope.offlineMail,
+ Ci.nsMsgSearchScope.offlineMailFilter,
+ Ci.nsMsgSearchScope.onlineMail,
+ Ci.nsMsgSearchScope.onlineMailFilter,
+ Ci.nsMsgSearchScope.news,
+ Ci.nsMsgSearchScope.newsFilter,
+ Ci.nsMsgSearchScope.localNews,
+ Ci.nsMsgSearchScope.LDAP,
+ Ci.nsMsgSearchScope.LDAPAnd,
+ Ci.nsMsgSearchScope.LocalAB,
+ Ci.nsMsgSearchScope.LocalABAnd,
+];
+
+function run_test() {
+ for (var index = 0; index < kValidScopes.length; ++index) {
+ let scope = kValidScopes[index];
+ let table = gValidityManager.getTable(scope);
+ let attributes = table.getAvailableAttributes();
+ let attribute;
+ while ((attribute = attributes.pop()) && attribute) {
+ let property = gValidityManager.getAttributeProperty(attribute);
+ let valid = false;
+ let localizedString;
+ try {
+ localizedString = gStringBundle.GetStringFromName(property);
+ valid = true;
+ } catch (e) {
+ dump("\n" + e);
+ }
+ valid = valid && localizedString && localizedString.length > 0;
+ if (!valid) {
+ dump(
+ "\nNo valid property for scope = " +
+ scope +
+ " attribute = " +
+ attribute +
+ " property = " +
+ property
+ );
+ }
+ Assert.ok(valid);
+ }
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_searchTag.js b/comm/mailnews/search/test/unit/test_searchTag.js
new file mode 100644
index 0000000000..321c22a6cf
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchTag.js
@@ -0,0 +1,490 @@
+/* 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/. */
+
+/*
+ * Testing of tag search features.
+ *
+ * Specifically tests changes implemented in bug 217034
+ * Does not do comprehensive testing.
+ *
+ */
+/* import-globals-from ../../../test/resources/searchTestUtils.js */
+load("../../../resources/searchTestUtils.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var Isnt = Ci.nsMsgSearchOp.Isnt;
+var Is = Ci.nsMsgSearchOp.Is;
+var IsEmpty = Ci.nsMsgSearchOp.IsEmpty;
+var IsntEmpty = Ci.nsMsgSearchOp.IsntEmpty;
+var Contains = Ci.nsMsgSearchOp.Contains;
+var DoesntContain = Ci.nsMsgSearchOp.DoesntContain;
+var IsBefore = Ci.nsMsgSearchOp.IsBefore; // control entry not enabled
+
+var offlineMail = Ci.nsMsgSearchScope.offlineMail;
+var onlineMail = Ci.nsMsgSearchScope.onlineMail;
+var offlineMailFilter = Ci.nsMsgSearchScope.offlineMailFilter;
+var onlineMailFilter = Ci.nsMsgSearchScope.onlineMailFilter;
+var news = Ci.nsMsgSearchScope.news; // control entry not enabled
+
+var Keywords = Ci.nsMsgSearchAttrib.Keywords;
+
+// test tags
+var Tag1 = "istag";
+var Tag2 = "notistag";
+var Tag3 = "istagnot";
+var Tag4 = "istagtoo";
+var Tag1Tag4 = Tag1 + " " + Tag4;
+var Tag1Tag3 = Tag1 + " " + Tag3;
+var Tag1Tag1 = Tag1 + " " + Tag1;
+
+var Tests = [
+ // Message has a single valid tag
+ // test the valid tag
+ {
+ msgTag: Tag1,
+ testTag: Tag1,
+ op: Is,
+ count: 1,
+ },
+ {
+ msgTag: Tag1,
+ testTag: Tag1,
+ op: Isnt,
+ count: 0,
+ },
+ {
+ msgTag: Tag1,
+ testTag: Tag1,
+ op: Contains,
+ count: 1,
+ },
+ {
+ msgTag: Tag1,
+ testTag: Tag1,
+ op: DoesntContain,
+ count: 0,
+ },
+ {
+ msgTag: Tag1,
+ testTag: Tag1,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ msgTag: Tag1,
+ testTag: Tag1,
+ op: IsntEmpty,
+ count: 1,
+ },
+ // test an invalid tag, should act like empty
+ {
+ msgTag: Tag2,
+ testTag: Tag1,
+ op: Contains,
+ count: 0,
+ },
+ {
+ msgTag: Tag2,
+ testTag: Tag1,
+ op: DoesntContain,
+ count: 1,
+ },
+ {
+ msgTag: Tag2,
+ testTag: Tag1,
+ op: Is,
+ count: 0,
+ },
+ {
+ msgTag: Tag2,
+ testTag: Tag1,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ msgTag: Tag2,
+ testTag: Tag1,
+ op: IsEmpty,
+ count: 1,
+ },
+ {
+ msgTag: Tag2,
+ testTag: Tag1,
+ op: IsntEmpty,
+ count: 0,
+ },
+ // Message has two valid tags
+ // test first tag
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag1,
+ op: Is,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag1,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag1,
+ op: Contains,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag1,
+ op: DoesntContain,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag1,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag1,
+ op: IsntEmpty,
+ count: 1,
+ },
+ // test second tag
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag4,
+ op: Is,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag4,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag4,
+ op: Contains,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag4,
+ op: DoesntContain,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag4,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag4,
+ op: IsntEmpty,
+ count: 1,
+ },
+ // test tag not in message
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag2,
+ op: Is,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag2,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag2,
+ op: Contains,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag2,
+ op: DoesntContain,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag2,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag4,
+ testTag: Tag2,
+ op: IsntEmpty,
+ count: 1,
+ },
+ // empty message
+ {
+ msgTag: "",
+ testTag: Tag2,
+ op: Is,
+ count: 0,
+ },
+ {
+ msgTag: "",
+ testTag: Tag2,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ msgTag: "",
+ testTag: Tag2,
+ op: Contains,
+ count: 0,
+ },
+ {
+ msgTag: "",
+ testTag: Tag2,
+ op: DoesntContain,
+ count: 1,
+ },
+ {
+ msgTag: "",
+ testTag: Tag2,
+ op: IsEmpty,
+ count: 1,
+ },
+ {
+ msgTag: "",
+ testTag: Tag2,
+ op: IsntEmpty,
+ count: 0,
+ },
+ // message with two tags, only one is valid
+ // test with the single valid tag
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag1,
+ op: Is,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag1,
+ op: Isnt,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag1,
+ op: Contains,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag1,
+ op: DoesntContain,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag1,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag1,
+ op: IsntEmpty,
+ count: 1,
+ },
+ // test with a tag not in the message
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag2,
+ op: Is,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag2,
+ op: Isnt,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag2,
+ op: Contains,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag2,
+ op: DoesntContain,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag2,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag3,
+ testTag: Tag2,
+ op: IsntEmpty,
+ count: 1,
+ },
+ // Message has a duplicated tag
+ // test the tag
+ {
+ msgTag: Tag1Tag1,
+ testTag: Tag1,
+ op: Is,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag1,
+ testTag: Tag1,
+ op: Isnt,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag1,
+ testTag: Tag1,
+ op: Contains,
+ count: 1,
+ },
+ {
+ msgTag: Tag1Tag1,
+ testTag: Tag1,
+ op: DoesntContain,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag1,
+ testTag: Tag1,
+ op: IsEmpty,
+ count: 0,
+ },
+ {
+ msgTag: Tag1Tag1,
+ testTag: Tag1,
+ op: IsntEmpty,
+ count: 1,
+ },
+];
+
+var hdr;
+
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+
+ // test that validity table terms are valid
+
+ // offline mail table
+ testValidityTable(offlineMail, Contains, Keywords, true);
+ testValidityTable(offlineMail, DoesntContain, Keywords, true);
+ testValidityTable(offlineMail, Is, Keywords, true);
+ testValidityTable(offlineMail, Isnt, Keywords, true);
+ testValidityTable(offlineMail, IsEmpty, Keywords, true);
+ testValidityTable(offlineMail, IsntEmpty, Keywords, true);
+ testValidityTable(offlineMail, IsBefore, Keywords, false);
+
+ // offline mail filter table
+ testValidityTable(offlineMailFilter, Contains, Keywords, true);
+ testValidityTable(offlineMailFilter, DoesntContain, Keywords, true);
+ testValidityTable(offlineMailFilter, Is, Keywords, true);
+ testValidityTable(offlineMailFilter, Isnt, Keywords, true);
+ testValidityTable(offlineMailFilter, IsEmpty, Keywords, true);
+ testValidityTable(offlineMailFilter, IsntEmpty, Keywords, true);
+ testValidityTable(offlineMailFilter, IsBefore, Keywords, false);
+
+ // online mail
+ testValidityTable(onlineMail, Contains, Keywords, true);
+ testValidityTable(onlineMail, DoesntContain, Keywords, true);
+ testValidityTable(onlineMail, Is, Keywords, false);
+ testValidityTable(onlineMail, Isnt, Keywords, false);
+ testValidityTable(onlineMail, IsEmpty, Keywords, false);
+ testValidityTable(onlineMail, IsntEmpty, Keywords, false);
+ testValidityTable(onlineMail, IsBefore, Keywords, false);
+
+ // online mail filter
+ testValidityTable(onlineMailFilter, Contains, Keywords, true);
+ testValidityTable(onlineMailFilter, DoesntContain, Keywords, true);
+ testValidityTable(onlineMailFilter, Is, Keywords, true);
+ testValidityTable(onlineMailFilter, Isnt, Keywords, true);
+ testValidityTable(onlineMailFilter, IsEmpty, Keywords, true);
+ testValidityTable(onlineMailFilter, IsntEmpty, Keywords, true);
+ testValidityTable(onlineMailFilter, IsBefore, Keywords, false);
+
+ // news
+ testValidityTable(news, Contains, Keywords, false);
+ testValidityTable(news, DoesntContain, Keywords, false);
+ testValidityTable(news, Is, Keywords, false);
+ testValidityTable(news, Isnt, Keywords, false);
+ testValidityTable(news, IsEmpty, Keywords, false);
+ testValidityTable(news, IsntEmpty, Keywords, false);
+ testValidityTable(news, IsBefore, Keywords, false);
+
+ // delete any existing tags
+ let tagArray = MailServices.tags.getAllTags();
+ for (var i = 0; i < tagArray.length; i++) {
+ MailServices.tags.deleteKey(tagArray[i].key);
+ }
+
+ // add as valid tags Tag1 and Tag4
+ MailServices.tags.addTagForKey(Tag1, Tag1, null, null);
+ MailServices.tags.addTagForKey(Tag4, Tag4, null, null);
+
+ var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {
+ hdr = localAccountUtils.inboxFolder.GetMessageHeader(aKey);
+ },
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ testKeywordSearch();
+ },
+ };
+
+ // Get a message into the local filestore. function testKeywordSearch() continues the testing after the copy.
+ var bugmail1 = do_get_file("../../../data/bugmail1");
+ do_test_pending();
+ MailServices.copy.copyFileMessage(
+ bugmail1,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+}
+
+// process each test from queue, calls itself upon completion of each search
+function testKeywordSearch() {
+ var test = Tests.shift();
+ if (test) {
+ hdr.setStringProperty("keywords", test.msgTag);
+ new TestSearch(
+ localAccountUtils.inboxFolder,
+ test.testTag,
+ Ci.nsMsgSearchAttrib.Keywords,
+ test.op,
+ test.count,
+ testKeywordSearch
+ );
+ } else {
+ hdr = null;
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/test_searchUint32HdrProperty.js b/comm/mailnews/search/test/unit/test_searchUint32HdrProperty.js
new file mode 100644
index 0000000000..e31f4db7d2
--- /dev/null
+++ b/comm/mailnews/search/test/unit/test_searchUint32HdrProperty.js
@@ -0,0 +1,141 @@
+/* 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/. */
+
+/*
+ * Testing of Uint32HdrProperty search attribute. Adapted from test_search.js
+ */
+
+/* import-globals-from ../../../test/resources/searchTestUtils.js */
+load("../../../resources/searchTestUtils.js");
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+
+var Isnt = Ci.nsMsgSearchOp.Isnt;
+var Is = Ci.nsMsgSearchOp.Is;
+var IsGreaterThan = Ci.nsMsgSearchOp.IsGreaterThan;
+var IsLessThan = Ci.nsMsgSearchOp.IsLessThan;
+
+var Tests = [
+ // test a property that does not exist
+ {
+ hdrProperty: "idonotexist",
+ op: Is,
+ value: 1,
+ count: 0,
+ },
+ {
+ hdrProperty: "idonotexist",
+ op: Isnt,
+ value: 1,
+ count: 1,
+ },
+ // add a property and test its value
+ {
+ setup: function setupProperty() {
+ for (let msgHdr of localAccountUtils.inboxFolder.msgDatabase.enumerateMessages()) {
+ msgHdr.setUint32Property("iam23", 23);
+ }
+ },
+ hdrProperty: "iam23",
+ op: Is,
+ value: 23,
+ count: 1,
+ },
+ {
+ hdrProperty: "iam23",
+ op: Isnt,
+ value: 23,
+ count: 0,
+ },
+ {
+ hdrProperty: "iam23",
+ op: Is,
+ value: 17,
+ count: 0,
+ },
+ {
+ hdrProperty: "iam23",
+ op: Isnt,
+ value: 17,
+ count: 1,
+ },
+ {
+ hdrProperty: "iam23",
+ op: IsGreaterThan,
+ value: 25,
+ count: 0,
+ },
+ {
+ hdrProperty: "iam23",
+ op: IsLessThan,
+ value: 25,
+ count: 1,
+ },
+ {
+ hdrProperty: "iam23",
+ op: IsGreaterThan,
+ value: 17,
+ count: 1,
+ },
+ {
+ hdrProperty: "iam23",
+ op: IsLessThan,
+ value: 17,
+ count: 0,
+ },
+];
+
+function run_test() {
+ localAccountUtils.loadLocalMailAccount();
+
+ var copyListener = {
+ OnStartCopy() {},
+ OnProgress(aProgress, aProgressMax) {},
+ SetMessageKey(aKey) {},
+ SetMessageId(aMessageId) {},
+ OnStopCopy(aStatus) {
+ testSearch();
+ },
+ };
+
+ // Get a message into the local filestore. function testSearch() continues
+ // the testing after the copy.
+ var bugmail1 = do_get_file("../../../data/bugmail1");
+ do_test_pending();
+ MailServices.copy.copyFileMessage(
+ bugmail1,
+ localAccountUtils.inboxFolder,
+ null,
+ false,
+ 0,
+ "",
+ copyListener,
+ null
+ );
+}
+
+// process each test from queue, calls itself upon completion of each search
+function testSearch() {
+ var test = Tests.shift();
+ if (test) {
+ if (test.setup) {
+ test.setup();
+ }
+ new TestSearch(
+ localAccountUtils.inboxFolder,
+ test.value,
+ Ci.nsMsgSearchAttrib.Uint32HdrProperty,
+ test.op,
+ test.count,
+ testSearch,
+ null,
+ null,
+ test.hdrProperty
+ );
+ } else {
+ do_test_finished();
+ }
+}
diff --git a/comm/mailnews/search/test/unit/xpcshell.ini b/comm/mailnews/search/test/unit/xpcshell.ini
new file mode 100644
index 0000000000..3157b90aea
--- /dev/null
+++ b/comm/mailnews/search/test/unit/xpcshell.ini
@@ -0,0 +1,20 @@
+[DEFAULT]
+head = head_mailbase.js
+tail =
+
+[test_base64_decoding.js]
+[test_bug366491.js]
+[test_bug404489.js]
+[test_copyThenMoveManual.js]
+[test_junkWhitelisting.js]
+[test_quarantineFilterMove.js]
+[test_search.js]
+[test_searchAddressInAb.js]
+[test_searchBody.js]
+[test_searchBoolean.js]
+[test_searchChaining.js]
+[test_searchCustomTerm.js]
+[test_searchJunk.js]
+[test_searchLocalizationStrings.js]
+[test_searchTag.js]
+[test_searchUint32HdrProperty.js]