JAMES-2541 Add tests for JSON structure stability

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

Branch: refs/heads/master
Commit: f6f9961ac053ed245b1d362e6747e6bdba4ee8dc
Parents: 7dc41ae
Author: Benoit Tellier <[email protected]>
Authored: Fri Sep 7 17:02:27 2018 +0700
Committer: Benoit Tellier <[email protected]>
Committed: Mon Sep 10 17:19:38 2018 +0700

----------------------------------------------------------------------
 server/queue/queue-rabbitmq/pom.xml             |   5 +
 .../apache/james/queue/rabbitmq/HeadersDto.java |  20 ++-
 .../apache/james/queue/rabbitmq/MailDTO.java    |  50 ++++++--
 .../james/queue/rabbitmq/RabbitMQMailQueue.java |   8 +-
 .../james/queue/rabbitmq/MailDTOTest.java       | 122 +++++++++++++++++++
 .../src/test/resources/json/mail1.json          |  16 +++
 .../src/test/resources/json/mail_min.json       |  14 +++
 7 files changed, 221 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/f6f9961a/server/queue/queue-rabbitmq/pom.xml
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/pom.xml 
b/server/queue/queue-rabbitmq/pom.xml
index 1dc37ef..2884684 100644
--- a/server/queue/queue-rabbitmq/pom.xml
+++ b/server/queue/queue-rabbitmq/pom.xml
@@ -140,6 +140,11 @@
             <artifactId>javax.inject</artifactId>
         </dependency>
         <dependency>
+            <groupId>net.javacrumbs.json-unit</groupId>
+            <artifactId>json-unit-assertj</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>nl.jqno.equalsverifier</groupId>
             <artifactId>equalsverifier</artifactId>
             <scope>test</scope>

http://git-wip-us.apache.org/repos/asf/james-project/blob/f6f9961a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/HeadersDto.java
----------------------------------------------------------------------
diff --git 
a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/HeadersDto.java
 
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/HeadersDto.java
index 5d6061b..e2ed6c6 100644
--- 
a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/HeadersDto.java
+++ 
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/HeadersDto.java
@@ -20,6 +20,7 @@
 package org.apache.james.queue.rabbitmq;
 
 import java.util.Collection;
+import java.util.Objects;
 
 import org.apache.mailet.PerRecipientHeaders;
 
@@ -31,7 +32,7 @@ import com.google.common.collect.Multimap;
 
 public class HeadersDto {
 
-    public static HeadersDto from(Collection<PerRecipientHeaders.Header> 
headers) {
+    static HeadersDto from(Collection<PerRecipientHeaders.Header> headers) {
         return new HeadersDto(headers.stream()
             .collect(ImmutableListMultimap.toImmutableListMultimap(
                 PerRecipientHeaders.Header::getName,
@@ -50,7 +51,7 @@ public class HeadersDto {
         return headers;
     }
 
-    public Collection<PerRecipientHeaders.Header> toHeaders() {
+    Collection<PerRecipientHeaders.Header> toHeaders() {
         return headers.entries()
             .stream()
             .map(entry -> PerRecipientHeaders.Header.builder()
@@ -59,4 +60,19 @@ public class HeadersDto {
                 .build())
             .collect(ImmutableList.toImmutableList());
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof HeadersDto) {
+            HeadersDto that = (HeadersDto) o;
+
+            return Objects.equals(this.headers, that.headers);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(headers);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/f6f9961a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailDTO.java
----------------------------------------------------------------------
diff --git 
a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailDTO.java
 
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailDTO.java
index d760f18..c4b9d28 100644
--- 
a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailDTO.java
+++ 
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/MailDTO.java
@@ -21,9 +21,12 @@ package org.apache.james.queue.rabbitmq;
 
 import java.time.Instant;
 import java.util.Collection;
+import java.util.Date;
 import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.stream.Stream;
 
-import org.apache.commons.lang3.tuple.Pair;
 import org.apache.james.blob.mail.MimeMessagePartsId;
 import org.apache.james.core.MailAddress;
 import org.apache.james.util.SerializationUtil;
@@ -41,14 +44,15 @@ class MailDTO {
 
     static MailDTO fromMail(Mail mail, MimeMessagePartsId partsId) {
         return new MailDTO(
-            mail.getRecipients().stream()
+            Optional.ofNullable(mail.getRecipients()).map(Collection::stream)
+                .orElse(Stream.empty())
                 .map(MailAddress::asString)
                 .collect(Guavate.toImmutableList()),
             mail.getName(),
-            mail.getSender().asString(),
+            Optional.ofNullable(mail.getSender()).map(MailAddress::asString),
             mail.getState(),
             mail.getErrorMessage(),
-            mail.getLastUpdated().toInstant(),
+            Optional.ofNullable(mail.getLastUpdated()).map(Date::toInstant),
             serializedAttributes(mail),
             mail.getRemoteAddr(),
             mail.getRemoteHost(),
@@ -76,10 +80,10 @@ class MailDTO {
 
     private final ImmutableList<String> recipients;
     private final String name;
-    private final String sender;
+    private final Optional<String> sender;
     private final String state;
     private final String errorMessage;
-    private final Instant lastUpdated;
+    private final Optional<Instant> lastUpdated;
     private final ImmutableMap<String, String> attributes;
     private final String remoteAddr;
     private final String remoteHost;
@@ -90,10 +94,10 @@ class MailDTO {
     @JsonCreator
     private MailDTO(@JsonProperty("recipients") ImmutableList<String> 
recipients,
                     @JsonProperty("name") String name,
-                    @JsonProperty("sender") String sender,
+                    @JsonProperty("sender") Optional<String> sender,
                     @JsonProperty("state") String state,
                     @JsonProperty("errorMessage") String errorMessage,
-                    @JsonProperty("lastUpdated") Instant lastUpdated,
+                    @JsonProperty("lastUpdated") Optional<Instant> lastUpdated,
                     @JsonProperty("attributes") ImmutableMap<String, String> 
attributes,
                     @JsonProperty("remoteAddr") String remoteAddr,
                     @JsonProperty("remoteHost") String remoteHost,
@@ -125,7 +129,7 @@ class MailDTO {
     }
 
     @JsonProperty("sender")
-    String getSender() {
+    Optional<String> getSender() {
         return sender;
     }
 
@@ -140,7 +144,7 @@ class MailDTO {
     }
 
     @JsonProperty("lastUpdated")
-    Instant getLastUpdated() {
+    Optional<Instant> getLastUpdated() {
         return lastUpdated;
     }
 
@@ -173,4 +177,30 @@ class MailDTO {
     String getBodyBlobId() {
         return bodyBlobId;
     }
+
+    @Override
+    public final boolean equals(Object o) {
+        if (o instanceof MailDTO) {
+            MailDTO mailDTO = (MailDTO) o;
+
+            return Objects.equals(this.recipients, mailDTO.recipients)
+                && Objects.equals(this.name, mailDTO.name)
+                && Objects.equals(this.sender, mailDTO.sender)
+                && Objects.equals(this.state, mailDTO.state)
+                && Objects.equals(this.errorMessage, mailDTO.errorMessage)
+                && Objects.equals(this.lastUpdated, mailDTO.lastUpdated)
+                && Objects.equals(this.attributes, mailDTO.attributes)
+                && Objects.equals(this.remoteAddr, mailDTO.remoteAddr)
+                && Objects.equals(this.remoteHost, mailDTO.remoteHost)
+                && Objects.equals(this.perRecipientHeaders, 
mailDTO.perRecipientHeaders)
+                && Objects.equals(this.headerBlobId, mailDTO.headerBlobId)
+                && Objects.equals(this.bodyBlobId, mailDTO.bodyBlobId);
+        }
+        return false;
+    }
+
+    @Override
+    public final int hashCode() {
+        return Objects.hash(recipients, name, sender, state, errorMessage, 
lastUpdated, attributes, remoteAddr, remoteHost, perRecipientHeaders, 
headerBlobId, bodyBlobId);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/f6f9961a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
----------------------------------------------------------------------
diff --git 
a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
 
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
index 10300cd..f9ad07c 100644
--- 
a/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
+++ 
b/server/queue/queue-rabbitmq/src/main/java/org/apache/james/queue/rabbitmq/RabbitMQMailQueue.java
@@ -21,6 +21,7 @@ package org.apache.james.queue.rabbitmq;
 
 import java.io.IOException;
 import java.io.Serializable;
+import java.time.Instant;
 import java.util.Date;
 import java.util.concurrent.CompletableFuture;
 import java.util.concurrent.Executors;
@@ -203,7 +204,7 @@ public class RabbitMQMailQueue implements MailQueue {
 
             MailImpl mail = new MailImpl(
                 dto.getName(),
-                MailAddress.getMailSender(dto.getSender()),
+                dto.getSender().map(MailAddress::getMailSender).orElse(null),
                 dto.getRecipients()
                     .stream()
                     .map(Throwing.<String, 
MailAddress>function(MailAddress::new).sneakyThrow())
@@ -214,7 +215,10 @@ public class RabbitMQMailQueue implements MailQueue {
             mail.setRemoteAddr(dto.getRemoteAddr());
             mail.setRemoteHost(dto.getRemoteHost());
             mail.setState(dto.getState());
-            mail.setLastUpdated(new Date(dto.getLastUpdated().toEpochMilli()));
+            dto.getLastUpdated()
+                .map(Instant::toEpochMilli)
+                .map(Date::new)
+                .ifPresent(mail::setLastUpdated);
 
             dto.getAttributes()
                 .forEach((name, value) -> mail.setAttribute(name, 
SerializationUtil.<Serializable>deserialize(value)));

http://git-wip-us.apache.org/repos/asf/james-project/blob/f6f9961a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/MailDTOTest.java
----------------------------------------------------------------------
diff --git 
a/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/MailDTOTest.java
 
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/MailDTOTest.java
new file mode 100644
index 0000000..695e978
--- /dev/null
+++ 
b/server/queue/queue-rabbitmq/src/test/java/org/apache/james/queue/rabbitmq/MailDTOTest.java
@@ -0,0 +1,122 @@
+/****************************************************************
+ * 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.queue.rabbitmq;
+
+import static net.javacrumbs.jsonunit.assertj.JsonAssertions.assertThatJson;
+import static org.apache.james.util.ClassLoaderUtils.getSystemResourceAsString;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.time.Instant;
+import java.util.Date;
+
+import javax.mail.MessagingException;
+
+import org.apache.james.blob.api.HashBlobId;
+import org.apache.james.blob.mail.MimeMessagePartsId;
+import org.apache.james.server.core.MailImpl;
+import org.apache.mailet.PerRecipientHeaders;
+import org.apache.mailet.base.MailAddressFixture;
+import org.apache.mailet.base.test.FakeMail;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.datatype.guava.GuavaModule;
+import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+class MailDTOTest {
+    static final HashBlobId.Factory BLOB_ID_FACTORY = new HashBlobId.Factory();
+    static final Date LAST_UPDATED = 
Date.from(Instant.parse("2016-09-08T14:25:52.000Z"));
+
+    private ObjectMapper objectMapper;
+
+    @BeforeEach
+    void setUp() {
+        objectMapper = new ObjectMapper()
+            .registerModule(new Jdk8Module())
+            .registerModule(new JavaTimeModule())
+            .registerModule(new GuavaModule());
+    }
+
+    @Test
+    void mailDtoShouldBeSerializedToTheRightFormat() throws Exception {
+        assertThatJson(objectMapper.writeValueAsString(mailDTO1()))
+            .isEqualTo(getSystemResourceAsString("json/mail1.json"));
+    }
+
+    @Test
+    void mailDtoShouldBeDeserializedFromTheRightFormat() throws Exception {
+        
assertThat(objectMapper.readValue(getSystemResourceAsString("json/mail1.json"), 
MailDTO.class))
+            .isEqualTo(mailDTO1());
+    }
+
+    @Test
+    void mailDtoShouldBeSerializedWhenOnlyNameAndBlob() throws Exception {
+        assertThatJson(objectMapper.writeValueAsString(mailDTOMin()))
+            .isEqualTo(getSystemResourceAsString("json/mail_min.json"));
+    }
+
+    @Test
+    void mailDtoShouldBeDeserializedWhenOnlyNameAndBlob() throws Exception {
+        
assertThat(objectMapper.readValue(getSystemResourceAsString("json/mail_min.json"),
 MailDTO.class))
+            .isEqualTo(mailDTOMin());
+    }
+
+    private MailDTO mailDTO1() throws MessagingException {
+        return MailDTO.fromMail(
+            FakeMail.builder()
+                .recipients(MailAddressFixture.RECIPIENT1, 
MailAddressFixture.RECIPIENT2)
+                .sender(MailAddressFixture.SENDER)
+                .attribute("att1", "value")
+                .errorMessage("an error")
+                .lastUpdated(LAST_UPDATED)
+                .remoteHost("toto.com")
+                .remoteAddr("159.221.12.145")
+                .addHeaderForRecipient(PerRecipientHeaders.Header.builder()
+                    .name("X-custom-header")
+                    .value("uedcgukrcg")
+                    .build(), MailAddressFixture.RECIPIENT1)
+                .addHeaderForRecipient(PerRecipientHeaders.Header.builder()
+                    .name("X-custom-header-2")
+                    .value("uedcgukrcg")
+                    .build(), MailAddressFixture.RECIPIENT2)
+                .state("state")
+                .name("mail-name-558")
+                .build(),
+            MimeMessagePartsId.builder()
+                
.headerBlobId(BLOB_ID_FACTORY.from("210e7136-ede3-44eb-9495-3ed816d6e23b"))
+                
.bodyBlobId(BLOB_ID_FACTORY.from("ef46c026-7819-4048-b562-3a37469191ed"))
+                .build());
+    }
+
+    private MailDTO mailDTOMin() throws MessagingException {
+        MailImpl mail = new MailImpl();
+        mail.setState(null);
+        mail.setName("mail-name-558");
+        mail.setLastUpdated(null);
+        return MailDTO.fromMail(
+            mail,
+            MimeMessagePartsId.builder()
+                
.headerBlobId(BLOB_ID_FACTORY.from("210e7136-ede3-44eb-9495-3ed816d6e23b"))
+                
.bodyBlobId(BLOB_ID_FACTORY.from("ef46c026-7819-4048-b562-3a37469191ed"))
+                .build());
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/james-project/blob/f6f9961a/server/queue/queue-rabbitmq/src/test/resources/json/mail1.json
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/resources/json/mail1.json 
b/server/queue/queue-rabbitmq/src/test/resources/json/mail1.json
new file mode 100644
index 0000000..625ed2e
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/test/resources/json/mail1.json
@@ -0,0 +1,16 @@
+{
+  "recipients":["recipient1@localhost","recipient2@localhost"],
+  "name":"mail-name-558",
+  "sender":"sender@localhost",
+  "state":"state",
+  "errorMessage":"an error",
+  "lastUpdated":1473344752.000000000,
+  "attributes":{"att1":"rO0ABXQABXZhbHVl"},
+  "remoteAddr":"159.221.12.145",
+  "remoteHost":"toto.com",
+  "perRecipientHeaders":{
+    "recipient1@localhost":{"header":{"X-custom-header":["uedcgukrcg"]}},
+    "recipient2@localhost":{"header":{"X-custom-header-2":["uedcgukrcg"]}}},
+  "headerBlobId":"210e7136-ede3-44eb-9495-3ed816d6e23b",
+  "bodyBlobId":"ef46c026-7819-4048-b562-3a37469191ed"
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/f6f9961a/server/queue/queue-rabbitmq/src/test/resources/json/mail_min.json
----------------------------------------------------------------------
diff --git a/server/queue/queue-rabbitmq/src/test/resources/json/mail_min.json 
b/server/queue/queue-rabbitmq/src/test/resources/json/mail_min.json
new file mode 100644
index 0000000..b2b8eea
--- /dev/null
+++ b/server/queue/queue-rabbitmq/src/test/resources/json/mail_min.json
@@ -0,0 +1,14 @@
+{
+  "recipients":[],
+  "name":"mail-name-558",
+  "sender":null,
+  "state":null,
+  "errorMessage":null,
+  "lastUpdated":null,
+  "attributes":{},
+  "remoteAddr":"127.0.0.1",
+  "remoteHost":"localhost",
+  "perRecipientHeaders":{},
+  "headerBlobId":"210e7136-ede3-44eb-9495-3ed816d6e23b",
+  "bodyBlobId":"ef46c026-7819-4048-b562-3a37469191ed"
+}


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to