This is an automated email from the ASF dual-hosted git repository.

btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git

commit 8cd5cf7f6fdd3620b9d6651bed639fd22e22123d
Author: Rene Cordier <rcord...@linagora.com>
AuthorDate: Mon Oct 14 15:37:31 2019 +0700

    JAMES-2920 No longer rely on mocks in 
ElasticSearchListeningMessageSearchIndexTest
---
 ...asticSearchListeningMessageSearchIndexTest.java | 496 ++++++++++++++-------
 1 file changed, 332 insertions(+), 164 deletions(-)

diff --git 
a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
 
b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
index f7c2f3f..e2df49a 100644
--- 
a/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
+++ 
b/mailbox/elasticsearch/src/test/java/org/apache/james/mailbox/elasticsearch/events/ElasticSearchListeningMessageSearchIndexTest.java
@@ -19,81 +19,162 @@
 package org.apache.james.mailbox.elasticsearch.events;
 
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatCode;
 import static org.assertj.core.api.Assertions.assertThatThrownBy;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.refEq;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
 
 import java.io.IOException;
-import java.util.List;
-import java.util.Optional;
+import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
+import java.time.ZoneId;
+import java.util.Date;
 
 import javax.mail.Flags;
+import javax.mail.util.SharedByteArrayInputStream;
 
+import org.apache.james.backends.es.DockerElasticSearchRule;
 import org.apache.james.backends.es.ElasticSearchIndexer;
-import org.apache.james.backends.es.UpdatedRepresentation;
-import org.apache.james.core.User;
+import org.apache.james.mailbox.DefaultMailboxes;
 import org.apache.james.mailbox.MailboxSession;
-import org.apache.james.mailbox.MailboxSessionUtil;
 import org.apache.james.mailbox.MessageUid;
+import org.apache.james.mailbox.elasticsearch.IndexAttachments;
+import org.apache.james.mailbox.elasticsearch.MailboxElasticSearchConstants;
+import org.apache.james.mailbox.elasticsearch.MailboxIndexCreationUtil;
 import org.apache.james.mailbox.elasticsearch.json.MessageToElasticSearchJson;
+import org.apache.james.mailbox.elasticsearch.query.CriterionConverter;
+import org.apache.james.mailbox.elasticsearch.query.QueryConverter;
 import org.apache.james.mailbox.elasticsearch.search.ElasticSearchSearcher;
 import org.apache.james.mailbox.events.Group;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.extractor.ParsedContent;
+import org.apache.james.mailbox.extractor.TextExtractor;
+import org.apache.james.mailbox.inmemory.InMemoryId;
+import org.apache.james.mailbox.inmemory.InMemoryMailboxSessionMapperFactory;
+import org.apache.james.mailbox.inmemory.InMemoryMessageId;
+import org.apache.james.mailbox.manager.ManagerTestProvisionner;
+import org.apache.james.mailbox.model.Attachment;
 import org.apache.james.mailbox.model.Mailbox;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.model.MessageAttachment;
+import org.apache.james.mailbox.model.MessageId;
+import org.apache.james.mailbox.model.SearchQuery;
 import org.apache.james.mailbox.model.TestId;
+import org.apache.james.mailbox.model.TestMessageId;
 import org.apache.james.mailbox.model.UpdatedFlags;
+import org.apache.james.mailbox.store.Authorizator;
+import org.apache.james.mailbox.store.FakeAuthenticator;
+import org.apache.james.mailbox.store.FakeAuthorizator;
 import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
 import org.apache.james.mailbox.store.SessionProvider;
-import org.apache.james.mailbox.store.mail.model.MailboxMessage;
-import org.elasticsearch.ElasticsearchException;
-import org.elasticsearch.action.bulk.BulkResponse;
-import org.elasticsearch.index.query.QueryBuilder;
-import org.elasticsearch.index.query.QueryBuilders;
+import org.apache.james.mailbox.store.extractor.DefaultTextExtractor;
+import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
+import org.apache.james.mailbox.store.mail.model.impl.SimpleMailboxMessage;
+import org.awaitility.Duration;
+import org.elasticsearch.client.RestHighLevelClient;
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
+import org.testcontainers.shaded.com.google.common.collect.ImmutableList;
 
-import com.fasterxml.jackson.core.JsonGenerationException;
-import com.fasterxml.jackson.core.JsonGenerator;
-import com.fasterxml.jackson.core.JsonProcessingException;
-import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Lists;
 
 public class ElasticSearchListeningMessageSearchIndexTest {
-    private static final long MODSEQ = 18L;
-    private static final MessageUid MESSAGE_UID = MessageUid.of(1);
-    private static final TestId MAILBOX_ID = TestId.of(12);
-    private static final String ELASTIC_SEARCH_ID = "12:1";
-    private static final String EXPECTED_JSON_CONTENT = "json content";
-    private static final String USERNAME = "username";
+    private static final int SIZE = 25;
+    private static final int BODY_START_OCTET = 100;
+    private static final TestId MAILBOX_ID = TestId.of(1L);
+    private static final long MOD_SEQ = 42L;
+    private static final String USERNAME = "user";
+    private static final MessageUid MESSAGE_UID_1 = MessageUid.of(25);
+    private static final MessageUid MESSAGE_UID_2 = MessageUid.of(26);
+    private static final MessageUid MESSAGE_UID_3 = MessageUid.of(27);
+    private static final MessageId MESSAGE_ID_1 = TestMessageId.of(18L);
+    private static final MessageId MESSAGE_ID_2 = TestMessageId.of(19L);
+    private static final MessageId MESSAGE_ID_3 = TestMessageId.of(20L);
+
+    private static final SimpleMailboxMessage.Builder MESSAGE_BUILDER = 
SimpleMailboxMessage.builder()
+        .mailboxId(MAILBOX_ID)
+        .flags(new Flags())
+        .bodyStartOctet(BODY_START_OCTET)
+        .internalDate(new Date(1433628000000L))
+        .size(SIZE)
+        .content(new 
SharedByteArrayInputStream("message".getBytes(StandardCharsets.UTF_8)))
+        .propertyBuilder(new PropertyBuilder())
+        .modseq(MOD_SEQ);
+
+    private static final SimpleMailboxMessage MESSAGE_1 = 
MESSAGE_BUILDER.messageId(MESSAGE_ID_1)
+        .uid(MESSAGE_UID_1)
+        .build();
+
+    private static final SimpleMailboxMessage MESSAGE_2 = 
MESSAGE_BUILDER.messageId(MESSAGE_ID_2)
+        .uid(MESSAGE_UID_2)
+        .build();
+
+    private static final MessageAttachment MESSAGE_ATTACHMENT = 
MessageAttachment.builder()
+        .attachment(Attachment.builder()
+            .bytes("".getBytes(StandardCharsets.UTF_8))
+            .type("type")
+            .build())
+        .name("name")
+        .isInline(false)
+        .build();
+
+    private static final SimpleMailboxMessage MESSAGE_WITH_ATTACHMENT = 
MESSAGE_BUILDER.messageId(MESSAGE_ID_3)
+        .uid(MESSAGE_UID_3)
+        .addAttachments(ImmutableList.of(MESSAGE_ATTACHMENT))
+        .build();
+
+    static class FailingTextExtractor implements TextExtractor {
+        @Override
+        public ParsedContent extractContent(InputStream inputStream, String 
contentType) throws Exception {
+            throw new RuntimeException();
+        }
+    }
 
-    private ElasticSearchIndexer elasticSearchIndexer;
-    private MessageToElasticSearchJson messageToElasticSearchJson;
     private ElasticSearchListeningMessageSearchIndex testee;
     private MailboxSession session;
-    private List<User> users;
     private Mailbox mailbox;
+    private MailboxSessionMapperFactory mapperFactory;
+    private ElasticSearchIndexer elasticSearchIndexer;
+    private ElasticSearchSearcher elasticSearchSearcher;
+    private SessionProvider sessionProvider;
+
+    @Rule
+    public DockerElasticSearchRule elasticSearch = new 
DockerElasticSearchRule();
 
     @Before
-    public void setup() {
-        MailboxSessionMapperFactory mapperFactory = 
mock(MailboxSessionMapperFactory.class);
-        messageToElasticSearchJson = mock(MessageToElasticSearchJson.class);
-        ElasticSearchSearcher elasticSearchSearcher = 
mock(ElasticSearchSearcher.class);
-        SessionProvider mockSessionProvider = mock(SessionProvider.class);
+    public void setup() throws MailboxException, IOException {
+        mapperFactory = new InMemoryMailboxSessionMapperFactory();
+
+        MessageToElasticSearchJson messageToElasticSearchJson = new 
MessageToElasticSearchJson(
+            new DefaultTextExtractor(),
+            ZoneId.of("UTC"),
+            IndexAttachments.YES);
+
+        InMemoryMessageId.Factory messageIdFactory = new 
InMemoryMessageId.Factory();
+
+        RestHighLevelClient client = 
MailboxIndexCreationUtil.prepareDefaultClient(
+            elasticSearch.clientProvider().get(),
+            elasticSearch.getDockerElasticSearch().configuration());
 
-        elasticSearchIndexer = mock(ElasticSearchIndexer.class);
+        elasticSearchSearcher = new ElasticSearchSearcher(client,
+            new QueryConverter(new CriterionConverter()),
+            ElasticSearchSearcher.DEFAULT_SEARCH_SIZE,
+            new InMemoryId.Factory(),
+            messageIdFactory,
+            MailboxElasticSearchConstants.DEFAULT_MAILBOX_READ_ALIAS);
+
+        FakeAuthenticator fakeAuthenticator = new FakeAuthenticator();
+        fakeAuthenticator.addUser(ManagerTestProvisionner.USER, 
ManagerTestProvisionner.USER_PASS);
+        Authorizator authorizator = FakeAuthorizator.defaultReject();
+        sessionProvider = new SessionProvider(fakeAuthenticator, authorizator);
+
+        elasticSearchIndexer = new ElasticSearchIndexer(client, 
MailboxElasticSearchConstants.DEFAULT_MAILBOX_WRITE_ALIAS);
         
         testee = new ElasticSearchListeningMessageSearchIndex(mapperFactory, 
elasticSearchIndexer, elasticSearchSearcher,
-            messageToElasticSearchJson, mockSessionProvider);
-        session = MailboxSessionUtil.create(USERNAME);
-        users = ImmutableList.of(User.fromUsername(USERNAME));
+            messageToElasticSearchJson, sessionProvider);
+        session = sessionProvider.createSystemSession(USERNAME);
 
-        mailbox = mock(Mailbox.class);
-        when(mailbox.getMailboxId()).thenReturn(MAILBOX_ID);
+        mailbox = new Mailbox(MailboxPath.forUser(USERNAME, 
DefaultMailboxes.INBOX), MAILBOX_ID.id);
+        mapperFactory.getMailboxMapper(session).save(mailbox);
     }
 
     @Test
@@ -103,168 +184,255 @@ public class 
ElasticSearchListeningMessageSearchIndexTest {
     }
     
     @Test
-    public void addShouldIndex() throws Exception {
-        //Given
-        MailboxMessage message = mockedMessage(MESSAGE_UID);
-        
-        when(messageToElasticSearchJson.convertToJson(eq(message), eq(users)))
-            .thenReturn(EXPECTED_JSON_CONTENT);
-        
-        //When
-        testee.add(session, mailbox, message);
-        
-        //Then
-        verify(elasticSearchIndexer).index(eq(ELASTIC_SEARCH_ID), 
eq(EXPECTED_JSON_CONTENT));
+    public void addShouldIndexMessageWithoutAttachment() throws Exception {
+        testee.add(session, mailbox, MESSAGE_1);
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .containsExactly(MESSAGE_1.getUid());
     }
 
+
     @Test
-    public void addShouldIndexEmailBodyWhenNotIndexableAttachment() throws 
Exception {
-        //Given
-        MailboxMessage message = mockedMessage(MESSAGE_UID);
-        
-        when(messageToElasticSearchJson.convertToJson(eq(message), eq(users)))
-            .thenThrow(JsonProcessingException.class);
-        
-        
when(messageToElasticSearchJson.convertToJsonWithoutAttachment(eq(message), 
eq(users)))
-            .thenReturn(EXPECTED_JSON_CONTENT);
-        
-        //When
-        testee.add(session, mailbox, message);
-        
-        //Then
-        verify(elasticSearchIndexer).index(eq(ELASTIC_SEARCH_ID), 
eq(EXPECTED_JSON_CONTENT));
+    public void addShouldIndexMessageWithAttachment() throws Exception {
+        testee.add(session, mailbox, MESSAGE_WITH_ATTACHMENT);
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .containsExactly(MESSAGE_WITH_ATTACHMENT.getUid());
+    }
+
+    @Test
+    public void addShouldBeIndempotent() throws Exception {
+        testee.add(session, mailbox, MESSAGE_1);
+        testee.add(session, mailbox, MESSAGE_1);
+
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .containsExactly(MESSAGE_1.getUid());
     }
 
-    private MailboxMessage mockedMessage(MessageUid uid) {
-        MailboxMessage message = mock(MailboxMessage.class);
-        when(message.getUid()).thenReturn(uid);
-        return message;
+    @Test
+    public void addShouldIndexMultipleMessages() throws Exception {
+        testee.add(session, mailbox, MESSAGE_1);
+        testee.add(session, mailbox, MESSAGE_2);
+
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .containsExactly(MESSAGE_1.getUid(), MESSAGE_2.getUid());
+    }
+
+    @Test
+    public void addShouldIndexEmailBodyWhenNotIndexableAttachment() throws 
Exception {
+        MessageToElasticSearchJson messageToElasticSearchJson = new 
MessageToElasticSearchJson(
+            new FailingTextExtractor(),
+            ZoneId.of("Europe/Paris"),
+            IndexAttachments.YES);
+
+        testee = new ElasticSearchListeningMessageSearchIndex(mapperFactory, 
elasticSearchIndexer, elasticSearchSearcher,
+            messageToElasticSearchJson, sessionProvider);
+
+        testee.add(session, mailbox, MESSAGE_WITH_ATTACHMENT);
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .containsExactly(MESSAGE_WITH_ATTACHMENT.getUid());
     }
 
     @Test
     public void addShouldPropagateExceptionWhenExceptionOccurs() throws 
Exception {
-        //Given
-        MailboxMessage message = mockedMessage(MESSAGE_UID);
-        
-        when(messageToElasticSearchJson.convertToJson(eq(message), eq(users)))
-            .thenThrow(JsonProcessingException.class);
+        elasticSearch.getDockerElasticSearch().pause();
+        Thread.sleep(Duration.FIVE_SECONDS.getValueInMS()); // Docker pause is 
asynchronous and we found no way to poll for it
 
-        // When
-        JsonGenerator jsonGenerator = null;
-        
when(messageToElasticSearchJson.convertToJsonWithoutAttachment(eq(message), 
eq(users)))
-            .thenThrow(new JsonGenerationException("expected error", 
jsonGenerator));
-        
-        //Then
-        assertThatThrownBy(() -> testee.add(session, mailbox, 
message)).isInstanceOf(JsonGenerationException.class);
+        assertThatThrownBy(() -> testee.add(session, mailbox, MESSAGE_1))
+            .isInstanceOf(IOException.class);
+
+        elasticSearch.getDockerElasticSearch().unpause();
     }
 
     @Test
-    @SuppressWarnings("unchecked")
-    public void deleteShouldWork() throws IOException {
-        //Given
-        BulkResponse expectedBulkResponse = mock(BulkResponse.class);
-        when(elasticSearchIndexer.delete(any(List.class)))
-            .thenReturn(Optional.of(expectedBulkResponse));
-
-        //When
-        testee.delete(session, mailbox, Lists.newArrayList(MESSAGE_UID));
-
-        //Then
-        
verify(elasticSearchIndexer).delete(eq(Lists.newArrayList(ELASTIC_SEARCH_ID)));
+    public void deleteShouldRemoveIndex() throws IOException {
+        testee.add(session, mailbox, MESSAGE_1);
+        elasticSearch.awaitForElasticSearch();
+
+        testee.delete(session, mailbox, Lists.newArrayList(MESSAGE_UID_1));
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .isEmpty();
     }
 
     @Test
-    @SuppressWarnings("unchecked")
-    public void deleteShouldWorkWhenMultipleMessageIds() throws IOException {
-        //Given
-        MessageUid messageId2 = MessageUid.of(2);
-        MessageUid messageId3 = MessageUid.of(3);
-        MessageUid messageId4 = MessageUid.of(4);
-        MessageUid messageId5 = MessageUid.of(5);
-
-        BulkResponse expectedBulkResponse = mock(BulkResponse.class);
-        when(elasticSearchIndexer.delete(any(List.class)))
-            .thenReturn(Optional.of(expectedBulkResponse));
-        
-        //When
-        testee.delete(session, mailbox, Lists.newArrayList(MESSAGE_UID, 
messageId2, messageId3, messageId4, messageId5));
-        
-        //Then
-        
verify(elasticSearchIndexer).delete(eq(Lists.newArrayList(ELASTIC_SEARCH_ID, 
"12:2", "12:3", "12:4", "12:5")));
+    public void deleteShouldOnlyRemoveIndexesPassedAsArguments() throws 
IOException {
+        testee.add(session, mailbox, MESSAGE_1);
+        testee.add(session, mailbox, MESSAGE_2);
+
+        elasticSearch.awaitForElasticSearch();
+
+        testee.delete(session, mailbox, Lists.newArrayList(MESSAGE_UID_1));
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .containsExactly(MESSAGE_2.getUid());
     }
 
     @Test
-    @SuppressWarnings("unchecked")
-    public void deleteShouldPropagateExceptionWhenExceptionOccurs() throws 
IOException {
-        //Given
-        when(elasticSearchIndexer.delete(any(List.class)))
-            .thenThrow(new ElasticsearchException(""));
-
-        // Then
-        assertThatThrownBy(() -> testee.delete(session, mailbox, 
Lists.newArrayList(MESSAGE_UID)))
-            .isInstanceOf(ElasticsearchException.class);
+    public void deleteShouldRemoveMultipleIndexes() throws IOException {
+        testee.add(session, mailbox, MESSAGE_1);
+        testee.add(session, mailbox, MESSAGE_2);
+
+        elasticSearch.awaitForElasticSearch();
+
+        testee.delete(session, mailbox, Lists.newArrayList(MESSAGE_UID_1, 
MESSAGE_UID_2));
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .isEmpty();
     }
 
     @Test
-    public void updateShouldWork() throws Exception {
-        //Given
-        Flags flags = new Flags();
+    public void deleteShouldBeIdempotent() throws IOException {
+        testee.add(session, mailbox, MESSAGE_1);
+        elasticSearch.awaitForElasticSearch();
+
+        testee.delete(session, mailbox, Lists.newArrayList(MESSAGE_UID_1));
+        testee.delete(session, mailbox, Lists.newArrayList(MESSAGE_UID_1));
+        elasticSearch.awaitForElasticSearch();
 
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .isEmpty();
+    }
+
+    @Test
+    public void deleteShouldNotThrowOnUnknownMessageUid() throws Exception {
+        assertThatCode(() -> testee.delete(session, mailbox, 
Lists.newArrayList(MESSAGE_UID_1)))
+            .doesNotThrowAnyException();
+    }
+
+    @Test
+    public void deleteShouldPropagateExceptionWhenExceptionOccurs() throws 
Exception {
+        elasticSearch.getDockerElasticSearch().pause();
+        Thread.sleep(Duration.FIVE_SECONDS.getValueInMS()); // Docker pause is 
asynchronous and we found no way to poll for it
+
+        assertThatThrownBy(() -> testee.delete(session, mailbox, 
Lists.newArrayList(MESSAGE_UID_1)))
+            .isInstanceOf(IOException.class);
+
+        elasticSearch.getDockerElasticSearch().unpause();
+    }
+
+    @Test
+    public void updateShouldUpdateIndex() throws Exception {
+        testee.add(session, mailbox, MESSAGE_1);
+        elasticSearch.awaitForElasticSearch();
+
+        Flags newFlags = new Flags(Flags.Flag.ANSWERED);
         UpdatedFlags updatedFlags = UpdatedFlags.builder()
-            .uid(MESSAGE_UID)
-            .modSeq(MODSEQ)
-            .oldFlags(flags)
-            .newFlags(flags)
+            .uid(MESSAGE_UID_1)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags())
+            .newFlags(newFlags)
             .build();
 
-        
when(messageToElasticSearchJson.getUpdatedJsonMessagePart(any(Flags.class), 
any(Long.class)))
-            .thenReturn("json updated content");
-        
-        //When
         testee.update(session, mailbox, Lists.newArrayList(updatedFlags));
-        
-        //Then
-        ImmutableList<UpdatedRepresentation> expectedUpdatedRepresentations = 
ImmutableList.of(new UpdatedRepresentation(ELASTIC_SEARCH_ID, "json updated 
content"));
-        verify(elasticSearchIndexer).update(expectedUpdatedRepresentations);
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new 
SearchQuery(SearchQuery.flagIsSet(Flags.Flag.ANSWERED));
+        assertThat(testee.search(session, mailbox, query))
+            .containsExactly(MESSAGE_1.getUid());
     }
 
     @Test
-    public void updateShouldPropagateExceptionWhenExceptionOccurs() throws 
Exception {
-        //Given
-        Flags flags = new Flags();
+    public void updateShouldNotUpdateNorThrowOnUnknownMessageUid() throws 
Exception {
+        testee.add(session, mailbox, MESSAGE_1);
+        elasticSearch.awaitForElasticSearch();
+
+        Flags newFlags = new Flags(Flags.Flag.ANSWERED);
         UpdatedFlags updatedFlags = UpdatedFlags.builder()
-            .uid(MESSAGE_UID)
-            .modSeq(MODSEQ)
-            .oldFlags(flags)
-            .newFlags(flags)
+            .uid(MESSAGE_UID_2)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags())
+            .newFlags(newFlags)
             .build();
-        when(messageToElasticSearchJson.getUpdatedJsonMessagePart(any(), 
anyLong())).thenReturn("update doc");
 
-        //When
-        when(elasticSearchIndexer.update(any())).thenThrow(new 
ElasticsearchException(""));
-        
-        //Then
-        assertThatThrownBy(() -> testee.update(session, mailbox, 
Lists.newArrayList(updatedFlags))).isInstanceOf(ElasticsearchException.class);
+        testee.update(session, mailbox, Lists.newArrayList(updatedFlags));
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new 
SearchQuery(SearchQuery.flagIsSet(Flags.Flag.ANSWERED));
+        assertThat(testee.search(session, mailbox, query))
+            .isEmpty();
     }
 
     @Test
-    public void deleteAllShouldWork() {
-        //Given
-        testee.deleteAll(session, MAILBOX_ID);
-        
-        //Then
-        QueryBuilder expectedQueryBuilder = 
QueryBuilders.termQuery("mailboxId", "12");
-        
verify(elasticSearchIndexer).deleteAllMatchingQuery(refEq(expectedQueryBuilder));
+    public void updateShouldBeIdempotent() throws Exception {
+        testee.add(session, mailbox, MESSAGE_1);
+        elasticSearch.awaitForElasticSearch();
+
+        Flags newFlags = new Flags(Flags.Flag.ANSWERED);
+        UpdatedFlags updatedFlags = UpdatedFlags.builder()
+            .uid(MESSAGE_UID_1)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags())
+            .newFlags(newFlags)
+            .build();
+
+        testee.update(session, mailbox, Lists.newArrayList(updatedFlags));
+        testee.update(session, mailbox, Lists.newArrayList(updatedFlags));
+        elasticSearch.awaitForElasticSearch();
+
+        SearchQuery query = new 
SearchQuery(SearchQuery.flagIsSet(Flags.Flag.ANSWERED));
+        assertThat(testee.search(session, mailbox, query))
+            .containsExactly(MESSAGE_1.getUid());
+    }
+
+    @Test
+    public void updateShouldPropagateExceptionWhenExceptionOccurs() throws 
Exception {
+        elasticSearch.getDockerElasticSearch().pause();
+        Thread.sleep(Duration.FIVE_SECONDS.getValueInMS()); // Docker pause is 
asynchronous and we found no way to poll for it
+
+        Flags newFlags = new Flags(Flags.Flag.ANSWERED);
+        UpdatedFlags updatedFlags = UpdatedFlags.builder()
+            .uid(MESSAGE_UID_1)
+            .modSeq(MOD_SEQ)
+            .oldFlags(new Flags())
+            .newFlags(newFlags)
+            .build();
+
+        assertThatThrownBy(() -> testee.update(session, mailbox, 
Lists.newArrayList(updatedFlags)))
+            .isInstanceOf(IOException.class);
+
+        elasticSearch.getDockerElasticSearch().unpause();
     }
 
     @Test
-    public void deleteAllShouldNotPropagateExceptionWhenExceptionOccurs() {
-        //Given
-        doThrow(RuntimeException.class)
-            .when(elasticSearchIndexer).deleteAllMatchingQuery(any());
+    public void deleteAllShouldRemoveAllIndexes() throws Exception {
+        testee.add(session, mailbox, MESSAGE_1);
+        testee.add(session, mailbox, MESSAGE_2);
+
+        elasticSearch.awaitForElasticSearch();
+
+        testee.deleteAll(session, mailbox.getMailboxId());
+        elasticSearch.awaitForElasticSearch();
 
-        //Then
-        assertThatThrownBy(() -> testee.deleteAll(session, 
MAILBOX_ID)).isInstanceOf(RuntimeException.class);
+        SearchQuery query = new SearchQuery(SearchQuery.all());
+        assertThat(testee.search(session, mailbox, query))
+            .isEmpty();
+    }
+
+    @Test
+    public void deleteAllShouldNotThrowWhenEmptyIndex() {
+        assertThatCode(() -> testee.deleteAll(session, mailbox.getMailboxId()))
+            .doesNotThrowAnyException();
     }
 
 }
\ No newline at end of file


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

Reply via email to