Repository: james-project
Updated Branches:
  refs/heads/master 74fd6c223 -> 81d88bf73


JAMES-1742 Retrieve attachment in download endpoint


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

Branch: refs/heads/master
Commit: 81d88bf73d655e698afb7ba436649a5d273a03ab
Parents: 4df388b
Author: Antoine Duprat <adup...@linagora.com>
Authored: Wed Jun 1 12:46:37 2016 +0200
Committer: Antoine Duprat <adup...@linagora.com>
Committed: Mon Jun 6 13:05:37 2016 +0200

----------------------------------------------------------------------
 .../inmemory/mail/InMemoryAttachmentMapper.java |  3 ++
 .../cucumber/CassandraDownloadCucumberTest.java |  2 +-
 .../cassandra/cucumber/CassandraStepdefs.java   | 21 +++++---
 .../integration/cucumber/DownloadStepdefs.java  | 53 ++++++++++++++++--
 .../resources/cucumber/DownloadEndpoint.feature |  6 +--
 .../test/resources/cucumber/DownloadGet.feature | 16 ++++++
 .../src/test/resources/eml/oneAttachment.eml    | 38 +++++++++++++
 .../cucumber/MemoryDownloadCucumberTest.java    |  2 +-
 .../org/apache/james/jmap/DownloadServlet.java  | 48 +++++++++++++++++
 .../apache/james/jmap/DownloadServletTest.java  | 57 ++++++++++++++++++++
 10 files changed, 229 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
----------------------------------------------------------------------
diff --git 
a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
 
b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
index d4decc9..126fc61 100644
--- 
a/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
+++ 
b/mailbox/memory/src/main/java/org/apache/james/mailbox/inmemory/mail/InMemoryAttachmentMapper.java
@@ -39,6 +39,9 @@ public class InMemoryAttachmentMapper implements 
AttachmentMapper {
 
     @Override
     public Attachment getAttachment(AttachmentId attachmentId) throws 
AttachmentNotFoundException {
+        if (!attachmentsById.containsKey(attachmentId)) {
+            throw new AttachmentNotFoundException(attachmentId.getId());
+        }
         return attachmentsById.get(attachmentId);
     }
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java
index 1ad24f8..428d9df 100644
--- 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraDownloadCucumberTest.java
@@ -25,7 +25,7 @@ import cucumber.api.CucumberOptions;
 import cucumber.api.junit.Cucumber;
 
 @RunWith(Cucumber.class)
-@CucumberOptions(features="classpath:cucumber/DownloadEndpoint.feature",
+@CucumberOptions(features={"classpath:cucumber/DownloadEndpoint.feature", 
"classpath:cucumber/DownloadGet.feature"},
                 glue={"org.apache.james.jmap.methods.integration", 
"org.apache.james.jmap.cassandra.cucumber"})
 public class CassandraDownloadCucumberTest {
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java
 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java
index fa2f77a..0ba38d1 100644
--- 
a/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java
+++ 
b/server/protocols/jmap-integration-testing/cassandra-jmap-integration-testing/src/test/java/org/apache/james/jmap/cassandra/cucumber/CassandraStepdefs.java
@@ -19,6 +19,8 @@
 
 package org.apache.james.jmap.cassandra.cucumber;
 
+import java.util.Arrays;
+
 import javax.inject.Inject;
 
 import org.apache.james.CassandraJamesServerMain;
@@ -29,6 +31,8 @@ import 
org.apache.james.mailbox.elasticsearch.EmbeddedElasticSearch;
 import org.apache.james.modules.CassandraJmapServerModule;
 import org.junit.rules.TemporaryFolder;
 
+import com.github.fge.lambdas.runnable.ThrowingRunnable;
+
 import cucumber.api.java.After;
 import cucumber.api.java.Before;
 import cucumber.runtime.java.guice.ScenarioScoped;
@@ -59,16 +63,21 @@ public class CassandraStepdefs {
 
     @After
     public void tearDown() {
-        tearDown(() -> mainStepdefs.tearDown());
-        tearDown(() -> embeddedElasticSearch.after());
-        tearDown(() -> temporaryFolder.delete());
+        ignoreFailures(() -> mainStepdefs.tearDown(),
+                () -> embeddedElasticSearch.after(),
+                () -> temporaryFolder.delete());
     }
 
-    private void tearDown(Runnable cleaningFunction) {
+    private void ignoreFailures(ThrowingRunnable... cleaners) {
+        Arrays.stream(cleaners)
+            .forEach(this::runSwallowingException);
+    }
+    
+    private void runSwallowingException(Runnable run) {
         try {
-            cleaningFunction.run();
+            run.run();
         } catch (Exception e) {
-            e.printStackTrace();
+            // ignore
         }
     }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
index e703f23..8b0ce48 100644
--- 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/cucumber/DownloadStepdefs.java
@@ -20,8 +20,16 @@
 package org.apache.james.jmap.methods.integration.cucumber;
 
 import static com.jayway.restassured.RestAssured.with;
+import static org.hamcrest.Matchers.not;
+import static org.hamcrest.Matchers.notNullValue;
+
+import java.util.Date;
 
 import javax.inject.Inject;
+import javax.mail.Flags;
+
+import org.apache.james.mailbox.model.MailboxConstants;
+import org.apache.james.mailbox.model.MailboxPath;
 
 import com.jayway.restassured.http.ContentType;
 import com.jayway.restassured.response.Response;
@@ -45,9 +53,13 @@ public class DownloadStepdefs {
         this.userStepdefs = userStepdefs;
     }
 
-    @Given("^an unknown current user with username \"([^\"]*)\" and password 
\"([^\"]*)\"$")
-    public void createUserWithPassword(String username, String password) 
throws Exception {
-        mainStepdefs.jmapServer.serverProbe().addUser(username, password);
+    @Given("^a message containing an attachment$")
+    public void appendMessageWithAttachment() throws Exception {
+        
mainStepdefs.jmapServer.serverProbe().createMailbox(MailboxConstants.USER_NAMESPACE,
 userStepdefs.username, "INBOX");
+        MailboxPath mailboxPath = new 
MailboxPath(MailboxConstants.USER_NAMESPACE, userStepdefs.username, "INBOX");
+
+        
mainStepdefs.jmapServer.serverProbe().appendMessage(userStepdefs.username, 
mailboxPath,
+                
ClassLoader.getSystemResourceAsStream("eml/oneAttachment.eml"), new Date(), 
false, new Flags());
     }
 
     @When("^checking for the availability of the attachment endpoint$")
@@ -85,10 +97,28 @@ public class DownloadStepdefs {
             .get("/download/");
     }
 
+    @When("^getting the attachment with its correct blobId$")
+    public void getDownloadWithKnownBlobId() throws Throwable {
+        response = with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", userStepdefs.accessToken.serialize())
+                .get("/download/4000c5145f633410b80be368c44e1c394bff9437");
+    }
+
+    @When("^getting the attachment with an unknown blobId$")
+    public void getDownloadWithUnknownBlobId() throws Throwable {
+        response = with()
+                .accept(ContentType.JSON)
+                .contentType(ContentType.JSON)
+                .header("Authorization", userStepdefs.accessToken.serialize())
+                .get("/download/badbadbadbadbadbadbadbadbadbadbadbadbadb");
+    }
+
     @Then("^the user should be authorized$")
-    public void httpOkStatus() throws Exception {
+    public void httpStatusDifferentFromUnauthorized() throws Exception {
         response.then()
-            .statusCode(200);
+            .statusCode(not(401));
     }
 
     @Then("^the user should not be authorized$")
@@ -102,4 +132,17 @@ public class DownloadStepdefs {
         response.then()
             .statusCode(400);
     }
+
+    @Then("^the user should receive that attachment$")
+    public void httpOkStatusAndExpectedContent() throws Throwable {
+        response.then()
+            .statusCode(200)
+            .content(notNullValue());
+    }
+
+    @Then("^the user should receive a not found response$")
+    public void httpNotFoundStatus() throws Throwable {
+        response.then()
+            .statusCode(404);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
index a483d8e..b5f9d3b 100644
--- 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadEndpoint.feature
@@ -10,8 +10,7 @@ Feature: Download endpoint
     When checking for the availability of the attachment endpoint
     Then the user should be authorized
 
-  Scenario: An unknown user should initiate the access to the download endpoint
-    Given an unknown current user with username "unkn...@domain.tld" and 
password "secret"
+  Scenario: An unauthenticated user should initiate the access to the download 
endpoint
     When checking for the availability of the attachment endpoint
     Then the user should be authorized
 
@@ -20,8 +19,7 @@ Feature: Download endpoint
     When asking for an attachment
     Then the user should be authorized
 
-  Scenario: An unknown user should not have access to the download endpoint
-    Given an unknown current user with username "unkn...@domain.tld" and 
password "secret"
+  Scenario: An unauthenticated user should not have access to the download 
endpoint
     When asking for an attachment
     Then the user should not be authorized
 

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
new file mode 100644
index 0000000..cd92d8a
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/cucumber/DownloadGet.feature
@@ -0,0 +1,16 @@
+Feature: Download GET
+  As a James user
+  I want to retrieve my attachments
+
+  Background:
+    Given a domain named "domain.tld"
+    And a current user with username "usern...@domain.tld" and password 
"secret"
+
+  Scenario: Getting an attachment previously stored
+    Given a message containing an attachment
+    When getting the attachment with its correct blobId
+    Then the user should receive that attachment
+
+  Scenario: Getting an attachment with an unknown blobId
+    When getting the attachment with an unknown blobId
+    Then the user should receive a not found response

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment.eml
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment.eml
 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment.eml
new file mode 100644
index 0000000..ca0abe7
--- /dev/null
+++ 
b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/resources/eml/oneAttachment.eml
@@ -0,0 +1,38 @@
+Mail content:
+To: "=?utf-8?B?UmFuaSBBc3NhZg==?=" <rani.as...@jri.obm.lng.org>
+Subject: =?utf-8?B?VHIuIDogUGhvdG9zICE=?=
+Importance: Normal
+MIME-Version: 1.0
+Content-Type: multipart/mixed;
+       boundary="----=_Part_0_1330682067197"
+
+------=_Part_0_1330682067197
+Content-Type: multipart/alternative;
+       boundary="----=_Part_2_1330682067197"
+
+------=_Part_2_1330682067197
+Content-Type: text/plain;
+       charset= utf-8
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+Content of part 1-1
+------=_Part_2_1330682067197
+Content-Type: text/html;
+       charset= utf-8
+Content-Transfer-Encoding: 8bit
+Content-Disposition: inline
+
+<b>Content of part 1-2</b>
+------=_Part_2_1330682067197--
+
+------=_Part_0_1330682067197
+Content-Type: application/octet-stream
+Content-Transfer-Encoding: base64
+Content-Disposition: attachment;
+       filename="gimp.png"
+
+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
+
+------=_Part_0_1330682067197--
+

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java
 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java
index b6a0f3e..3784393 100644
--- 
a/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java
+++ 
b/server/protocols/jmap-integration-testing/memory-jmap-integration-testing/src/test/java/org/apache/james/jmap/memory/cucumber/MemoryDownloadCucumberTest.java
@@ -25,7 +25,7 @@ import cucumber.api.CucumberOptions;
 import cucumber.api.junit.Cucumber;
 
 @RunWith(Cucumber.class)
-@CucumberOptions(features="classpath:cucumber/DownloadEndpoint.feature",
+@CucumberOptions(features={"classpath:cucumber/DownloadEndpoint.feature", 
"classpath:cucumber/DownloadGet.feature"},
                 glue={"org.apache.james.jmap.methods.integration", 
"org.apache.james.jmap.memory.cucumber"})
 public class MemoryDownloadCucumberTest {
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
index d4a7597..e0c1e98 100644
--- 
a/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
+++ 
b/server/protocols/jmap/src/main/java/org/apache/james/jmap/DownloadServlet.java
@@ -19,18 +19,43 @@
 package org.apache.james.jmap;
 
 import static javax.servlet.http.HttpServletResponse.SC_BAD_REQUEST;
+import static javax.servlet.http.HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
+import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
 import static javax.servlet.http.HttpServletResponse.SC_OK;
 
+import java.io.IOException;
+
+import javax.inject.Inject;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.commons.io.IOUtils;
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.AttachmentNotFoundException;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.apache.james.mailbox.store.mail.AttachmentMapper;
+import org.apache.james.mailbox.store.mail.model.Attachment;
+import org.apache.james.mailbox.store.mail.model.AttachmentId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Strings;
 
 public class DownloadServlet extends HttpServlet {
 
     private static final String ROOT_URL = "/";
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(DownloadServlet.class);
+
+    private final MailboxSessionMapperFactory mailboxSessionMapperFactory;
+
+    @Inject
+    @VisibleForTesting DownloadServlet(MailboxSessionMapperFactory 
mailboxSessionMapperFactory) {
+        this.mailboxSessionMapperFactory = mailboxSessionMapperFactory;
+    }
 
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException {
@@ -38,7 +63,30 @@ public class DownloadServlet extends HttpServlet {
         if (Strings.isNullOrEmpty(pathInfo) || pathInfo.equals(ROOT_URL)) {
             resp.setStatus(SC_BAD_REQUEST);
         } else {
+            download(getMailboxSession(req), blobIdFrom(pathInfo), resp);
+        }
+    }
+
+    @VisibleForTesting String blobIdFrom(String pathInfo) {
+        return pathInfo.substring(1);
+    }
+
+    @VisibleForTesting void download(MailboxSession mailboxSession, String 
blobId, HttpServletResponse resp) {
+        try {
+            AttachmentMapper attachmentMapper = 
mailboxSessionMapperFactory.createAttachmentMapper(mailboxSession);
+            Attachment attachment = 
attachmentMapper.getAttachment(AttachmentId.from(blobId));
+            IOUtils.copy(attachment.getStream(), resp.getOutputStream());
             resp.setStatus(SC_OK);
+        } catch (AttachmentNotFoundException e) {
+            LOGGER.info(String.format("Attachment '%s' not found", blobId), e);
+            resp.setStatus(SC_NOT_FOUND);
+        } catch (MailboxException | IOException e) {
+            LOGGER.error("Error while downloading", e);
+            resp.setStatus(SC_INTERNAL_SERVER_ERROR);
         }
     }
+
+    private MailboxSession getMailboxSession(HttpServletRequest req) {
+        return (MailboxSession) 
req.getAttribute(AuthenticationFilter.MAILBOX_SESSION);
+    }
 }

http://git-wip-us.apache.org/repos/asf/james-project/blob/81d88bf7/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java
----------------------------------------------------------------------
diff --git 
a/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java
 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java
new file mode 100644
index 0000000..ccf4992
--- /dev/null
+++ 
b/server/protocols/jmap/src/test/java/org/apache/james/jmap/DownloadServletTest.java
@@ -0,0 +1,57 @@
+/****************************************************************
+ * 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 static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.james.mailbox.MailboxSession;
+import org.apache.james.mailbox.exception.MailboxException;
+import org.apache.james.mailbox.store.MailboxSessionMapperFactory;
+import org.junit.Test;
+
+public class DownloadServletTest {
+
+    @Test
+    public void blobIdFromShouldSkipTheFirstCharacter() {
+        String blobId = new DownloadServlet(null).blobIdFrom("1234");
+        assertThat(blobId).isEqualTo("234");
+    }
+
+    @Test
+    public void downloadMayFailWhenUnableToCreateAttachmentMapper() throws 
Exception {
+        MailboxSession mailboxSession = mock(MailboxSession.class);
+        MailboxSessionMapperFactory mailboxSessionMapperFactory = 
mock(MailboxSessionMapperFactory.class);
+        
when(mailboxSessionMapperFactory.createAttachmentMapper(mailboxSession))
+            .thenThrow(new MailboxException());
+
+        DownloadServlet testee = new 
DownloadServlet(mailboxSessionMapperFactory);
+
+        String blobId = null;
+        HttpServletResponse resp = mock(HttpServletResponse.class);
+        testee.download(mailboxSession, blobId, resp);
+
+        verify(resp).setStatus(500);
+    }
+}


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