| /**************************************************************** |
| * 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.cucumber; |
| |
| import static org.assertj.core.api.Assertions.assertThat; |
| |
| import java.io.ByteArrayInputStream; |
| import java.time.ZonedDateTime; |
| import java.util.Date; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| import java.util.Optional; |
| import java.util.Set; |
| import java.util.function.Function; |
| import java.util.stream.Collectors; |
| |
| import javax.inject.Inject; |
| import javax.mail.Flags; |
| |
| import org.apache.commons.lang3.StringEscapeUtils; |
| import org.apache.http.HttpResponse; |
| import org.apache.http.client.fluent.Request; |
| import org.apache.james.jmap.methods.integration.cucumber.util.TableRow; |
| import org.apache.james.mailbox.model.MailboxConstants; |
| import org.apache.james.mailbox.model.MailboxPath; |
| import org.javatuples.Pair; |
| |
| import com.google.common.base.Charsets; |
| import com.google.common.base.Joiner; |
| import com.jayway.jsonpath.Configuration; |
| import com.jayway.jsonpath.DocumentContext; |
| import com.jayway.jsonpath.JsonPath; |
| import com.jayway.jsonpath.Option; |
| |
| import cucumber.api.DataTable; |
| import cucumber.api.java.en.Given; |
| import cucumber.api.java.en.Then; |
| import cucumber.api.java.en.When; |
| import cucumber.runtime.java.guice.ScenarioScoped; |
| |
| @ScenarioScoped |
| public class GetMessagesMethodStepdefs { |
| |
| private static final Optional<Map<String, String>> NO_HEADERS = Optional.empty(); |
| private static final String NAME = "[0][0]"; |
| private static final String ARGUMENTS = "[0][1]"; |
| private static final String FIRST_MESSAGE = ARGUMENTS + ".list[0]"; |
| private static final String ATTACHMENTS = FIRST_MESSAGE + ".attachments"; |
| private static final String FIRST_ATTACHMENT = ATTACHMENTS + "[0]"; |
| private static final String SECOND_ATTACHMENT = ATTACHMENTS + "[1]"; |
| |
| |
| private final MainStepdefs mainStepdefs; |
| private final UserStepdefs userStepdefs; |
| |
| private HttpResponse response; |
| private DocumentContext jsonPath; |
| |
| @Inject |
| private GetMessagesMethodStepdefs(MainStepdefs mainStepdefs, UserStepdefs userStepdefs) { |
| this.mainStepdefs = mainStepdefs; |
| this.userStepdefs = userStepdefs; |
| } |
| |
| @Given("^the user has a message in \"([^\"]*)\" mailbox with subject \"([^\"]*)\" and content \"([^\"]*)\"$") |
| public void appendMessage(String mailbox, String subject, String content) throws Throwable { |
| appendMessage(mailbox, ContentType.noContentType(), subject, content, NO_HEADERS); |
| } |
| |
| @Given("^the user has a message in \"([^\"]*)\" mailbox with content-type \"([^\"]*)\" subject \"([^\"]*)\" and content \"([^\"]*)\"$") |
| public void appendMessage(String mailbox, String contentType, String subject, String content) throws Throwable { |
| appendMessage(mailbox, ContentType.from(contentType), subject, content, NO_HEADERS); |
| } |
| |
| @Given("^the user has a message in \"([^\"]*)\" mailbox with subject \"([^\"]*)\" and content \"([^\"]*)\" with headers$") |
| public void appendMessage(String mailbox, String subject, String content, DataTable headers) throws Throwable { |
| appendMessage(mailbox, ContentType.noContentType(), subject, content, Optional.of(headers.asMap(String.class, String.class))); |
| } |
| |
| private void appendMessage(String mailbox, ContentType contentType, String subject, String content, Optional<Map<String, String>> headers) throws Exception { |
| ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z"); |
| mainStepdefs.jmapServer.serverProbe().appendMessage(userStepdefs.lastConnectedUser, |
| new MailboxPath(MailboxConstants.USER_NAMESPACE, userStepdefs.lastConnectedUser, mailbox), |
| new ByteArrayInputStream(message(contentType, subject, content, headers).getBytes(Charsets.UTF_8)), |
| Date.from(dateTime.toInstant()), false, new Flags()); |
| } |
| |
| private String message(ContentType contentType, String subject, String content, Optional<Map<String,String>> headers) { |
| return serialize(headers) + contentType.serializeToHeader() + "Subject: " + subject + "\r\n\r\n" + content; |
| } |
| |
| private String serialize(Optional<Map<String,String>> headers) { |
| return headers |
| .map(map -> map.entrySet()) |
| .map(entriesToString()) |
| .orElse(""); |
| } |
| |
| private Function<Set<Entry<String, String>>, String> entriesToString() { |
| return entries -> entries.stream() |
| .map(this::entryToPair) |
| .map(this::joinKeyValue) |
| .collect(Collectors.joining("\r\n", "", "\r\n")); |
| } |
| |
| @Given("^the user has a message in \"([^\"]*)\" mailbox with two attachments$") |
| public void appendHtmlMessageWithTwoAttachments(String mailbox) throws Throwable { |
| appendMessage("eml/twoAttachments.eml"); |
| } |
| |
| @Given("^the user has a message in \"([^\"]*)\" mailbox with two attachments in text$") |
| public void appendTextMessageWithTwoAttachments(String arg1) throws Throwable { |
| appendMessage("eml/twoAttachmentsTextPlain.eml"); |
| } |
| |
| @Given("^the user has a multipart message in \"([^\"]*)\" mailbox$") |
| public void appendMultipartMessageWithOneAttachments(String arg1) throws Throwable { |
| appendMessage("eml/htmlAndTextMultipartWithOneAttachment.eml"); |
| } |
| |
| private void appendMessage(String emlFileName) throws Exception { |
| ZonedDateTime dateTime = ZonedDateTime.parse("2014-10-30T14:12:00Z"); |
| mainStepdefs.jmapServer.serverProbe().appendMessage(userStepdefs.lastConnectedUser, |
| new MailboxPath(MailboxConstants.USER_NAMESPACE, userStepdefs.lastConnectedUser, "inbox"), |
| ClassLoader.getSystemResourceAsStream(emlFileName), |
| Date.from(dateTime.toInstant()), false, new Flags()); |
| } |
| |
| @When("^the user ask for messages using its accountId$") |
| public void postWithAccountId() throws Exception { |
| post("[[\"getMessages\", {\"accountId\": \"1\"}, \"#0\"]]"); |
| } |
| |
| @When("^the user ask for messages using unknown arguments$") |
| public void postWithUnknownArguments() throws Exception { |
| post("[[\"getMessages\", {\"WAT\": true}, \"#0\"]]"); |
| } |
| |
| @When("^the user ask for messages using invalid argument$") |
| public void postWithInvalidArguments() throws Exception { |
| post("[[\"getMessages\", {\"ids\": null}, \"#0\"]]"); |
| } |
| |
| @When("^the user ask for messages$") |
| public void post() throws Throwable { |
| post("[[\"getMessages\", {\"ids\": []}, \"#0\"]]"); |
| } |
| |
| @When("^the user ask for messages \"(.*?)\"$") |
| public void postWithAListOfIds(String ids) throws Throwable { |
| post("[[\"getMessages\", {\"ids\": " + ids + "}, \"#0\"]]"); |
| } |
| |
| @When("^the user is getting his messages with parameters$") |
| public void postWithParameters(DataTable parameters) throws Throwable { |
| String payload = |
| parameters.asMap(String.class, String.class) |
| .entrySet() |
| .stream() |
| .map(this::entryToPair) |
| .map(this::quoteIndex) |
| .map(this::joinKeyValue) |
| .collect(Collectors.joining(",", "{", "}")); |
| |
| post("[[\"getMessages\", " + payload + ", \"#0\"]]"); |
| } |
| |
| private Pair<String, String> entryToPair(Map.Entry<String, String> entry) { |
| return Pair.with(entry.getKey(), entry.getValue()); |
| } |
| |
| private Pair<String, String> quoteIndex(Pair<String, String> pair) { |
| return Pair.with(String.format("\"%s\"", pair.getValue0()), pair.getValue1()); |
| } |
| |
| private String joinKeyValue(Pair<String, String> pair) { |
| return Joiner.on(": ").join(pair); |
| } |
| |
| private void post(String requestBody) throws Exception { |
| response = Request.Post(mainStepdefs.baseUri().setPath("/jmap").build()) |
| .addHeader("Authorization", userStepdefs.tokenByUser.get(userStepdefs.lastConnectedUser).serialize()) |
| .addHeader("Accept", org.apache.http.entity.ContentType.APPLICATION_JSON.getMimeType()) |
| .bodyString(requestBody, org.apache.http.entity.ContentType.APPLICATION_JSON) |
| .execute() |
| .returnResponse(); |
| jsonPath = JsonPath.using(Configuration.defaultConfiguration().addOptions(Option.SUPPRESS_EXCEPTIONS)).parse(response.getEntity().getContent()); |
| } |
| |
| @Then("^an error \"([^\"]*)\" is returned$") |
| public void error(String type) throws Throwable { |
| assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200); |
| assertThat(jsonPath.<String>read(NAME)).isEqualTo("error"); |
| assertThat(jsonPath.<String>read(ARGUMENTS + ".type")).isEqualTo(type); |
| } |
| |
| @Then("^no error is returned$") |
| public void noError() throws Throwable { |
| assertThat(response.getStatusLine().getStatusCode()).isEqualTo(200); |
| assertThat(jsonPath.<String>read(NAME)).isEqualTo("messages"); |
| } |
| |
| @Then("^the list of unknown messages is empty$") |
| public void assertNotFoundIsEmpty() { |
| assertThat(jsonPath.<List<String>>read(ARGUMENTS + ".notFound")).isEmpty(); |
| } |
| |
| @Then("^the list of messages is empty$") |
| public void assertListIsEmpty() { |
| assertThat(jsonPath.<List<String>>read(ARGUMENTS + ".list")).isEmpty(); |
| } |
| |
| @Then("^the description is \"(.*?)\"$") |
| public void assertDescription(String description) throws Throwable { |
| assertThat(jsonPath.<String>read(ARGUMENTS + ".description")).isEqualTo(description); |
| } |
| |
| @Then("^the notFound list should contains \"([^\"]*)\"$") |
| public void assertNotFoundListContains(String ids) throws Throwable { |
| assertThat(jsonPath.<List<String>>read(ARGUMENTS + ".notFound")).contains(ids); |
| } |
| |
| @Then("^the list should contain (\\d+) message$") |
| public void assertListContains(int numberOfMessages) throws Throwable { |
| assertThat(jsonPath.<List<String>>read(ARGUMENTS + ".list")).hasSize(numberOfMessages); |
| } |
| |
| @Then("^the id of the message is \"([^\"]*)\"$") |
| public void assertIdOfTheFirstMessage(String id) throws Throwable { |
| assertThat(jsonPath.<String>read(FIRST_MESSAGE + ".id")).isEqualTo(id); |
| } |
| |
| @Then("^the threadId of the message is \"([^\"]*)\"$") |
| public void assertThreadIdOfTheFirstMessage(String threadId) throws Throwable { |
| assertThat(jsonPath.<String>read(FIRST_MESSAGE + ".threadId")).isEqualTo(threadId); |
| } |
| |
| @Then("^the subject of the message is \"([^\"]*)\"$") |
| public void assertSubjectOfTheFirstMessage(String subject) throws Throwable { |
| assertThat(jsonPath.<String>read(FIRST_MESSAGE + ".subject")).isEqualTo(subject); |
| } |
| |
| @Then("^the textBody of the message is \"([^\"]*)\"$") |
| public void assertTextBodyOfTheFirstMessage(String textBody) throws Throwable { |
| assertThat(jsonPath.<String>read(FIRST_MESSAGE + ".textBody")).isEqualTo(StringEscapeUtils.unescapeJava(textBody)); |
| } |
| |
| @Then("^the htmlBody of the message is \"([^\"]*)\"$") |
| public void assertHtmlBodyOfTheFirstMessage(String htmlBody) throws Throwable { |
| assertThat(jsonPath.<String>read(FIRST_MESSAGE + ".htmlBody")).isEqualTo(StringEscapeUtils.unescapeJava(htmlBody)); |
| } |
| |
| @Then("^the isUnread of the message is \"([^\"]*)\"$") |
| public void assertIsUnreadOfTheFirstMessage(String isUnread) throws Throwable { |
| assertThat(jsonPath.<Boolean>read(FIRST_MESSAGE + ".isUnread")).isEqualTo(Boolean.valueOf(isUnread)); |
| } |
| |
| @Then("^the preview of the message is \"([^\"]*)\"$") |
| public void assertPreviewOfTheFirstMessage(String preview) throws Throwable { |
| String actual = jsonPath.<String>read(FIRST_MESSAGE + ".preview").replace("\n", " "); |
| assertThat(actual).isEqualToIgnoringWhitespace(StringEscapeUtils.unescapeJava(preview)); |
| } |
| |
| @Then("^the headers of the message contains:$") |
| public void assertHeadersOfTheFirstMessage(DataTable headers) throws Throwable { |
| assertThat(jsonPath.<Map<String, String>>read(FIRST_MESSAGE + ".headers")).isEqualTo(headers.asMap(String.class, String.class)); |
| } |
| |
| @Then("^the date of the message is \"([^\"]*)\"$") |
| public void assertDateOfTheFirstMessage(String date) throws Throwable { |
| assertThat(jsonPath.<String>read(FIRST_MESSAGE + ".date")).isEqualTo(date); |
| } |
| |
| @Then("^the hasAttachment of the message is \"([^\"]*)\"$") |
| public void assertHasAttachmentOfTheFirstMessage(String hasAttachment) throws Throwable { |
| assertThat(jsonPath.<Boolean>read(FIRST_MESSAGE + ".hasAttachment")).isEqualTo(Boolean.valueOf(hasAttachment)); |
| } |
| |
| @Then("^the list of attachments of the message is empty$") |
| public void assertAttachmentsOfTheFirstMessageIsEmpty() throws Throwable { |
| assertThat(jsonPath.<List<Object>>read(ATTACHMENTS)).isEmpty(); |
| } |
| |
| @Then("^the property \"([^\"]*)\" of the message is null$") |
| public void assertPropertyIsNull(String property) throws Throwable { |
| assertThat(jsonPath.<String>read(FIRST_MESSAGE + "." + property + ".date")).isNull(); |
| } |
| |
| @Then("^the list of attachments of the message contains (\\d+) attachments?$") |
| public void assertAttachmentsHasSize(int numberOfAttachments) throws Throwable { |
| assertThat(jsonPath.<List<Object>>read(ATTACHMENTS)).hasSize(numberOfAttachments); |
| } |
| |
| @Then("^the first attachment is:$") |
| public void assertFirstAttachment(DataTable attachmentProperties) throws Throwable { |
| assertAttachment(FIRST_ATTACHMENT, attachmentProperties); |
| } |
| |
| @Then("^the second attachment is:$") |
| public void assertSecondAttachment(DataTable attachmentProperties) throws Throwable { |
| assertAttachment(SECOND_ATTACHMENT, attachmentProperties); |
| } |
| |
| private void assertAttachment(String attachment, DataTable attachmentProperties) { |
| attachmentProperties.asList(TableRow.class) |
| .stream() |
| .forEach(entry -> assertThat(jsonPath.<Object>read(attachment + "." + entry.getKey())).isEqualTo(entry.getValue())); |
| } |
| } |