You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by ma...@apache.org on 2016/07/26 07:46:41 UTC

[02/17] james-project git commit: JAMES-1804 Index text attribute Append of: from, to, cc, bcc, subjects, body

JAMES-1804 Index text attribute
Append of: from, to, cc, bcc, subjects, body


Project: http://git-wip-us.apache.org/repos/asf/james-project/repo
Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/c321b93c
Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/c321b93c
Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/c321b93c

Branch: refs/heads/master
Commit: c321b93cde4ec1afa344770acef46810aa8ffead
Parents: 9470ccf
Author: Antoine Duprat <ad...@linagora.com>
Authored: Wed Jul 20 10:53:46 2016 +0200
Committer: Antoine Duprat <ad...@linagora.com>
Committed: Tue Jul 26 08:57:04 2016 +0200

----------------------------------------------------------------------
 .../apache/james/mailbox/model/SearchQuery.java |  23 +++
 mailbox/elasticsearch/pom.xml                   |   5 +
 .../elasticsearch/NodeMappingFactory.java       |  11 ++
 .../elasticsearch/json/IndexableMessage.java    |  20 ++
 .../json/JsonMessageConstants.java              |   1 +
 .../elasticsearch/query/CriterionConverter.java |   3 +
 .../json/IndexableMessageTest.java              | 185 +++++++++++++++++++
 .../src/test/resources/eml/mailWithHeaders.eml  |  14 ++
 .../search/AbstractMessageSearchIndexTest.java  |  66 +++++++
 .../store/src/test/resources/eml/htmlMail.json  |   3 +-
 mailbox/store/src/test/resources/eml/mail.json  |   3 +-
 .../src/test/resources/eml/nonTextual.json      |   3 +-
 .../src/test/resources/eml/pgpSignedMail.json   |   3 +-
 .../src/test/resources/eml/recursiveMail.json   |   3 +-
 .../store/src/test/resources/eml/spamMail.json  |   3 +-
 15 files changed, 340 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java
----------------------------------------------------------------------
diff --git a/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java b/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java
index d815d9d..8a62315 100644
--- a/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java
+++ b/mailbox/api/src/main/java/org/apache/james/mailbox/model/SearchQuery.java
@@ -30,6 +30,8 @@ import java.util.Set;
 import javax.mail.Flags;
 import javax.mail.Flags.Flag;
 
+import org.apache.james.mailbox.model.SearchQuery.Sort;
+
 /**
  * <p>
  * Models a query used to search for messages. A query is the logical
@@ -428,6 +430,22 @@ public class SearchQuery implements Serializable {
     }
 
     /**
+     * Creates a filter matching messages which contains the given text either
+     * within the headers (From, To, Cc, Bcc & Subject) and text / html bodies. 
+     * Implementations may choose to ignore mime parts which cannot be decoded to text.
+     * 
+     * All to-compared Strings MUST BE converted to uppercase before doing so
+     * (this also include the search value)
+     * 
+     * @param value
+     *            search value
+     * @return <code>Criterion</code>, not null
+     */
+    public static final Criterion textContains(String value) {
+        return new TextCriterion(value, Scope.TEXT);
+    }
+
+    /**
      * Creates a filter matching messages which contains the given text within
      * the body. Implementations may choose to ignore mime parts which cannot be
      * decoded to text.
@@ -950,6 +968,11 @@ public class SearchQuery implements Serializable {
         /** Only message body content */
         BODY,
 
+        /** Headers: From, To, Cc, Bcc & Subjects
+         *  plus text/plain & text/html part
+         */
+        TEXT,
+
         /** Full message content including headers */
         FULL
     }

http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/elasticsearch/pom.xml
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/pom.xml b/mailbox/elasticsearch/pom.xml
index 59df4ee..5e43f4f 100644
--- a/mailbox/elasticsearch/pom.xml
+++ b/mailbox/elasticsearch/pom.xml
@@ -259,6 +259,11 @@
                     <type>test-jar</type>
                 </dependency>
                 <dependency>
+                    <groupId>org.mockito</groupId>
+                    <artifactId>mockito-core</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
                     <groupId>org.slf4j</groupId>
                     <artifactId>slf4j-api</artifactId>
                 </dependency>

http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeMappingFactory.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeMappingFactory.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeMappingFactory.java
index 91bf2e6..14af791 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeMappingFactory.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/NodeMappingFactory.java
@@ -212,6 +212,17 @@ public class NodeMappingFactory {
                                     .endObject()
                                 .endObject()
                             .endObject()
+                            
+
+                            .startObject(JsonMessageConstants.TEXT)
+                                .field(TYPE, STRING)
+                                .startObject(FIELDS)
+                                    .startObject(RAW)
+                                        .field(TYPE, STRING)
+                                        .field(ANALYZER, IndexCreationFactory.CASE_INSENSITIVE)
+                                    .endObject()
+                                .endObject()
+                            .endObject()
                         .endObject()
                     .endObject()
                 .endObject();

http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
index ec58c3c..a3d1ae4 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessage.java
@@ -26,6 +26,7 @@ import java.time.ZonedDateTime;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
+import java.util.stream.Stream;
 
 import org.apache.james.mailbox.MailboxSession.User;
 import org.apache.james.mailbox.elasticsearch.query.DateResolutionFormater;
@@ -37,6 +38,7 @@ import org.apache.james.mime4j.MimeException;
 import com.fasterxml.jackson.annotation.JsonProperty;
 import com.github.steveash.guavate.Guavate;
 import com.google.common.base.Preconditions;
+import com.google.common.base.Strings;
 import com.google.common.base.Throwables;
 import com.google.common.collect.Multimap;
 
@@ -52,6 +54,7 @@ public class IndexableMessage {
             indexableMessage.bodyText = parsingResult.locateFirstTextualBody();
             indexableMessage.setFlattenedAttachments(parsingResult);
             indexableMessage.copyHeaderFields(parsingResult.getHeaderCollection(), getSanitizedInternalDate(message, zoneId));
+            indexableMessage.generateText();
         } catch (IOException | MimeException e) {
             throw Throwables.propagate(e);
         }
@@ -102,6 +105,17 @@ public class IndexableMessage {
             zoneId);
     }
 
+    private void generateText() {
+        this.text = Stream.of(from.serialize(),
+                to.serialize(),
+                cc.serialize(),
+                bcc.serialize(),
+                subjects.serialize(),
+                bodyText.orElse(null))
+            .filter(str -> !Strings.isNullOrEmpty(str))
+            .collect(Collectors.joining(" "));
+    }
+
     private Long id;
     private String mailboxId;
     private List<String> users;
@@ -128,6 +142,7 @@ public class IndexableMessage {
     private List<Property> properties;
     private List<MimePart> attachments;
     private Optional<String> bodyText;
+    private String text;
 
     @JsonProperty(JsonMessageConstants.ID)
     public Long getId() {
@@ -263,4 +278,9 @@ public class IndexableMessage {
     public boolean getHasAttachment() {
         return attachments.size() > 0;
     }
+
+    @JsonProperty(JsonMessageConstants.TEXT)
+    public String getText() {
+        return text;
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java
index 56361e8..25df70b 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/json/JsonMessageConstants.java
@@ -43,6 +43,7 @@ public interface JsonMessageConstants {
     String TEXT_BODY = "textBody";
     String SENT_DATE = "sentDate";
     String ATTACHMENTS = "attachments";
+    String TEXT = "text";
 
     /*
     James properties we can easily get

http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
index a523c3d..a49713d 100644
--- a/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
+++ b/mailbox/elasticsearch/src/main/java/org/apache/james/mailbox/elasticsearch/query/CriterionConverter.java
@@ -128,6 +128,9 @@ public class CriterionConverter {
         switch (textCriterion.getType()) {
         case BODY:
             return matchQuery(JsonMessageConstants.TEXT_BODY, textCriterion.getOperator().getValue());
+        case TEXT:
+            return boolQuery()
+                    .should(matchQuery(JsonMessageConstants.TEXT, textCriterion.getOperator().getValue()));
         case FULL:
             return boolQuery()
                     .should(matchQuery(JsonMessageConstants.TEXT_BODY, textCriterion.getOperator().getValue()))

http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
new file mode 100644
index 0000000..2a62f2c
--- /dev/null
+++ b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/json/IndexableMessageTest.java
@@ -0,0 +1,185 @@
+/****************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one   *
+ * or more contributor license agreements.  See the NOTICE file *
+ * distributed with this work for additional information        *
+ * regarding copyright ownership.  The ASF licenses this file   *
+ * to you under the Apache License, Version 2.0 (the            *
+ * "License"); you may not use this file except in compliance   *
+ * with the License.  You may obtain a copy of the License at   *
+ *                                                              *
+ *   http://www.apache.org/licenses/LICENSE-2.0                 *
+ *                                                              *
+ * Unless required by applicable law or agreed to in writing,   *
+ * software distributed under the License is distributed on an  *
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
+ * KIND, either express or implied.  See the License for the    *
+ * specific language governing permissions and limitations      *
+ * under the License.                                           *
+ ****************************************************************/
+
+package org.apache.james.mailbox.elasticsearch.json;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.time.ZoneId;
+
+import javax.mail.Flags;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mailbox.mock.MockMailboxSession;
+import org.apache.james.mailbox.store.TestId;
+import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
+import org.apache.james.mailbox.store.mail.model.MailboxMessage;
+import org.junit.Test;
+
+import com.google.common.collect.ImmutableList;
+
+public class IndexableMessageTest {
+
+    @Test
+    public void textShouldBeEmptyWhenNoMatchingHeaders() throws Exception {
+        MailboxMessage mailboxMessage = mock(MailboxMessage.class);
+        TestId mailboxId = TestId.of(1);
+        when(mailboxMessage.getMailboxId())
+            .thenReturn(mailboxId);
+        when(mailboxMessage.getFullContent())
+            .thenReturn(new ByteArrayInputStream("".getBytes()));
+        when(mailboxMessage.createFlags())
+            .thenReturn(new Flags());
+
+        IndexableMessage indexableMessage = IndexableMessage.from(mailboxMessage, ImmutableList.of(new MockMailboxSession("username").getUser()),
+                new DefaultTextExtractor(), ZoneId.of("Europe/Paris"));
+
+        assertThat(indexableMessage.getText()).isEmpty();
+    }
+
+    @Test
+    public void textShouldContainsFromWhenFrom() throws Exception {
+        MailboxMessage mailboxMessage = mock(MailboxMessage.class);
+        TestId mailboxId = TestId.of(1);
+        when(mailboxMessage.getMailboxId())
+            .thenReturn(mailboxId);
+        when(mailboxMessage.getFullContent())
+            .thenReturn(new ByteArrayInputStream("From: First user <us...@james.org>\nFrom: Second user <us...@james.org>".getBytes()));
+        when(mailboxMessage.createFlags())
+            .thenReturn(new Flags());
+
+        IndexableMessage indexableMessage = IndexableMessage.from(mailboxMessage, ImmutableList.of(new MockMailboxSession("username").getUser()),
+                new DefaultTextExtractor(), ZoneId.of("Europe/Paris"));
+
+        assertThat(indexableMessage.getText()).isEqualTo("Second user user2@james.org First user user@james.org");
+    }
+
+    @Test
+    public void textShouldContainsToWhenTo() throws Exception {
+        MailboxMessage mailboxMessage = mock(MailboxMessage.class);
+        TestId mailboxId = TestId.of(1);
+        when(mailboxMessage.getMailboxId())
+            .thenReturn(mailboxId);
+        when(mailboxMessage.getFullContent())
+            .thenReturn(new ByteArrayInputStream("To: First to <us...@james.org>\nTo: Second to <us...@james.org>".getBytes()));
+        when(mailboxMessage.createFlags())
+            .thenReturn(new Flags());
+
+        IndexableMessage indexableMessage = IndexableMessage.from(mailboxMessage, ImmutableList.of(new MockMailboxSession("username").getUser()),
+                new DefaultTextExtractor(), ZoneId.of("Europe/Paris"));
+
+        assertThat(indexableMessage.getText()).isEqualTo("First to user@james.org Second to user2@james.org");
+    }
+
+    @Test
+    public void textShouldContainsCcWhenCc() throws Exception {
+        MailboxMessage mailboxMessage = mock(MailboxMessage.class);
+        TestId mailboxId = TestId.of(1);
+        when(mailboxMessage.getMailboxId())
+            .thenReturn(mailboxId);
+        when(mailboxMessage.getFullContent())
+            .thenReturn(new ByteArrayInputStream("Cc: First cc <us...@james.org>\nCc: Second cc <us...@james.org>".getBytes()));
+        when(mailboxMessage.createFlags())
+            .thenReturn(new Flags());
+
+        IndexableMessage indexableMessage = IndexableMessage.from(mailboxMessage, ImmutableList.of(new MockMailboxSession("username").getUser()),
+                new DefaultTextExtractor(), ZoneId.of("Europe/Paris"));
+
+        assertThat(indexableMessage.getText()).isEqualTo("First cc user@james.org Second cc user2@james.org");
+    }
+
+    @Test
+    public void textShouldContainsBccWhenBcc() throws Exception {
+        MailboxMessage mailboxMessage = mock(MailboxMessage.class);
+        TestId mailboxId = TestId.of(1);
+        when(mailboxMessage.getMailboxId())
+            .thenReturn(mailboxId);
+        when(mailboxMessage.getFullContent())
+            .thenReturn(new ByteArrayInputStream("Bcc: First bcc <us...@james.org>\nBcc: Second bcc <us...@james.org>".getBytes()));
+        when(mailboxMessage.createFlags())
+            .thenReturn(new Flags());
+
+        IndexableMessage indexableMessage = IndexableMessage.from(mailboxMessage, ImmutableList.of(new MockMailboxSession("username").getUser()),
+                new DefaultTextExtractor(), ZoneId.of("Europe/Paris"));
+
+        assertThat(indexableMessage.getText()).isEqualTo("Second bcc user2@james.org First bcc user@james.org");
+    }
+
+    @Test
+    public void textShouldContainsSubjectsWhenSubjects() throws Exception {
+        MailboxMessage mailboxMessage = mock(MailboxMessage.class);
+        TestId mailboxId = TestId.of(1);
+        when(mailboxMessage.getMailboxId())
+            .thenReturn(mailboxId);
+        when(mailboxMessage.getFullContent())
+            .thenReturn(new ByteArrayInputStream("Subject: subject1\nSubject: subject2".getBytes()));
+        when(mailboxMessage.createFlags())
+            .thenReturn(new Flags());
+
+        IndexableMessage indexableMessage = IndexableMessage.from(mailboxMessage, ImmutableList.of(new MockMailboxSession("username").getUser()),
+                new DefaultTextExtractor(), ZoneId.of("Europe/Paris"));
+
+        assertThat(indexableMessage.getText()).isEqualTo("subject1 subject2");
+    }
+
+    @Test
+    public void textShouldContainsBodyWhenBody() throws Exception {
+        MailboxMessage mailboxMessage = mock(MailboxMessage.class);
+        TestId mailboxId = TestId.of(1);
+        when(mailboxMessage.getMailboxId())
+            .thenReturn(mailboxId);
+        when(mailboxMessage.getFullContent())
+            .thenReturn(new ByteArrayInputStream("\nMy body".getBytes()));
+        when(mailboxMessage.createFlags())
+            .thenReturn(new Flags());
+
+        IndexableMessage indexableMessage = IndexableMessage.from(mailboxMessage, ImmutableList.of(new MockMailboxSession("username").getUser()),
+                new DefaultTextExtractor(), ZoneId.of("Europe/Paris"));
+
+        assertThat(indexableMessage.getText()).isEqualTo("My body");
+    }
+
+    @Test
+    public void textShouldContainsAllFieldsWhenAllSet() throws Exception {
+        MailboxMessage mailboxMessage = mock(MailboxMessage.class);
+        TestId mailboxId = TestId.of(1);
+        when(mailboxMessage.getMailboxId())
+            .thenReturn(mailboxId);
+        when(mailboxMessage.getFullContent())
+            .thenReturn(new ByteArrayInputStream(IOUtils.toByteArray(ClassLoader.getSystemResourceAsStream("eml/mailWithHeaders.eml"))));
+        when(mailboxMessage.createFlags())
+            .thenReturn(new Flags());
+
+        IndexableMessage indexableMessage = IndexableMessage.from(mailboxMessage, ImmutableList.of(new MockMailboxSession("username").getUser()),
+                new DefaultTextExtractor(), ZoneId.of("Europe/Paris"));
+
+        assertThat(indexableMessage.getText()).isEqualTo("Ad Min admin@opush.test " +
+                "a@test a@test B b@test " + 
+                "c@test c@test " +
+                "dD d@test " + 
+                "my subject " + 
+                "Mail content\n" +
+                "\n" +
+                "-- \n" + 
+                "Ad Min\n");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/elasticsearch/src/test/resources/eml/mailWithHeaders.eml
----------------------------------------------------------------------
diff --git a/mailbox/elasticsearch/src/test/resources/eml/mailWithHeaders.eml b/mailbox/elasticsearch/src/test/resources/eml/mailWithHeaders.eml
new file mode 100644
index 0000000..2aff55d
--- /dev/null
+++ b/mailbox/elasticsearch/src/test/resources/eml/mailWithHeaders.eml
@@ -0,0 +1,14 @@
+Content-Type: text/plain; Charset=UTF-8
+Date: Fri, 17 Sep 2010 17:12:26 +0200
+Subject: my subject
+To: a@test, B <b...@test>
+Cc: c@test
+Bcc: dD <d...@test>
+MIME-Version: 1.0
+Message-Id: <20...@lenny>
+From: Ad Min <ad...@opush.test>
+
+Mail content
+
+-- 
+Ad Min

http://git-wip-us.apache.org/repos/asf/james-project/blob/c321b93c/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
----------------------------------------------------------------------
diff --git a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
index c2a1fcb..b889778 100644
--- a/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
+++ b/mailbox/store/src/test/java/org/apache/james/mailbox/store/search/AbstractMessageSearchIndexTest.java
@@ -757,4 +757,70 @@ public abstract class AbstractMessageSearchIndexTest {
         assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
             .containsExactly(2L, 3L, 4L, 5L);
     }
+
+    @Test
+    public void searchWithFullTextShouldReturnNoMailWhenNotMatching() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new SearchQuery();
+        searchQuery.andCriteria(SearchQuery.textContains("unmatching"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .isEmpty();
+    }
+
+    @Test
+    public void searchWithFullTextShouldReturnMailsWhenFromMatches() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new SearchQuery();
+        searchQuery.andCriteria(SearchQuery.textContains("spam.minet.net"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(1l);
+    }
+
+    @Test
+    public void searchWithFullTextShouldReturnMailsWhenToMatches() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new SearchQuery();
+        searchQuery.andCriteria(SearchQuery.textContains("listes.minet.net"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(1l);
+    }
+
+    @Test
+    public void searchWithFullTextShouldReturnMailsWhenCcMatches() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new SearchQuery();
+        searchQuery.andCriteria(SearchQuery.textContains("abc.org"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(3l);
+    }
+
+    @Test
+    public void searchWithFullTextShouldReturnMailsWhenBccMatches() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new SearchQuery();
+        searchQuery.andCriteria(SearchQuery.textContains("any.com"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(5l);
+    }
+
+    @Test
+    public void searchWithFullTextShouldReturnMailsWhenTextBodyMatches() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new SearchQuery();
+        searchQuery.andCriteria(SearchQuery.textContains("reviewing work"));
+        // text/plain contains: "We are reviewing work I did for this feature."
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(3l);
+    }
+
+    @Test
+    public void searchWithFullTextShouldReturnMailsWhenTextBodyMatchesAndNonContinuousWords() throws Exception {
+        Assume.assumeTrue(storeMailboxManager.getSupportedSearchCapabilities().contains(MailboxManager.SearchCapabilities.Text));
+        SearchQuery searchQuery = new SearchQuery();
+        // 2: text/plain contains: "Issue Type: New Feature"
+        // 3: text/plain contains: "We are reviewing work I did for this feature."
+        searchQuery.andCriteria(SearchQuery.textContains("reviewing feature"));
+        assertThat(messageSearchIndex.search(session, mailbox, searchQuery))
+            .containsExactly(2l, 3l);
+    }
 }


---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org