Bug 1531317 - Message search WebExtension API - tests. r=mkmelin
authorGeoff Lankow <geoff@darktrojan.net>
Mon, 24 Jun 2019 10:57:37 +0200
changeset 35934 450a66aeeaa8bd80ee95808f2e4d1a274c7bcb14
parent 35933 14390389783d5a46cca22ceafa2ae777028159fa
child 35935 384e0fef96b79b5379fb97e9a953c0b3f2bf50e1
push id392
push userclokep@gmail.com
push dateMon, 02 Sep 2019 20:17:19 +0000
reviewersmkmelin
bugs1531317
Bug 1531317 - Message search WebExtension API - tests. r=mkmelin
mail/components/extensions/test/xpcshell/head.js
mail/components/extensions/test/xpcshell/test_ext_messages_query.js
mail/components/extensions/test/xpcshell/xpcshell.ini
--- a/mail/components/extensions/test/xpcshell/head.js
+++ b/mail/components/extensions/test/xpcshell/head.js
@@ -27,17 +27,28 @@ function cleanUpAccount(account) {
   info(`Cleaning up account ${account.toString()}`);
   MailServices.accounts.removeAccount(account, true);
 }
 
 registerCleanupFunction(() => {
   [...MailServices.accounts.accounts.enumerate()].forEach(cleanUpAccount);
 });
 
+function addIdentity(account, email = "xpcshell@localhost") {
+  let identity = MailServices.accounts.createIdentity();
+  identity.email = email;
+  account.addIdentity(identity);
+  if (!account.defaultIdentity) {
+    account.defaultIdentity = identity;
+  }
+  info(`Created identity ${identity.toString()}`);
+}
+
 function createMessages(folder, count) {
   const {
     MessageGenerator,
   } = ChromeUtils.import("resource://testing-common/mailnews/messageGenerator.js");
-  let messages = new MessageGenerator().makeMessages({ count });
+  let messages = new MessageGenerator().makeMessages({ count, age_incr: { days: 2 } });
   let messageStrings = messages.map(message => message.toMboxString());
   folder.QueryInterface(Ci.nsIMsgLocalMailFolder);
   folder.addMessageBatch(messageStrings.length, messageStrings);
+  folder.callFilterPlugins(null);
 }
new file mode 100644
--- /dev/null
+++ b/mail/components/extensions/test/xpcshell/test_ext_messages_query.js
@@ -0,0 +1,144 @@
+/* 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/. */
+
+"use strict";
+
+var {ExtensionTestUtils} = ChromeUtils.import("resource://testing-common/ExtensionXPCShellUtils.jsm");
+ExtensionTestUtils.init(this);
+
+var {Gloda} = ChromeUtils.import("resource:///modules/gloda/public.js");
+var {GlodaIndexer} = ChromeUtils.import("resource:///modules/gloda/indexer.js");
+
+// Create some folders and populate them.
+let account, rootFolder;
+let subFolders = {};
+add_task(async function setup() {
+  GlodaIndexer._INDEX_INTERVAL = 0;
+
+  account = createAccount();
+  rootFolder = account.incomingServer.rootFolder;
+  rootFolder.createSubfolder("test1", null);
+  rootFolder.createSubfolder("test2", null);
+  for (let folder of rootFolder.subFolders) {
+    subFolders[folder.name] = folder;
+  }
+  createMessages(subFolders.test1, 9);
+  createMessages(subFolders.test2, 9);
+
+  let messages = [...subFolders.test1.messages];
+  // NB: Here, the messages are zero-indexed. In the test they're one-indexed.
+  messages[1].markFlagged(true);
+  messages[6].markFlagged(true);
+
+  addIdentity(account, messages[5].author.replace(/.*<(.*)>/, "$1"));
+  addIdentity(account, messages[2].recipients.replace(/.*<(.*)>/, "$1"));
+  Gloda._initMyIdentities();
+
+  // Wait for Gloda to re-index the added messages.
+  await new Promise(resolve => {
+    let waiting = false;
+    GlodaIndexer.addListener(function indexListener(status) {
+      if (status == Gloda.kIndexerIdle && !GlodaIndexer.indexing && waiting) {
+        GlodaIndexer.removeListener(indexListener);
+        resolve();
+      }
+    });
+    waiting = true;
+  });
+
+  registerCleanupFunction(() => GlodaIndexer._shutdown());
+});
+
+add_task(async function() {
+  let extension = ExtensionTestUtils.loadExtension({
+    background: async () => {
+      let [accountId] = await new Promise(resolve => {
+        browser.test.onMessage.addListener(function listener(...args) {
+          browser.test.onMessage.removeListener(listener);
+          resolve(args);
+        });
+      });
+
+      // Check all messages are returned.
+      let {messages} = await browser.messages.query({});
+      browser.test.assertEq(18, messages.length);
+
+      let folder = { accountId, path: "/test1" };
+
+      // Query messages from test1. No messages from test2 should be returned.
+      // We'll use these messages as a reference for further tests.
+      let {messages: referenceMessages} = await browser.messages.query({folder});
+      browser.test.assertEq(9, referenceMessages.length);
+      browser.test.assertTrue(referenceMessages.every(m => m.folder.path == "/test1"));
+
+      // Dump the reference messages to the console for easier debugging.
+      browser.test.log("Reference messages:");
+      for (let m of referenceMessages) {
+        let date = m.date.toISOString().substring(0, 10);
+        let author = m.author.replace(/"(.*)".*/, "$1").padEnd(16, " ");
+        let recipients = m.recipients[0].replace(/(.*) <.*>/, "$1").padEnd(16, " ");
+        browser.test.log(`[${m.id}] ${date} From: ${author} To: ${recipients} Subject: ${m.subject}`);
+      }
+
+      let subtest = async function(queryInfo, ...expectedMessageIndices) {
+        browser.test.log("Testing " + JSON.stringify(queryInfo));
+        queryInfo.folder = folder;
+        let {messages: actualMessages} = await browser.messages.query(queryInfo);
+
+        browser.test.assertEq(expectedMessageIndices.length, actualMessages.length, "Correct number of messages");
+        for (let index of expectedMessageIndices) {
+          // browser.test.log(`Looking for message ${index}`);
+          if (!actualMessages.some(am => am.id == index)) {
+            browser.test.fail(`Message ${index} was not returned`);
+            browser.test.log("These messages were returned: " + actualMessages.map(am => am.id));
+          }
+        }
+      };
+
+      // Date range query. The messages are 0 days old, 2 days old, 4 days old, etc..
+      let today = new Date();
+      let date1 = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 5);
+      let date2 = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 11);
+      await subtest({ fromDate: today });
+      await subtest({ fromDate: date1 }, 1, 2, 3);
+      await subtest({ fromDate: date2 }, 1, 2, 3, 4, 5, 6);
+      await subtest({ toDate: date1 }, 4, 5, 6, 7, 8, 9);
+      await subtest({ toDate: date2 }, 7, 8, 9);
+      await subtest({ fromDate: date1, toDate: date2 });
+      await subtest({ fromDate: date2, toDate: date1 }, 4, 5, 6);
+
+      // Flagged query. Messages 2 and 7 are flagged.
+      await subtest({ flagged: true }, 2, 7);
+      await subtest({ flagged: false }, 1, 3, 4, 5, 6, 8, 9);
+
+      // Subject query.
+      let keyword = referenceMessages[1].subject.split(" ")[1];
+      await subtest({ subject: keyword }, 2);
+      await subtest({ fullText: keyword }, 2);
+
+      // Author query.
+      keyword = referenceMessages[2].author.replace("\"", "").split(" ")[0];
+      await subtest({ author: keyword }, 3);
+      await subtest({ fullText: keyword }, 3);
+
+      // Recipients query.
+      keyword = referenceMessages[7].recipients[0].split(" ")[0];
+      await subtest({ recipients: keyword }, 8);
+      await subtest({ fullText: keyword }, 8);
+      await subtest({ body: keyword }, 8);
+
+      // From Me and To Me. These use the identities added to account.
+      await subtest({ fromMe: true }, 6);
+      await subtest({ toMe: true }, 3);
+
+      browser.test.notifyPass("finished");
+    },
+    manifest: { permissions: ["accountsRead", "messagesRead"] },
+  });
+
+  await extension.startup();
+  extension.sendMessage(account.key);
+  await extension.awaitFinish("finished");
+  await extension.unload();
+});
--- a/mail/components/extensions/test/xpcshell/xpcshell.ini
+++ b/mail/components/extensions/test/xpcshell/xpcshell.ini
@@ -4,8 +4,9 @@ tags = webextensions
 
 [test_ext_accounts.js]
 [test_ext_addressBook.js]
 [test_ext_cloudFile.js]
 support-files = data/cloudFile1.txt data/cloudFile2.txt
 [test_ext_experiments.js]
 [test_ext_folders.js]
 [test_ext_messages.js]
+[test_ext_messages_query.js]