http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
new file mode 100644
index 0000000..258f264
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailetcontainer.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+
+<!--
+  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.
+ -->
+
+<mailetcontainer enableJmx="false">
+
+    <context>
+        <postmaster>postmas...@james.minet.net</postmaster>
+    </context>
+
+    <spooler>
+        <threads>20</threads>
+    </spooler>
+
+    <processors>
+        <processor state="root" enableJmx="false">
+            <mailet match="All" class="PostmasterAlias"/>
+            <mailet match="RelayLimit=30" class="Null"/>
+            <!-- Hook on sievemana...@james.linagora.com
+                 Mail send to this address will get interpreted with SIEVE 
Manage -->
+            <mailet match="All" class="ToProcessor">
+                <processor>transport</processor>
+            </mailet>
+        </processor>
+
+        <processor state="error" enableJmx="false">
+            <mailet match="All" class="Bounce"/>
+        </processor>
+
+
+        <processor state="transport" enableJmx="false">
+            <mailet match="SMTPAuthSuccessful" class="SetMimeHeader">
+                <name>X-UserIsAuth</name>
+                <value>true</value>
+            </mailet>
+            <mailet match="All" class="RemoveMimeHeader">
+                <name>bcc</name>
+            </mailet>
+            <mailet match="RecipientIsLocal" class="LocalDelivery"/>
+            <mailet match="HostIsLocal" class="ToProcessor">
+                <processor>local-address-error</processor>
+                <notice>550 - Requested action not taken: no such user 
here</notice>
+            </mailet>
+            <mailet match="SMTPAuthSuccessful" class="RemoteDelivery">
+                <outgoingQueue>outgoing</outgoingQueue>
+                <delayTime>5000, 100000, 500000</delayTime>
+                <maxRetries>25</maxRetries>
+                <maxDnsProblemRetries>0</maxDnsProblemRetries>
+                <deliveryThreads>10</deliveryThreads>
+                <sendpartial>true</sendpartial>
+                <bounceProcessor>bounces</bounceProcessor>
+            </mailet>
+            <mailet match="All" class="ToProcessor">
+                <processor>relay-denied</processor>
+            </mailet>
+        </processor>
+
+        <processor state="spam" enableJmx="false">
+            <mailet match="All" class="ToRepository">
+                <repositoryPath>file://var/mail/spam/</repositoryPath>
+            </mailet>
+        </processor>
+
+        <processor state="local-address-error" enableJmx="false">
+            <mailet match="All" class="Bounce">
+                <attachment>none</attachment>
+            </mailet>
+        </processor>
+
+        <processor state="relay-denied" enableJmx="false">
+            <mailet match="All" class="Bounce">
+                <attachment>none</attachment>
+            </mailet>
+        </processor>
+
+        <processor state="bounces" enableJmx="false">
+            <mailet match="All" class="DSNBounce">
+                <passThrough>false</passThrough>
+            </mailet>
+        </processor>
+
+    </processors>
+
+</mailetcontainer>
+
+

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailrepositorystore.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailrepositorystore.xml
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailrepositorystore.xml
new file mode 100644
index 0000000..3ca4a1d
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/mailrepositorystore.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!--
+  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.
+ -->
+
+<mailrepositorystore>
+    <mailrepositories>
+        <mailrepository 
class="org.apache.james.mailrepository.file.FileMailRepository">
+            <protocols>
+                <protocol>file</protocol>
+            </protocols>
+            <config FIFO="false" CACHEKEYS="true"/>
+        </mailrepository>
+    </mailrepositories>
+</mailrepositorystore>

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/pop3server.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/pop3server.xml
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/pop3server.xml
new file mode 100644
index 0000000..e4187da
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/pop3server.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<!--
+  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.                                           
+ -->
+
+
+<pop3servers>
+    <pop3server enabled="true">
+        <jmxName>pop3server</jmxName>
+        <bind>0.0.0.0:1110</bind>
+        <connectionBacklog>200</connectionBacklog>
+        <tls socketTLS="false" startTLS="false">
+            <!-- To create a new keystore execute:
+                  keytool -genkey -alias james -keyalg RSA -keystore 
/path/to/james/conf/keystore
+             -->
+            <keystore>file://conf/keystore</keystore>
+            <secret>james72laBalle</secret>
+            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
+        </tls>
+        <connectiontimeout>1200</connectiontimeout>
+        <connectionLimit>0</connectionLimit>
+        <connectionLimitPerIP>0</connectionLimitPerIP>
+        <handlerchain>
+            <handler 
class="org.apache.james.pop3server.core.CoreCmdHandlerLoader"/>
+        </handlerchain>
+    </pop3server>
+</pop3servers>

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/smtpserver.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/smtpserver.xml
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/smtpserver.xml
new file mode 100644
index 0000000..a3d4b8f
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/resources/smtpserver.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0"?>
+
+<!--
+  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.
+ -->
+
+<smtpservers>
+    <smtpserver enabled="true">
+        <jmxName>smtpserver-global</jmxName>
+        <bind>0.0.0.0:1025</bind>
+        <connectionBacklog>200</connectionBacklog>
+        <tls socketTLS="false" startTLS="false">
+            <keystore>file://conf/keystore</keystore>
+            <secret>james72laBalle</secret>
+            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
+            <algorithm>SunX509</algorithm>
+        </tls>
+        <connectiontimeout>360</connectiontimeout>
+        <connectionLimit>0</connectionLimit>
+        <connectionLimitPerIP>0</connectionLimitPerIP>
+        <authRequired>false</authRequired>
+        <authorizedAddresses>0.0.0.0/0</authorizedAddresses>
+        <verifyIdentity>true</verifyIdentity>
+        <maxmessagesize>0</maxmessagesize>
+        <addressBracketsEnforcement>true</addressBracketsEnforcement>
+        <smtpGreeting>JAMES Linagora's SMTP awesome Server</smtpGreeting>
+        <handlerchain>
+            <handler 
class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
+            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
+        </handlerchain>
+    </smtpserver>
+    <smtpserver enabled="true">
+        <jmxName>smtpserver-TLS</jmxName>
+        <bind>0.0.0.0:10465</bind>
+        <connectionBacklog>200</connectionBacklog>
+        <tls socketTLS="false" startTLS="false">
+            <keystore>file://conf/keystore</keystore>
+            <secret>james72laBalle</secret>
+            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
+            <algorithm>SunX509</algorithm>
+        </tls>
+        <connectiontimeout>360</connectiontimeout>
+        <connectionLimit>0</connectionLimit>
+        <connectionLimitPerIP>0</connectionLimitPerIP>
+        <!--
+           Authorize only local users
+        -->
+        <authRequired>true</authRequired>
+        <authorizedAddresses>0.0.0.0/0</authorizedAddresses>
+        <!-- Trust authenticated users -->
+        <verifyIdentity>false</verifyIdentity>
+        <maxmessagesize>0</maxmessagesize>
+        <addressBracketsEnforcement>true</addressBracketsEnforcement>
+        <smtpGreeting>JAMES Linagora's SMTP awesome Server</smtpGreeting>
+        <handlerchain>
+            <handler 
class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
+            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
+        </handlerchain>
+    </smtpserver>
+    <smtpserver enabled="true">
+        <jmxName>smtpserver-authenticated</jmxName>
+        <bind>0.0.0.0:1587</bind>
+        <connectionBacklog>200</connectionBacklog>
+        <tls socketTLS="false" startTLS="false">
+            <keystore>file://conf/keystore</keystore>
+            <secret>james72laBalle</secret>
+            
<provider>org.bouncycastle.jce.provider.BouncyCastleProvider</provider>
+            <algorithm>SunX509</algorithm>
+        </tls>
+        <connectiontimeout>360</connectiontimeout>
+        <connectionLimit>0</connectionLimit>
+        <connectionLimitPerIP>0</connectionLimitPerIP>
+        <!--
+           Authorize only local users
+        -->
+        <authRequired>true</authRequired>
+        <authorizedAddresses>0.0.0.0/0</authorizedAddresses>
+        <!-- Trust authenticated users -->
+        <verifyIdentity>false</verifyIdentity>
+        <maxmessagesize>0</maxmessagesize>
+        <addressBracketsEnforcement>true</addressBracketsEnforcement>
+        <smtpGreeting>JAMES Linagora's SMTP awesome Server</smtpGreeting>
+        <handlerchain>
+            <handler 
class="org.apache.james.smtpserver.fastfail.ValidRcptHandler"/>
+            <handler class="org.apache.james.smtpserver.CoreCmdHandlerLoader"/>
+        </handlerchain>
+    </smtpserver>
+</smtpservers>
+
+

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml
new file mode 100644
index 0000000..084c9e1
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/pom.xml
@@ -0,0 +1,241 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <artifactId>james-server</artifactId>
+        <groupId>org.apache.james</groupId>
+        <version>3.0.0-beta5-SNAPSHOT</version>
+        <relativePath>../../../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>james-server-jmap-integration-testing</artifactId>
+    <packaging>jar</packaging>
+
+    <name>Apache James :: Server :: JMAP :: Integration testing Common</name>
+
+    <profiles>
+        <profile>
+            <id>noTest</id>
+            <activation>
+                <os>
+                    <family>windows</family>
+                </os>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <skipTests>true</skipTests>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>disable-build-for-older-jdk</id>
+            <activation>
+                <jdk>(,1.8)</jdk>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-jar-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-jar</id>
+                                <phase>none</phase>
+                            </execution>
+                            <execution>
+                                <id>jar</id>
+                                <phase>none</phase>
+                            </execution>
+                            <execution>
+                                <id>test-jar</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-compile</id>
+                                <phase>none</phase>
+                            </execution>
+                            <execution>
+                                <id>default-testCompile</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-test</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-source-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>attach-sources</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-install-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-install</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>default-resources</id>
+                                <phase>none</phase>
+                            </execution>
+                            <execution>
+                                <id>default-testResources</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <artifactId>maven-site-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>attach-descriptor</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>build-for-jdk-8</id>
+            <activation>
+                <jdk>[1.8,)</jdk>
+            </activation>
+            <dependencies>
+                <dependency>
+                    <groupId>org.apache.james</groupId>
+                    <artifactId>james-server-guice-common</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.apache.james</groupId>
+                    <artifactId>james-server-guice-common</artifactId>
+                    <scope>test</scope>
+                    <type>test-jar</type>
+                </dependency>
+                <dependency>
+                    <groupId>com.google.guava</groupId>
+                    <artifactId>guava</artifactId>
+                    <version>18.0</version> <!--$NO-MVN-MAN-VER$-->
+                </dependency>
+                <dependency>
+                    <groupId>com.jayway.restassured</groupId>
+                    <artifactId>rest-assured</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.assertj</groupId>
+                    <artifactId>assertj-core</artifactId>
+                    <version>${assertj-3.version}</version>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.hamcrest</groupId>
+                    <artifactId>java-hamcrest</artifactId>
+                    <scope>test</scope>
+                </dependency>
+                <dependency>
+                    <groupId>org.testcontainers</groupId>
+                    <artifactId>testcontainers</artifactId>
+                    <version>1.0.2</version>
+                </dependency>
+            </dependencies>
+            <build>
+                <plugins>
+                    <plugin>
+                        <artifactId>maven-assembly-plugin</artifactId>
+                        <configuration>
+                            <archive>
+                                <manifest>
+                                    
<mainClass>fully.qualified.MainClass</mainClass>
+                                </manifest>
+                            </archive>
+                            <descriptorRefs>
+                                
<descriptorRef>jar-with-dependencies</descriptorRef>
+                            </descriptorRefs>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <configuration>
+                            <source>1.8</source>
+                            <target>1.8</target>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>disable-animal-sniffer</id>
+            <activation>
+                <jdk>[1.6,)</jdk>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>animal-sniffer-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>check_java_6</id>
+                                <phase>none</phase>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ContainerTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ContainerTest.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ContainerTest.java
new file mode 100644
index 0000000..d1c0bc4
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/ContainerTest.java
@@ -0,0 +1,45 @@
+/****************************************************************
+ * 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.jmap;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.apache.http.client.fluent.Request;
+import org.apache.http.client.fluent.Response;
+import org.apache.http.client.utils.URIBuilder;
+import org.junit.Rule;
+import org.junit.Test;
+import org.testcontainers.containers.GenericContainer;
+
+public class ContainerTest {
+
+    @Rule public GenericContainer container = new 
GenericContainer("nginx:1.7.1")
+            .withExposedPorts(80);
+
+    @Test
+    public void containerShouldBeReachableOnExposedPort() throws IOException, 
URISyntaxException {
+        String containerIpAddress = container.getContainerIpAddress();
+        Integer containerPort = container.getMappedPort(80);
+        Response response = Request.Get(new 
URIBuilder().setScheme("http").setHost(containerIpAddress).setPort(containerPort).build()).execute();
+        
assertThat(response.returnResponse().getStatusLine().getStatusCode()).isEqualTo(200);
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/FixedDateZonedDateTimeProvider.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/FixedDateZonedDateTimeProvider.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/FixedDateZonedDateTimeProvider.java
new file mode 100644
index 0000000..3dddcec
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/FixedDateZonedDateTimeProvider.java
@@ -0,0 +1,39 @@
+/****************************************************************
+ * 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.jmap;
+
+import java.time.ZonedDateTime;
+
+import org.apache.james.jmap.utils.ZonedDateTimeProvider;
+
+public class FixedDateZonedDateTimeProvider implements ZonedDateTimeProvider {
+
+    private ZonedDateTime zonedDateTime;
+
+    public void setFixedDateTime(ZonedDateTime zonedDateTime) {
+        this.zonedDateTime = zonedDateTime;
+    }
+
+    @Override
+    public ZonedDateTime get() {
+        return zonedDateTime;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
new file mode 100644
index 0000000..e7ad88b
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JMAPAuthenticationTest.java
@@ -0,0 +1,474 @@
+/****************************************************************
+ * 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.jmap;
+
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.RestAssured.with;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+
+import static org.hamcrest.Matchers.both;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.isA;
+import static org.hamcrest.Matchers.notNullValue;
+
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.UUID;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.jmap.model.ContinuationToken;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
+
+public abstract class JMAPAuthenticationTest {
+
+    private static final ZonedDateTime oldDate = 
ZonedDateTime.parse("2011-12-03T10:15:30+01:00", 
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+    private static final ZonedDateTime newDate = 
ZonedDateTime.parse("2011-12-03T10:16:30+01:00", 
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+    private static final ZonedDateTime afterExpirationDate = 
ZonedDateTime.parse("2011-12-03T10:30:31+01:00", 
DateTimeFormatter.ISO_OFFSET_DATE_TIME);
+
+    protected abstract GuiceJamesServer<?> 
createJmapServer(FixedDateZonedDateTimeProvider zonedDateTimeProvider);
+
+    private UserCredentials userCredentials;
+    private FixedDateZonedDateTimeProvider zonedDateTimeProvider;
+    private GuiceJamesServer<?> jmapServer;
+
+    @Before
+    public void setup() throws Throwable {
+        zonedDateTimeProvider = new FixedDateZonedDateTimeProvider();
+        zonedDateTimeProvider.setFixedDateTime(oldDate);
+        jmapServer = createJmapServer(zonedDateTimeProvider);
+        jmapServer.start();
+        RestAssured.port = jmapServer.getJmapPort();
+        RestAssured.config = 
newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8));
+
+        
+        userCredentials = UserCredentials.builder()
+                .username("u...@domain.tld")
+                .password("password")
+                .build();
+
+        
+        String domain = "domain.tld";
+        jmapServer.serverProbe().addDomain(domain);
+        jmapServer.serverProbe().addUser(userCredentials.getUsername(), 
userCredentials.getPassword());
+        
+    }
+    
+    @After
+    public void teardown() {
+        jmapServer.stop();
+    }
+
+    @Test
+    public void mustReturnMalformedRequestWhenContentTypeIsMissing() {
+        given()
+            .accept(ContentType.JSON)
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    @Test
+    public void mustReturnMalformedRequestWhenContentTypeIsNotJson() {
+        given()
+            .contentType(ContentType.XML)
+            .accept(ContentType.JSON)
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    @Test
+    public void mustReturnMalformedRequestWhenAcceptIsMissing() {
+        given()
+            .contentType(ContentType.JSON)
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    @Test
+    public void mustReturnMalformedRequestWhenAcceptIsNotJson() {
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.XML)
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    @Test
+    public void mustReturnMalformedRequestWhenCharsetIsNotUTF8() {
+        given()
+            .contentType("application/json; charset=ISO-8859-1")
+            .accept(ContentType.JSON)
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    @Test
+    public void mustReturnMalformedRequestWhenBodyIsEmpty() {
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    @Test
+    public void mustReturnMalformedRequestWhenBodyIsNotAcceptable() {
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"badAttributeName\": \"value\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(400);
+    }
+
+    @Test
+    public void mustReturnJsonResponse() throws Exception {
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"username\": \"" + userCredentials.getUsername() + "\", 
\"clientName\": \"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", 
\"deviceName\": \"Joe Blogg’s iPhone\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(200)
+            .contentType(ContentType.JSON);
+    }
+
+    @Test
+    public void methodShouldContainPasswordWhenValidResquest() throws 
Exception {
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"username\": \"" + userCredentials.getUsername() + "\", 
\"clientName\": \"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", 
\"deviceName\": \"Joe Blogg’s iPhone\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(200)
+            .body("methods", hasItem(userCredentials.getPassword()));
+    }
+
+    @Test
+    public void mustReturnContinuationTokenWhenValidResquest() throws 
Exception {
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"username\": \"" + userCredentials.getUsername() + "\", 
\"clientName\": \"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", 
\"deviceName\": \"Joe Blogg’s iPhone\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(200)
+            .body("continuationToken", isA(String.class));
+    }
+
+    @Test
+    public void mustReturnAuthenticationFailedWhenBadPassword() throws 
Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"token\": \"" + continuationToken + "\", \"method\": 
\"password\", \"password\": \"badpassword\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void 
mustReturnAuthenticationFailedWhenContinuationTokenIsRejectedByTheContinuationTokenManager()
 throws Exception {
+        ContinuationToken badContinuationToken = new 
ContinuationToken(userCredentials.getUsername(), newDate, "badSignature");
+
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"token\": \"" + badContinuationToken.serialize() + "\", 
\"method\": \"password\", \"password\": \"" + userCredentials.getPassword() + 
"\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void 
mustReturnRestartAuthenticationWhenContinuationTokenIsExpired() throws 
Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+        zonedDateTimeProvider.setFixedDateTime(afterExpirationDate);
+
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"token\": \"" + continuationToken + "\", \"method\": 
\"password\", \"password\": \"" + userCredentials.getPassword() + "\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(403);
+    }
+
+    @Test
+    public void mustReturnAuthenticationFailedWhenUsersRepositoryException() 
throws Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"token\": \"" + continuationToken + "\", \"method\": 
\"password\", \"password\": \"" + "wrong password" + "\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void mustReturnCreatedWhenGoodPassword() throws Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+        zonedDateTimeProvider.setFixedDateTime(newDate);
+
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"token\": \"" + continuationToken + "\", \"method\": 
\"password\", \"password\": \"" + userCredentials.getPassword() + "\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .statusCode(201);
+    }
+
+    @Test
+    public void 
mustSendJsonContainingAccessTokenAndEndpointsWhenGoodPassword() throws 
Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+        zonedDateTimeProvider.setFixedDateTime(newDate);
+
+        given()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"token\": \"" + continuationToken + "\", \"method\": 
\"password\", \"password\": \"" + userCredentials.getPassword() + "\"}")
+        .when()
+            .post("/authentication")
+        .then()
+            .body("accessToken", isA(String.class))
+            .body("api", equalTo("/jmap"))
+            .body("eventSource", both(isA(String.class)).and(notNullValue()))
+            .body("upload", both(isA(String.class)).and(notNullValue()))
+            .body("download", both(isA(String.class)).and(notNullValue()));
+    }
+    
+    @Test
+    public void getMustReturnUnauthorizedWithoutAuthroizationHeader() throws 
Exception {
+        given()
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void getMustReturnUnauthorizedWithoutAValidAuthroizationHeader() 
throws Exception {
+        given()
+            .header("Authorization", UUID.randomUUID())
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void getMustReturnEndpointsWhenValidAuthorizationHeader() throws 
Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+        String token = fromGoodAccessTokenRequest(continuationToken);
+
+        given()
+            .header("Authorization", token)
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(200)
+            .body("api", equalTo("/jmap"))
+            .body("eventSource", both(isA(String.class)).and(notNullValue()))
+            .body("upload", both(isA(String.class)).and(notNullValue()))
+            .body("download", both(isA(String.class)).and(notNullValue()));
+    }
+
+    @Test
+    public void getMustReturnEndpointsWhenValidJwtAuthorizationHeader() throws 
Exception {
+        String token = 
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.T04BTk"
 +
+                
"LXkJj24coSZkK13RfG25lpvmSl2MJ7N10KpBk9_-95EGYZdog-BDAn3PJzqVw52z-Bwjh4VOj1-j7cURu0cT4jXehhUrlCxS4n7QHZ"
 +
+                
"DN_bsEYGu7KzjWTpTsUiHe-rN7izXVFxDGG1TGwlmBCBnPW-EFCf9ylUsJi0r2BKNdaaPRfMIrHptH1zJBkkUziWpBN1RNLjmvlAUf"
 +
+                
"49t1Tbv21ZqYM5Ht2vrhJWczFbuC-TD-8zJkXhjTmA1GVgomIX5dx1cH-dZX1wANNmshUJGHgepWlPU-5VIYxPEhb219RMLJIELMY2"
 +
+                "qNOR8Q31ydinyqzXvCSzVJOf6T60-w";
+
+        given()
+                .header("Authorization", "Bearer " + token)
+                .when()
+                .get("/authentication")
+                .then()
+                .statusCode(200);
+    }
+
+    @Test
+    public void 
getMustReturnEndpointsWhenValidUnkwnonUserJwtAuthorizationHeader() throws 
Exception {
+        String token = 
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMzM3IiwibmFtZSI6Ik5ldyBVc2VyIn0.ci8U04EOWKpi_y"
+                + 
"faKs8fnCBcu1mWs8fvf-t9SDP2kkvDDfD-ya4sEGn4ueCp2dA2ndefZfVu_IfvdlVtxqzSf0tQ-dFKrIe-OtSKhI2otjWctLtk9A"
+                + 
"G7jpWkXoDgr5IOVmsqg37Zxc2bgkLkC5FJqV6oCp51TNQTH6zZbXIUeuGFbHj2-iJeX8sACKTQB0llwc6TFm7GYUF03rv4DfJjqp"
+                + 
"Kd0g8RdnlevSOjV-gGzvKEItugtexS5pgOZ2GYcvqEUDb9EnQR7Qe2EzPAX_FCJfGhlv7bDQlTgOHHAjqw2lD4-zeAznw-3wlYLS"
+                + "zhi4ivvPjT-y2T5wnnhzeeYOpYOQ";
+        
+        given()
+            .header("Authorization", "Bearer " + token)
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(200);
+    }
+    
+    @Test
+    public void getMustReturnBadCredentialsWhenInvalidJwtAuthorizationHeader() 
throws Exception {
+        String token = 
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.T04BTk"
 +
+                
"LXkJj24coSZkK13RfG25lpvmSl2MJ7N10KpBk9_-95EGYZdog-BDAn3PJzqVw52z-Bwjh4VOj1-j7cURu0cT4jXehhUrlCxS4n7QHZ"
 +
+                
"EN_bsEYGu7KzjWTpTsUiHe-rN7izXVFxDGG1TGwlmBCBnPW-EFCf9ylUsJi0r2BKNdaaPRfMIrHptH1zJBkkUziWpBN1RNLjmvlAUf"
 +
+                
"49t1Tbv21ZqYM5Ht2vrhJWczFbuC-TD-8zJkXhjTmA1GVgomIX5dx1cH-dZX1wANNmshUJGHgepWlPU-5VIYxPEhb219RMLJIELMY2"
 +
+                "qNOR8Q31ydinyqzXvCSzVJOf6T60-w";
+
+        given()
+                .header("Authorization", "Bearer " + token)
+                .when()
+                .get("/authentication")
+                .then()
+                .statusCode(401);
+    }
+
+    @Test
+    public void optionsRequestsShouldNeverRequireAuthentication() {
+        given()
+                .when()
+                .options("/authentication")
+                .then()
+                .statusCode(200);
+    }
+
+    @Test
+    public void getMustReturnEndpointsWhenCorrectAuthentication() throws 
Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+        zonedDateTimeProvider.setFixedDateTime(newDate);
+    
+        String accessToken = fromGoodAccessTokenRequest(continuationToken);
+    
+        given()
+            .header("Authorization", accessToken)
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(200)
+            .body("api", isA(String.class));
+    }
+    
+    @Test
+    public void deleteMustReturnUnauthenticatedWithoutAuthorizationHeader() 
throws Exception {
+        given()
+        .when()
+            .delete("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void 
deleteMustReturnUnauthenticatedWithoutAValidAuthroizationHeader() throws 
Exception {
+        given()
+            .header("Authorization", UUID.randomUUID())
+        .when()
+            .delete("/authentication")
+        .then()
+            .statusCode(401);
+    }
+    
+    @Test
+    public void deleteMustReturnOKNoContentOnValidAuthorizationToken() throws 
Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+        String token = fromGoodAccessTokenRequest(continuationToken);
+        given()
+            .header("Authorization", token)
+        .when()
+            .delete("/authentication")
+        .then()
+            .statusCode(204);
+    }
+
+    @Test
+    public void deleteMustInvalidAuthorizationOnCorrectAuthorization() throws 
Exception {
+        String continuationToken = fromGoodContinuationTokenRequest();
+        zonedDateTimeProvider.setFixedDateTime(newDate);
+    
+        String accessToken = fromGoodAccessTokenRequest(continuationToken);
+        
+        goodDeleteAccessTokenRequest(accessToken);
+    
+        given()
+            .header("Authorization", accessToken)
+        .when()
+            .get("/authentication")
+        .then()
+            .statusCode(401);
+    }
+
+    private String fromGoodContinuationTokenRequest() {
+        return with()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"username\": \"" + userCredentials.getUsername() + "\", 
\"clientName\": \"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", 
\"deviceName\": \"Joe Blogg’s iPhone\"}")
+        .post("/authentication")
+            .body()
+            .path("continuationToken")
+            .toString();
+    }
+
+    private String fromGoodAccessTokenRequest(String continuationToken) {
+        return with()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"token\": \"" + continuationToken + "\", \"method\": 
\"password\", \"password\": \"" + userCredentials.getPassword() + "\"}")
+        .post("/authentication")
+            .path("accessToken")
+            .toString();
+    }
+
+    private void goodDeleteAccessTokenRequest(String accessToken) {
+        with()
+            .header("Authorization", accessToken)
+            .delete("/authentication");
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapAuthentication.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapAuthentication.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapAuthentication.java
new file mode 100644
index 0000000..b9fa503
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/JmapAuthentication.java
@@ -0,0 +1,55 @@
+/****************************************************************
+ * 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.jmap;
+
+import static com.jayway.restassured.RestAssured.with;
+
+import org.apache.james.jmap.api.access.AccessToken;
+
+import com.jayway.restassured.http.ContentType;
+
+public class JmapAuthentication {
+
+    public static AccessToken authenticateJamesUser(String username, String 
password) {
+        String continuationToken = getContinuationToken(username);
+
+        return AccessToken.fromString(
+            with()
+                .contentType(ContentType.JSON)
+                .accept(ContentType.JSON)
+                .body("{\"token\": \"" + continuationToken + "\", \"method\": 
\"password\", \"password\": \"" + password + "\"}")
+            .post("/authentication")
+                .body()
+                .jsonPath()
+                .getString("accessToken")
+        );
+    }
+
+    private static String getContinuationToken(String username) {
+        return with()
+            .contentType(ContentType.JSON)
+            .accept(ContentType.JSON)
+            .body("{\"username\": \"" + username + "\", \"clientName\": 
\"Mozilla Thunderbird\", \"clientVersion\": \"42.0\", \"deviceName\": \"Joe 
Blogg’s iPhone\"}")
+        .post("/authentication")
+            .body()
+            .path("continuationToken")
+            .toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/UserCredentials.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/UserCredentials.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/UserCredentials.java
new file mode 100644
index 0000000..25a1994
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/UserCredentials.java
@@ -0,0 +1,66 @@
+/****************************************************************
+ * 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.jmap;
+
+public class UserCredentials {
+
+    public static Builder builder() {
+        return new Builder();
+    }
+    
+    public static class Builder {
+        
+        private String username;
+        private String password;
+        
+        private Builder() {
+        }
+        
+        public Builder username(String username) {
+            this.username = username;
+            return this;
+        }
+        
+        public Builder password(String password) {
+            this.password = password;
+            return this;
+        }
+        
+        public UserCredentials build() {
+            return new UserCredentials(username, password);
+        }
+    }
+
+    private final String username;
+    private final String password;
+
+    private UserCredentials(String username, String password) {
+        this.username = username;
+        this.password = password;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public String getPassword() {
+        return password;
+    }
+}

http://git-wip-us.apache.org/repos/asf/james-project/blob/517a4cfe/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java
new file mode 100644
index 0000000..dfafe9f
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetMailboxesMethodTest.java
@@ -0,0 +1,421 @@
+/****************************************************************
+ * 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.jmap.methods.integration;
+
+import static com.jayway.restassured.RestAssured.given;
+import static com.jayway.restassured.config.EncoderConfig.encoderConfig;
+import static com.jayway.restassured.config.RestAssuredConfig.newConfig;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.isEmptyOrNullString;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.nullValue;
+
+import java.io.ByteArrayInputStream;
+import java.util.Date;
+
+import javax.mail.Flags;
+
+import org.apache.james.GuiceJamesServer;
+import org.apache.james.jmap.JmapAuthentication;
+import org.apache.james.jmap.api.access.AccessToken;
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxPath;
+import org.apache.james.mailbox.store.mail.model.Mailbox;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.common.base.Charsets;
+import com.jayway.restassured.RestAssured;
+import com.jayway.restassured.http.ContentType;
+
+public abstract class GetMailboxesMethodTest {
+    private static final String NAME = "[0][0]";
+    private static final String ARGUMENTS = "[0][1]";
+
+    protected abstract GuiceJamesServer<?> createJmapServer();
+
+    private AccessToken accessToken;
+    private String username;
+    private GuiceJamesServer<?> jmapServer;
+
+    @Before
+    public void setup() throws Throwable {
+        jmapServer = createJmapServer();
+        jmapServer.start();
+        RestAssured.port = jmapServer.getJmapPort();
+        RestAssured.config = 
newConfig().encoderConfig(encoderConfig().defaultContentCharset(Charsets.UTF_8));
+
+        String domain = "domain.tld";
+        username = "username@" + domain;
+        String password = "password";
+        jmapServer.serverProbe().addDomain(domain);
+        jmapServer.serverProbe().addUser(username, password);
+        accessToken = JmapAuthentication.authenticateJamesUser(username, 
password);
+    }
+
+    @After
+    public void teardown() {
+        jmapServer.stop();
+    }
+    
+    @Test
+    public void 
getMailboxesShouldErrorNotSupportedWhenRequestContainsNonNullAccountId() throws 
Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"accountId\": \"1\"}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("error"))
+            .body(ARGUMENTS + ".type", equalTo("Not yet implemented"));
+    }
+
+    @Test
+    public void getMailboxesShouldReturnEmptyWhenIdsDoesntMatch() throws 
Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "name");
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"ids\": [\"notAMailboxId\"]}, 
\"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", hasSize(0));
+    }
+
+    @Test
+    public void getMailboxesShouldReturnMailboxesWhenIdsMatch() throws 
Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "INBOX");
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "myMailbox");
+
+        Mailbox<?> mailbox = 
jmapServer.serverProbe().getMailbox(MailboxConstants.USER_NAMESPACE, username, 
"INBOX");
+        Mailbox<?> mailbox2 = 
jmapServer.serverProbe().getMailbox(MailboxConstants.USER_NAMESPACE, username, 
"myMailbox");
+
+        String mailboxId = mailbox.getMailboxId().serialize();
+        String mailboxId2 = mailbox2.getMailboxId().serialize();
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"ids\": [\"" + mailboxId + "\", \"" + 
mailboxId2 + "\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", hasSize(2))
+            .body(ARGUMENTS + ".list[0].id", equalTo(mailboxId))
+            .body(ARGUMENTS + ".list[1].id", equalTo(mailboxId2));
+    }
+
+    @Test
+    public void getMailboxesShouldReturnOnlyMatchingMailboxesWhenIdsGiven() 
throws Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "INBOX");
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "myMailbox");
+
+        Mailbox<?> mailbox = 
jmapServer.serverProbe().getMailbox(MailboxConstants.USER_NAMESPACE, username, 
"INBOX");
+
+        String mailboxId = mailbox.getMailboxId().serialize();
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"ids\": [\"" + mailboxId + "\"]}, 
\"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", hasSize(1))
+            .body(ARGUMENTS + ".list[0].id", equalTo(mailboxId));
+    }
+
+    @Test
+    public void getMailboxesShouldReturnEmptyWhenIdsIsEmpty() throws Exception 
{
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "INBOX");
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"ids\": []}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", empty());
+    }
+
+    @Test
+    public void getMailboxesShouldReturnAllMailboxesWhenIdsIsNull() throws 
Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "INBOX");
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "myMailbox");
+
+        Mailbox<?> mailbox = 
jmapServer.serverProbe().getMailbox(MailboxConstants.USER_NAMESPACE, username, 
"INBOX");
+        Mailbox<?> mailbox2 = 
jmapServer.serverProbe().getMailbox(MailboxConstants.USER_NAMESPACE, username, 
"myMailbox");
+
+        String mailboxId = mailbox.getMailboxId().serialize();
+        String mailboxId2 = mailbox2.getMailboxId().serialize();
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"ids\": null}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", hasSize(2))
+            .body(ARGUMENTS + ".list[0].id", equalTo(mailboxId))
+            .body(ARGUMENTS + ".list[1].id", equalTo(mailboxId2));
+    }
+    
+    @Test
+    public void getMailboxesShouldErrorInvalidArgumentsWhenRequestIsInvalid() 
throws Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"ids\": true}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("error"))
+            .body(ARGUMENTS + ".type", equalTo("invalidArguments"))
+            .body(ARGUMENTS + ".description", equalTo("Can not deserialize 
instance of java.util.ArrayList out of VALUE_TRUE token\n"
+                    + " at [Source: {\"ids\":true}; line: 1, column: 2] 
(through reference chain: org.apache.james.jmap.model.Builder[\"ids\"])"));
+    }
+
+    @Test
+    public void getMailboxesShouldReturnEmptyListWhenNoMailboxes() throws 
Exception {
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", empty());
+    }
+
+    @Test
+    public void 
getMailboxesShouldReturnDefaultMailboxesWhenAuthenticatedUserDoesntHaveAnAccountYet()
 throws Exception {
+
+        String token = 
"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMzM3QGRvbWFpbi50bGQiLCJuYW1lIjoiTmV3IFVzZXIif"
+                + 
"Q.fxNWNzksXyCij2ooVi-QfGe9vTicF2N9FDtWSJdjWTjhwoQ_i0dgiT8clp4dtOJzy78hB2UkAW-iq7z3PR_Gz0qFah7EbYoEs"
+                + 
"5lQs1UlhNGCRTvIsyR8qHUXtA6emw9x0nuMnswtyXhzoA-cEHCArrMxMeWhTYi2l4od3G8Irrvu1Yc5hKLwLgPdnImbKyB5a89T"
+                + 
"vzuZE8-FVyMmhlaJA2T1GpbsaUnfE1ki_bBzqMHTD_Ob7oSVzz2UOiOeL-ombn1X9GbYQ2I-Ob4V84WHONYxw0VjPHlj9saZ2n7"
+                + "2RJTBsIo6flJT-MchaEvTYBvuV_wlCCQYjI1g7mdeD6aXfw";
+        
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", "Bearer " + token)
+            .body("[[\"getMailboxes\", {}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", hasSize(3))
+            .body(ARGUMENTS + ".list.name", hasItems("INBOX", "Outbox", 
"Sent"));
+    }
+
+    @Test
+    public void getMailboxesShouldErrorWithBadJWTToken() {
+
+        String badAuthToken = 
"BADTOKENOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIn0.T04BTk"
 +
+                
"LXkJj24coSZkK13RfG25lpvmSl2MJ7N10KpBk9_-95EGYZdog-BDAn3PJzqVw52z-Bwjh4VOj1-j7cURu0cT4jXehhUrlCxS4n7QHZ"
 +
+                
"DN_bsEYGu7KzjWTpTsUiHe-rN7izXVFxDGG1TGwlmBCBnPW-EFCf9ylUsJi0r2BKNdaaPRfMIrHptH1zJBkkUziWpBN1RNLjmvlAUf"
 +
+                
"49t1Tbv21ZqYM5Ht2vrhJWczFbuC-TD-8zJkXhjTmA1GVgomIX5dx1cH-dZX1wANNmshUJGHgepWlPU-5VIYxPEhb219RMLJIELMY2"
 +
+                "qNOR8Q31ydinyqzXvCSzVJOf6T60-w";
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", "Bearer " + badAuthToken)
+            .body("[[\"getMailboxes\", {}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(401);
+    }
+
+    @Test
+    public void getMailboxesShouldReturnMailboxesWhenAvailable() throws 
Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "name");
+
+        jmapServer.serverProbe().appendMessage(username, new 
MailboxPath(MailboxConstants.USER_NAMESPACE, username, "name"),
+                new ByteArrayInputStream("Subject: 
test\r\n\r\ntestmail".getBytes()), new Date(), false, new Flags());
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list[0].name", equalTo("name"))
+            .body(ARGUMENTS + ".list[0].parentId", nullValue())
+            .body(ARGUMENTS + ".list[0].role", nullValue())
+            .body(ARGUMENTS + ".list[0].sortOrder", equalTo(1000))
+            .body(ARGUMENTS + ".list[0].mustBeOnlyMailbox", equalTo(false))
+            .body(ARGUMENTS + ".list[0].mayReadItems", equalTo(false))
+            .body(ARGUMENTS + ".list[0].mayAddItems", equalTo(false))
+            .body(ARGUMENTS + ".list[0].mayRemoveItems", equalTo(false))
+            .body(ARGUMENTS + ".list[0].mayCreateChild", equalTo(false))
+            .body(ARGUMENTS + ".list[0].mayRename", equalTo(false))
+            .body(ARGUMENTS + ".list[0].mayDelete", equalTo(false))
+            .body(ARGUMENTS + ".list[0].totalMessages", equalTo(1))
+            .body(ARGUMENTS + ".list[0].unreadMessages", equalTo(1))
+            .body(ARGUMENTS + ".list[0].unreadThreads", equalTo(0));
+    }
+
+    @Test
+    public void 
getMailboxesShouldReturnFilteredMailboxesPropertiesWhenRequestContainsFilterProperties()
 throws Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "name");
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"properties\" : [\"unreadMessages\", 
\"sortOrder\"]}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list[0].id", not(isEmptyOrNullString()))
+            .body(ARGUMENTS + ".list[0].name", nullValue())
+            .body(ARGUMENTS + ".list[0].parentId", nullValue())
+            .body(ARGUMENTS + ".list[0].role", nullValue())
+            .body(ARGUMENTS + ".list[0].sortOrder", equalTo(1000))
+            .body(ARGUMENTS + ".list[0].mustBeOnlyMailbox", nullValue())
+            .body(ARGUMENTS + ".list[0].mayReadItems", nullValue())
+            .body(ARGUMENTS + ".list[0].mayAddItems", nullValue())
+            .body(ARGUMENTS + ".list[0].mayRemoveItems", nullValue())
+            .body(ARGUMENTS + ".list[0].mayCreateChild", nullValue())
+            .body(ARGUMENTS + ".list[0].mayRename", nullValue())
+            .body(ARGUMENTS + ".list[0].mayDelete", nullValue())
+            .body(ARGUMENTS + ".list[0].totalMessages", nullValue())
+            .body(ARGUMENTS + ".list[0].unreadMessages", equalTo(0))
+            .body(ARGUMENTS + ".list[0].unreadThreads", nullValue());
+    }
+
+    @Test
+    public void 
getMailboxesShouldReturnIdWhenRequestContainsEmptyPropertyListFilter() throws 
Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "name");
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"properties\" : []}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list[0].id", not(isEmptyOrNullString()))
+            .body(ARGUMENTS + ".list[0].name", nullValue());
+    }
+
+    @Test
+    public void 
getMailboxesShouldIgnoreUnknownPropertiesWhenRequestContainsUnknownPropertyListFilter()
 throws Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "name");
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {\"properties\" : [\"unknown\"]}, 
\"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list[0].id", not(isEmptyOrNullString()))
+            .body(ARGUMENTS + ".list[0].name", nullValue());
+    }
+
+    @Test
+    public void getMailboxesShouldReturnMailboxesWithSortOrder() throws 
Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "inbox");
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "trash");
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", hasSize(2))
+            .body(ARGUMENTS + ".list[0].name", equalTo("inbox"))
+            .body(ARGUMENTS + ".list[0].sortOrder", equalTo(10))
+            .body(ARGUMENTS + ".list[1].name", equalTo("trash"))
+            .body(ARGUMENTS + ".list[1].sortOrder", equalTo(60));
+    }
+
+    @Test
+    public void getMailboxesShouldReturnMailboxesWithRolesInLowerCase() throws 
Exception {
+        
jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE, 
username, "outbox");
+
+        given()
+            .accept(ContentType.JSON)
+            .contentType(ContentType.JSON)
+            .header("Authorization", accessToken.serialize())
+            .body("[[\"getMailboxes\", {}, \"#0\"]]")
+        .when()
+            .post("/jmap")
+        .then()
+            .statusCode(200)
+            .body(NAME, equalTo("mailboxes"))
+            .body(ARGUMENTS + ".list", hasSize(1))
+            .body(ARGUMENTS + ".list[0].role", equalTo("outbox"));
+    }
+
+}


---------------------------------------------------------------------
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