diff options
Diffstat (limited to '')
-rw-r--r-- | comm/mailnews/db/gloda/test/unit/base_index_junk.js | 217 |
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, +]; |