summaryrefslogtreecommitdiffstats
path: root/comm/mailnews/db/gloda/test/unit/base_index_junk.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/mailnews/db/gloda/test/unit/base_index_junk.js')
-rw-r--r--comm/mailnews/db/gloda/test/unit/base_index_junk.js217
1 files changed, 217 insertions, 0 deletions
diff --git a/comm/mailnews/db/gloda/test/unit/base_index_junk.js b/comm/mailnews/db/gloda/test/unit/base_index_junk.js
new file mode 100644
index 0000000000..8529f24a56
--- /dev/null
+++ b/comm/mailnews/db/gloda/test/unit/base_index_junk.js
@@ -0,0 +1,217 @@
+/* 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 indexing in the face of junk classification and junk folders. It is
+ * gloda policy not to index junk mail.
+ *
+ * A similar test that moving things to the trash folder is deletion happens in
+ * base_index_messages.js.
+ */
+
+var { MailServices } = ChromeUtils.import(
+ "resource:///modules/MailServices.jsm"
+);
+var { Gloda } = ChromeUtils.import("resource:///modules/gloda/GlodaPublic.jsm");
+var { GlodaConstants } = ChromeUtils.import(
+ "resource:///modules/gloda/GlodaConstants.jsm"
+);
+var { GlodaMsgIndexer } = ChromeUtils.import(
+ "resource:///modules/gloda/IndexMsg.jsm"
+);
+var { queryExpect } = ChromeUtils.import(
+ "resource://testing-common/gloda/GlodaQueryHelper.jsm"
+);
+var { assertExpectedMessagesIndexed, waitForGlodaIndexer } = ChromeUtils.import(
+ "resource://testing-common/gloda/GlodaTestHelper.jsm"
+);
+var { MessageInjection } = ChromeUtils.import(
+ "resource://testing-common/mailnews/MessageInjection.jsm"
+);
+
+var messageInjection;
+
+const SPAM_BODY = { body: "superspam superspam superspam eevil eevil eevil" };
+const HAM_BODY = { body: "ham ham ham nice nice nice happy happy happy" };
+
+/**
+ * Make SPAM_BODY be known as spammy and HAM_BODY be known as hammy.
+ */
+async function setup_spam_filter() {
+ let [, spamSet, hamSet] = await messageInjection.makeFoldersWithSets(1, [
+ { count: 1, body: SPAM_BODY },
+ { count: 1, body: HAM_BODY },
+ ]);
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([spamSet, hamSet], []));
+ let promiseResolve;
+ let promise = new Promise(resolve => {
+ promiseResolve = resolve;
+ });
+ let junkListener = {
+ onMessageClassified() {
+ promiseResolve();
+ },
+ };
+
+ // Ham.
+ dump(`Marking message: ${hamSet.getMsgHdr(0)} as ham.`);
+ MailServices.junk.setMessageClassification(
+ hamSet.getMsgURI(0),
+ null, // no old classification
+ MailServices.junk.GOOD,
+ null,
+ junkListener
+ );
+ await promise;
+
+ // Reset promise for junkListener.
+ promise = new Promise(resolve => {
+ promiseResolve = resolve;
+ });
+
+ // Spam.
+ dump(`Marking message: ${spamSet.getMsgHdr(0)} as spam.`);
+ MailServices.junk.setMessageClassification(
+ spamSet.getMsgURI(0),
+ null, // No old classification.
+ MailServices.junk.JUNK,
+ null,
+ junkListener
+ );
+ await promise;
+}
+
+/**
+ * Because gloda defers indexing until after junk, we should never index a
+ * message that gets marked as junk. So if we inject a message that will
+ * definitely be marked as junk (thanks to use of terms that guarantee it),
+ * the indexer should never index it.
+ *
+ * ONLY THIS TEST ACTUALLY RELIES ON THE BAYESIAN CLASSIFIER.
+ */
+async function test_never_indexes_a_message_marked_as_junk() {
+ // Event-driven does not index junk.
+
+ // Make a message that will be marked as junk from the get-go.
+ await messageInjection.makeFoldersWithSets(1, [
+ { count: 1, body: SPAM_BODY },
+ ]);
+ // Since the message is junk, gloda should not index it!
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([]));
+
+ // Folder sweep does not index junk.
+ GlodaMsgIndexer.indexingSweepNeeded = true;
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([]));
+}
+
+/**
+ * Reset the training data so the bayesian classifier stops doing things.
+ */
+function reset_spam_filter() {
+ MailServices.junk.resetTrainingData();
+}
+
+/**
+ * Marking a message as junk is equivalent to deleting the message, un-mark it
+ * and it should go back to being a happy message (with the same gloda-id!).
+ *
+ * THIS TEST DOES NOT RELY ON THE BAYESIAN CLASSIFIER.
+ */
+
+async function test_mark_as_junk_is_deletion_mark_as_not_junk_is_exposure() {
+ // Mark as junk is deletion.
+ // Create a message; it should get indexed.
+ let [, msgSet] = await messageInjection.makeFoldersWithSets(1, [
+ { count: 1 },
+ ]);
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([msgSet], { augment: true }));
+ let glodaId = msgSet.glodaMessages[0].id;
+ // Mark it as junk.
+ msgSet.setJunk(true);
+ // It will appear deleted after the event.
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([], { deleted: [msgSet] }));
+ // Mark as non-junk gets indexed.
+ msgSet.setJunk(false);
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([msgSet], { augment: true }));
+ // We should have reused the existing gloda message so it should keep the id.
+ Assert.equal(glodaId, msgSet.glodaMessages[0].id);
+}
+
+/**
+ * Moving a message to the junk folder is equivalent to deletion. Gloda does
+ * not index junk folders at all, which is why this is an important and
+ * independent determination from marking a message directly as junk.
+ *
+ * The move to the junk folder is performed without using any explicit junk
+ * support code. This ends up being effectively the same underlying logic test
+ * as base_index_messages' test of moving a message to the trash folder.
+ */
+async function test_message_moving_to_junk_folder_is_deletion() {
+ // Create and index two messages in a conversation.
+ let [, msgSet] = await messageInjection.makeFoldersWithSets(1, [
+ { count: 2, msgsPerThread: 2 },
+ ]);
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([msgSet], { augment: true }));
+
+ let convId = msgSet.glodaMessages[0].conversation.id;
+ let firstGlodaId = msgSet.glodaMessages[0].id;
+ let secondGlodaId = msgSet.glodaMessages[1].id;
+
+ // Move them to the junk folder.
+ await messageInjection.moveMessages(
+ msgSet,
+ await messageInjection.getJunkFolder()
+ );
+
+ // They will appear deleted after the events.
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([], { deleted: [msgSet] }));
+
+ // We do not index the junk folder so this should actually make them appear
+ // deleted to an unprivileged query.
+ let msgQuery = Gloda.newQuery(GlodaConstants.NOUN_MESSAGE);
+ msgQuery.id(firstGlodaId, secondGlodaId);
+ await queryExpect(msgQuery, []);
+
+ // Force a sweep.
+ GlodaMsgIndexer.indexingSweepNeeded = true;
+ // There should be no apparent change as the result of this pass.
+ // (Well, the conversation will die, but we can't see that.)
+ await waitForGlodaIndexer();
+ Assert.ok(...assertExpectedMessagesIndexed([]));
+
+ // The conversation should be gone.
+ let convQuery = Gloda.newQuery(GlodaConstants.NOUN_CONVERSATION);
+ convQuery.id(convId);
+ await queryExpect(convQuery, []);
+
+ // The messages should be entirely gone.
+ let msgPrivQuery = Gloda.newQuery(GlodaConstants.NOUN_MESSAGE, {
+ noDbQueryValidityConstraints: true,
+ });
+ msgPrivQuery.id(firstGlodaId, secondGlodaId);
+ await queryExpect(msgPrivQuery, []);
+}
+
+function test_sanity_test_environment() {
+ Assert.ok(messageInjection, "Sanity that messageInjection is set.");
+ Assert.ok(messageInjection.messageGenerator, "Sanity that msgGen is set.");
+}
+
+/* exported tests */
+var base_index_junk_tests = [
+ test_sanity_test_environment,
+ setup_spam_filter,
+ test_never_indexes_a_message_marked_as_junk,
+ reset_spam_filter,
+ test_mark_as_junk_is_deletion_mark_as_not_junk_is_exposure,
+ test_message_moving_to_junk_folder_is_deletion,
+];