JAMES-1717 htmlBody field should be stored
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/aa877901 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/aa877901 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/aa877901 Branch: refs/heads/master Commit: aa8779017b7beffbd21bae396618907f7c948dc8 Parents: bfe7973 Author: Benoit Tellier <[email protected]> Authored: Thu Jun 2 09:41:13 2016 +0700 Committer: Benoit Tellier <[email protected]> Committed: Fri Jun 3 19:38:15 2016 +0700 ---------------------------------------------------------------------- .../vacation/CassandraVacationDAO.java | 11 ++-- .../vacation/CassandraVacationModule.java | 3 +- .../vacation/tables/CassandraVacationTable.java | 1 + .../james/jmap/api/vacation/Vacation.java | 50 +++++++++++++---- .../AbstractVacationRepositoryTest.java | 3 ++ .../james/jmap/api/vacation/VacationTest.java | 56 +++++++++++++++++++ .../integration/GetVacationResponseTest.java | 9 ++-- .../integration/SetVacationResponseTest.java | 10 ++-- .../jmap/methods/SetVacationResponseMethod.java | 1 + .../james/jmap/model/VacationResponse.java | 48 ++++++++++++----- .../methods/SetVacationResponseMethodTest.java | 10 ++-- .../jmap/model/GetVacationResponseTest.java | 4 +- .../jmap/model/SetVacationRequestTest.java | 5 +- .../james/jmap/model/VacationResponseTest.java | 57 ++++++++++++++++++-- 14 files changed, 222 insertions(+), 46 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java index 3bf5e18..e52139c 100644 --- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java +++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationDAO.java @@ -62,7 +62,8 @@ public class CassandraVacationDAO { .value(CassandraVacationTable.FROM_DATE, bindMarker(CassandraVacationTable.FROM_DATE)) .value(CassandraVacationTable.TO_DATE, bindMarker(CassandraVacationTable.TO_DATE)) .value(CassandraVacationTable.TEXT, bindMarker(CassandraVacationTable.TEXT)) - .value(CassandraVacationTable.SUBJECT, bindMarker(CassandraVacationTable.SUBJECT))); + .value(CassandraVacationTable.SUBJECT, bindMarker(CassandraVacationTable.SUBJECT)) + .value(CassandraVacationTable.HTML, bindMarker(CassandraVacationTable.HTML))); this.readStatement = session.prepare(select() .from(CassandraVacationTable.TABLE_NAME) @@ -77,8 +78,9 @@ public class CassandraVacationDAO { .setBool(CassandraVacationTable.IS_ENABLED, vacation.isEnabled()) .setUDTValue(CassandraVacationTable.FROM_DATE, convertToUDTValue(vacation.getFromDate())) .setUDTValue(CassandraVacationTable.TO_DATE, convertToUDTValue(vacation.getToDate())) - .setString(CassandraVacationTable.TEXT, vacation.getTextBody()) - .setString(CassandraVacationTable.SUBJECT, vacation.getSubject().orElse(null))); + .setString(CassandraVacationTable.TEXT, vacation.getTextBody().orElse(null)) + .setString(CassandraVacationTable.SUBJECT, vacation.getSubject().orElse(null)) + .setString(CassandraVacationTable.HTML, vacation.getHtmlBody().orElse(null))); } public CompletableFuture<Optional<Vacation>> retrieveVacation(AccountId accountId) { @@ -88,8 +90,9 @@ public class CassandraVacationDAO { .enabled(row.getBool(CassandraVacationTable.IS_ENABLED)) .fromDate(retrieveDate(row, CassandraVacationTable.FROM_DATE)) .toDate(retrieveDate(row, CassandraVacationTable.TO_DATE)) - .textBody(row.getString(CassandraVacationTable.TEXT)) .subject(Optional.ofNullable(row.getString(CassandraVacationTable.SUBJECT))) + .textBody(Optional.ofNullable(row.getString(CassandraVacationTable.TEXT))) + .htmlBody(Optional.ofNullable(row.getString(CassandraVacationTable.HTML))) .build())); } http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationModule.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationModule.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationModule.java index 00233e0..2a0395b 100644 --- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationModule.java +++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/CassandraVacationModule.java @@ -50,7 +50,8 @@ public class CassandraVacationModule implements CassandraModule { .addUDTColumn(CassandraVacationTable.FROM_DATE, SchemaBuilder.frozen(CassandraZonedDateTimeModule.ZONED_DATE_TIME)) .addUDTColumn(CassandraVacationTable.TO_DATE, SchemaBuilder.frozen(CassandraZonedDateTimeModule.ZONED_DATE_TIME)) .addColumn(CassandraVacationTable.TEXT, text()) - .addColumn(CassandraVacationTable.SUBJECT, text()))); + .addColumn(CassandraVacationTable.SUBJECT, text()) + .addColumn(CassandraVacationTable.HTML, text()))); index = ImmutableList.of(); types = ImmutableList.of(); } http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/tables/CassandraVacationTable.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/tables/CassandraVacationTable.java b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/tables/CassandraVacationTable.java index 271820b..8c587fc 100644 --- a/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/tables/CassandraVacationTable.java +++ b/server/data/data-jmap-cassandra/src/main/java/org/apache/james/jmap/cassandra/vacation/tables/CassandraVacationTable.java @@ -28,5 +28,6 @@ public interface CassandraVacationTable { String IS_ENABLED = "is_enabled"; String TEXT = "text"; String SUBJECT = "subject"; + String HTML = "html"; } http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/vacation/Vacation.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/vacation/Vacation.java b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/vacation/Vacation.java index 9b76409..62d6879 100644 --- a/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/vacation/Vacation.java +++ b/server/data/data-jmap/src/main/java/org/apache/james/jmap/api/vacation/Vacation.java @@ -38,8 +38,9 @@ public class Vacation { private Optional<Boolean> isEnabled = Optional.empty(); private Optional<ZonedDateTime> fromDate = Optional.empty(); private Optional<ZonedDateTime> toDate = Optional.empty(); + private Optional<String> textBody = Optional.empty(); private Optional<String> subject = Optional.empty(); - private String textBody = ""; + private Optional<String> htmlBody = Optional.empty(); public Builder enabled(boolean enabled) { isEnabled = Optional.of(enabled); @@ -58,16 +59,36 @@ public class Vacation { return this; } - public Builder textBody(String textBody) { + public Builder textBody(Optional<String> textBody) { + Preconditions.checkNotNull(textBody); this.textBody = textBody; return this; } + public Builder textBody(String textBody) { + Preconditions.checkNotNull(textBody); + this.textBody = Optional.of(textBody); + return this; + } + public Builder subject(Optional<String> subject) { + Preconditions.checkNotNull(subject); this.subject = subject; return this; } + public Builder htmlBody(Optional<String> htmlBody) { + Preconditions.checkNotNull(htmlBody); + this.htmlBody = htmlBody; + return this; + } + + public Builder htmlBody(String htmlBody) { + Preconditions.checkNotNull(htmlBody); + this.htmlBody = Optional.of(htmlBody); + return this; + } + public Builder copy(Vacation vacation) { this.textBody = vacation.getTextBody(); this.fromDate = vacation.getFromDate(); @@ -78,8 +99,11 @@ public class Vacation { } public Vacation build() { - Preconditions.checkNotNull(textBody); - return new Vacation(isEnabled.orElse(DEFAULT_DISABLED), fromDate, toDate, textBody, subject); + boolean enabled = isEnabled.orElse(DEFAULT_DISABLED); + if (enabled) { + Preconditions.checkState(textBody.isPresent() || htmlBody.isPresent(), "textBody or htmlBody property of vacationResponse object should not be null when enabled"); + } + return new Vacation(enabled, fromDate, toDate, textBody, subject, htmlBody); } } @@ -87,14 +111,17 @@ public class Vacation { private final Optional<ZonedDateTime> fromDate; private final Optional<ZonedDateTime> toDate; private final Optional<String> subject; - private final String textBody; + private final Optional<String> textBody; + private final Optional<String> htmlBody; - private Vacation(boolean isEnabled, Optional<ZonedDateTime> fromDate, Optional<ZonedDateTime> toDate, String textBody, Optional<String> subject) { + private Vacation(boolean isEnabled, Optional<ZonedDateTime> fromDate, Optional<ZonedDateTime> toDate, + Optional<String> textBody, Optional<String> subject, Optional<String> htmlBody) { this.isEnabled = isEnabled; this.fromDate = fromDate; this.toDate = toDate; this.textBody = textBody; this.subject = subject; + this.htmlBody = htmlBody; } @@ -110,7 +137,7 @@ public class Vacation { return toDate; } - public String getTextBody() { + public Optional<String> getTextBody() { return textBody; } @@ -118,6 +145,10 @@ public class Vacation { return subject; } + public Optional<String> getHtmlBody() { + return htmlBody; + } + public boolean isActiveAtDate(ZonedDateTime instant) { Preconditions.checkNotNull(instant); return isEnabled @@ -144,12 +175,13 @@ public class Vacation { Objects.equals(this.fromDate, vacation.fromDate) && Objects.equals(this.toDate, vacation.toDate) && Objects.equals(this.textBody, vacation.textBody) && - Objects.equals(this.subject, vacation.subject); + Objects.equals(this.subject, vacation.subject) && + Objects.equals(this.htmlBody, vacation.htmlBody); } @Override public int hashCode() { - return Objects.hash(isEnabled, fromDate, toDate, textBody, subject); + return Objects.hash(isEnabled, fromDate, toDate, textBody, subject, htmlBody); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/AbstractVacationRepositoryTest.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/AbstractVacationRepositoryTest.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/AbstractVacationRepositoryTest.java index 4b4c932..ee7ad0c 100644 --- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/AbstractVacationRepositoryTest.java +++ b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/AbstractVacationRepositoryTest.java @@ -33,11 +33,14 @@ public abstract class AbstractVacationRepositoryTest { public static final ZonedDateTime ZONED_DATE_TIME = ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]"); public static final Vacation VACATION_1 = Vacation.builder() .enabled(true) + .textBody("other Message") .build(); public static final Vacation VACATION_2 = Vacation.builder() .fromDate(Optional.of(ZONED_DATE_TIME)) .enabled(true) .subject(Optional.of("subject")) + .textBody("anyMessage") + .htmlBody("html Message") .build(); http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/VacationTest.java ---------------------------------------------------------------------- diff --git a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/VacationTest.java b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/VacationTest.java index 9704ae9..6442a32 100644 --- a/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/VacationTest.java +++ b/server/data/data-jmap/src/test/java/org/apache/james/jmap/api/vacation/VacationTest.java @@ -20,6 +20,7 @@ package org.apache.james.jmap.api.vacation; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.time.ZonedDateTime; import java.util.Optional; @@ -32,6 +33,8 @@ public class VacationTest { public static final ZonedDateTime DATE_TIME_2017 = ZonedDateTime.parse("2017-10-09T08:07:06+07:00[Asia/Vientiane]"); public static final ZonedDateTime DATE_TIME_2017_1MS = ZonedDateTime.parse("2017-10-09T08:07:06.001+07:00[Asia/Vientiane]"); public static final ZonedDateTime DATE_TIME_2018 = ZonedDateTime.parse("2018-10-09T08:07:06+07:00[Asia/Vientiane]"); + public static final String TEXT_BODY = "text is required when enabled"; + public static final String HTML_BODY = "<b>HTML body</b>"; @Test public void disabledVacationsAreNotActive() { @@ -48,6 +51,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .build() .isActiveAtDate(DATE_TIME_2016)) .isTrue(); @@ -58,6 +62,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .fromDate(Optional.of(DATE_TIME_2016)) .build() .isActiveAtDate(DATE_TIME_2016)) @@ -69,6 +74,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .toDate(Optional.of(DATE_TIME_2016)) .build() .isActiveAtDate(DATE_TIME_2016)) @@ -80,6 +86,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .fromDate(Optional.of(DATE_TIME_2016)) .toDate(Optional.of(DATE_TIME_2018)) .build() @@ -92,6 +99,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .fromDate(Optional.of(DATE_TIME_2016)) .toDate(Optional.of(DATE_TIME_2017)) .build() @@ -104,6 +112,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .fromDate(Optional.of(DATE_TIME_2017)) .toDate(Optional.of(DATE_TIME_2018)) .build() @@ -115,6 +124,7 @@ public class VacationTest { public void isActiveAtDateShouldThrowOnNullValue() { Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .fromDate(Optional.of(DATE_TIME_2016)) .toDate(Optional.of(DATE_TIME_2016)) .build() @@ -126,6 +136,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .fromDate(Optional.of(DATE_TIME_2016)) .build() .isActiveAtDate(DATE_TIME_2017)) @@ -137,6 +148,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .fromDate(Optional.of(DATE_TIME_2017)) .build() .isActiveAtDate(DATE_TIME_2016)) @@ -148,6 +160,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .toDate(Optional.of(DATE_TIME_2017)) .build() .isActiveAtDate(DATE_TIME_2018)) @@ -159,6 +172,7 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .toDate(Optional.of(DATE_TIME_2017)) .build() .isActiveAtDate(DATE_TIME_2016)) @@ -170,10 +184,52 @@ public class VacationTest { assertThat( Vacation.builder() .enabled(true) + .textBody(TEXT_BODY) .toDate(Optional.of(DATE_TIME_2017)) .build() .isActiveAtDate(DATE_TIME_2017_1MS)) .isFalse(); } + @Test + public void activeVacationShouldHaveHtmlBodyOrTextBody() { + assertThatThrownBy( + () -> Vacation.builder() + .enabled(true) + .build()) + .isInstanceOf(IllegalStateException.class); + } + + @Test + public void textBodyShouldBeEnoughToBuildAnActivatedVacation() { + assertThat( + Vacation.builder() + .enabled(true) + .textBody(TEXT_BODY) + .build() + .getTextBody()) + .contains(TEXT_BODY); + } + + @Test + public void htmlBodyShouldBeEnoughToBuildAnActivatedVacation() { + assertThat( + Vacation.builder() + .enabled(true) + .htmlBody(HTML_BODY) + .build() + .getHtmlBody()) + .contains(HTML_BODY); + } + + @Test + public void textOrHtmlBodyShouldNotBeRequiredOnUnactivatedVacation() { + assertThat( + Vacation.builder() + .enabled(false) + .build() + .isEnabled()) + .isFalse(); + } + } http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetVacationResponseTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetVacationResponseTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetVacationResponseTest.java index 7e49b56..4dc59e0 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetVacationResponseTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/GetVacationResponseTest.java @@ -99,8 +99,9 @@ public abstract class GetVacationResponseTest { .body(ARGUMENTS + ".list[0].fromDate", nullValue()) .body(ARGUMENTS + ".list[0].toDate", nullValue()) .body(ARGUMENTS + ".list[0].isEnabled", equalTo(false)) - .body(ARGUMENTS + ".list[0].textBody", equalTo("")) - .body(ARGUMENTS + ".list[0].subject", nullValue()); + .body(ARGUMENTS + ".list[0].subject", nullValue()) + .body(ARGUMENTS + ".list[0].textBody", nullValue()) + .body(ARGUMENTS + ".list[0].htmlBody", nullValue()); } @Test @@ -112,6 +113,7 @@ public abstract class GetVacationResponseTest { .toDate(Optional.of(ZonedDateTime.parse("2014-10-30T14:10:00Z"))) .textBody("Test explaining my vacations") .subject(Optional.of(SUBJECT)) + .htmlBody("<p>Test explaining my vacations</p>") .build()); given() @@ -135,7 +137,8 @@ public abstract class GetVacationResponseTest { .body(ARGUMENTS + ".list[0].toDate", equalTo("2014-10-30T14:10:00Z")) .body(ARGUMENTS + ".list[0].isEnabled", equalTo(true)) .body(ARGUMENTS + ".list[0].textBody", equalTo("Test explaining my vacations")) - .body(ARGUMENTS + ".list[0].subject", equalTo(SUBJECT)); + .body(ARGUMENTS + ".list[0].subject", equalTo(SUBJECT)) + .body(ARGUMENTS + ".list[0].htmlBody", equalTo("<p>Test explaining my vacations</p>")); } @Test http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java index dcf46e7..0209593 100644 --- a/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java +++ b/server/protocols/jmap-integration-testing/jmap-integration-testing-common/src/test/java/org/apache/james/jmap/methods/integration/SetVacationResponseTest.java @@ -146,6 +146,7 @@ public abstract class SetVacationResponseTest { "\"id\": \"singleton\"," + "\"isEnabled\": \"true\"," + "\"textBody\": \"Message explaining my wonderful vacations\"," + + "\"htmlBody\": \"<p>Here is the HTML version</p>\"," + "\"fromDate\":\"2014-09-30T14:10:00Z[GMT]\"," + "\"toDate\":\"2014-10-30T14:10:00Z[GMT]\"," + "\"subject\":\"" + SUBJECT + "\"" + @@ -168,7 +169,8 @@ public abstract class SetVacationResponseTest { .body(ARGUMENTS + ".updated[0]", equalTo("singleton")); Vacation vacation = jmapServer.serverProbe().retrieveVacation(AccountId.fromString(USER)); - assertThat(vacation.getTextBody()).isEqualTo("Message explaining my wonderful vacations"); + assertThat(vacation.getTextBody()).contains("Message explaining my wonderful vacations"); + assertThat(vacation.getHtmlBody()).contains("<p>Here is the HTML version</p>"); assertThat(vacation.isEnabled()).isTrue(); assertThat(vacation.getFromDate()).contains(ZonedDateTime.parse("2014-09-30T14:10:00Z[GMT]")); assertThat(vacation.getToDate()).contains(ZonedDateTime.parse("2014-10-30T14:10:00Z[GMT]")); @@ -206,7 +208,7 @@ public abstract class SetVacationResponseTest { .body(ARGUMENTS + ".updated[0]", equalTo("singleton")); Vacation vacation = jmapServer.serverProbe().retrieveVacation(AccountId.fromString(USER)); - assertThat(vacation.getTextBody()).isEqualTo("Message explaining my wonderful vacations"); + assertThat(vacation.getTextBody()).contains("Message explaining my wonderful vacations"); assertThat(vacation.isEnabled()).isTrue(); assertThat(vacation.getFromDate()).contains(ZonedDateTime.parse("2016-04-03T02:01+07:00[Asia/Vientiane]")); assertThat(vacation.getToDate()).contains(ZonedDateTime.parse("2016-04-07T02:01+07:00[Asia/Vientiane]")); @@ -239,7 +241,7 @@ public abstract class SetVacationResponseTest { .statusCode(200) .body(NAME, equalTo("error")) .body(ARGUMENTS + ".type", equalTo("invalidArguments")) - .body(ARGUMENTS + ".description", containsString("textBody property of vacationResponse object should not be null")); + .body(ARGUMENTS + ".description", containsString("textBody or htmlBody property of vacationResponse object should not be null when enabled")); } @Test @@ -268,7 +270,7 @@ public abstract class SetVacationResponseTest { .statusCode(200) .body(NAME, equalTo("error")) .body(ARGUMENTS + ".type", equalTo("invalidArguments")) - .body(ARGUMENTS + ".description", containsString("textBody property of vacationResponse object should not be null")); + .body(ARGUMENTS + ".description", containsString("textBody or htmlBody property of vacationResponse object should not be null when enabled")); } @Test http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetVacationResponseMethod.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetVacationResponseMethod.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetVacationResponseMethod.java index 136a162..56235e9 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetVacationResponseMethod.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/methods/SetVacationResponseMethod.java @@ -123,6 +123,7 @@ public class SetVacationResponseMethod implements Method { .toDate(vacationResponse.getToDate()) .textBody(vacationResponse.getTextBody()) .subject(vacationResponse.getSubject()) + .htmlBody(vacationResponse.getHtmlBody()) .build(); } http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/VacationResponse.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/VacationResponse.java b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/VacationResponse.java index 410ab2c..751dfa9 100644 --- a/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/VacationResponse.java +++ b/server/protocols/jmap/src/main/java/org/apache/james/jmap/model/VacationResponse.java @@ -37,6 +37,8 @@ import com.google.common.base.Preconditions; @JsonDeserialize(builder = VacationResponse.Builder.class) public class VacationResponse { + public static final boolean DEFAULT_DISABLED = false; + public static Builder builder() { return new Builder(); } @@ -44,11 +46,12 @@ public class VacationResponse { @JsonPOJOBuilder(withPrefix = "") public static class Builder { private String id; - private boolean isEnabled; + private Optional<Boolean> isEnabled = Optional.empty(); private Optional<ZonedDateTime> fromDate = Optional.empty(); private Optional<ZonedDateTime> toDate = Optional.empty(); private Optional<String> subject = Optional.empty(); - private String textBody; + private Optional<String> textBody = Optional.empty(); + private Optional<String> htmlBody = Optional.empty(); public Builder id(String id) { this.id = id; @@ -57,45 +60,59 @@ public class VacationResponse { @JsonProperty("isEnabled") public Builder enabled(boolean enabled) { - isEnabled = enabled; + isEnabled = Optional.of(enabled); return this; } @JsonDeserialize(using = OptionalZonedDateTimeDeserializer.class) public Builder fromDate(Optional<ZonedDateTime> fromDate) { + Preconditions.checkNotNull(fromDate); this.fromDate = fromDate; return this; } @JsonDeserialize(using = OptionalZonedDateTimeDeserializer.class) public Builder toDate(Optional<ZonedDateTime> toDate) { + Preconditions.checkNotNull(toDate); this.toDate = toDate; return this; } - public Builder textBody(String textBody) { + public Builder textBody(Optional<String> textBody) { + Preconditions.checkNotNull(textBody); this.textBody = textBody; return this; } public Builder subject(Optional<String> subject) { + Preconditions.checkNotNull(subject); this.subject = subject; return this; } + public Builder htmlBody(Optional<String> htmlBody) { + Preconditions.checkNotNull(htmlBody); + this.htmlBody = htmlBody; + return this; + } + public Builder fromVacation(Vacation vacation) { this.id = Vacation.ID; - this.isEnabled = vacation.isEnabled(); + this.isEnabled = Optional.of(vacation.isEnabled()); this.fromDate = vacation.getFromDate(); this.toDate = vacation.getToDate(); this.textBody = vacation.getTextBody(); this.subject = vacation.getSubject(); + this.htmlBody = vacation.getHtmlBody(); return this; } public VacationResponse build() { - Preconditions.checkState(textBody != null, "textBody property of vacationResponse object should not be null"); - return new VacationResponse(id, isEnabled, fromDate, toDate, textBody, subject); + boolean enabled = isEnabled.orElse(DEFAULT_DISABLED); + if (enabled) { + Preconditions.checkState(textBody.isPresent() || htmlBody.isPresent(), "textBody or htmlBody property of vacationResponse object should not be null when enabled"); + } + return new VacationResponse(id, enabled, fromDate, toDate, textBody, subject, htmlBody); } } @@ -104,16 +121,18 @@ public class VacationResponse { private final Optional<ZonedDateTime> fromDate; private final Optional<ZonedDateTime> toDate; private final Optional<String> subject; - private final String textBody; + private final Optional<String> textBody; + private final Optional<String> htmlBody; private VacationResponse(String id, boolean isEnabled, Optional<ZonedDateTime> fromDate, Optional<ZonedDateTime> toDate, - String textBody, Optional<String> subject) { + Optional<String> textBody, Optional<String> subject, Optional<String> htmlBody) { this.id = id; this.isEnabled = isEnabled; this.fromDate = fromDate; this.toDate = toDate; this.textBody = textBody; this.subject = subject; + this.htmlBody = htmlBody; } public String getId() { @@ -135,7 +154,7 @@ public class VacationResponse { return toDate; } - public String getTextBody() { + public Optional<String> getTextBody() { return textBody; } @@ -143,6 +162,10 @@ public class VacationResponse { return subject; } + public Optional<String> getHtmlBody() { + return htmlBody; + } + @JsonIgnore public boolean isValid() { return id.equals(Vacation.ID); @@ -161,11 +184,12 @@ public class VacationResponse { && Objects.equals(this.fromDate, that.fromDate) && Objects.equals(this.toDate, that.toDate) && Objects.equals(this.textBody, that.textBody) - && Objects.equals(this.subject, that.subject); + && Objects.equals(this.subject, that.subject) + && Objects.equals(this.htmlBody, that.htmlBody); } @Override public int hashCode() { - return Objects.hash(id, isEnabled, fromDate, toDate, textBody, subject); + return Objects.hash(id, isEnabled, fromDate, toDate, textBody, subject, htmlBody); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetVacationResponseMethodTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetVacationResponseMethodTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetVacationResponseMethodTest.java index 69d1c72..85c9a5e 100644 --- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetVacationResponseMethodTest.java +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/methods/SetVacationResponseMethodTest.java @@ -131,7 +131,7 @@ public class SetVacationResponseMethodTest { .update(ImmutableMap.of(WRONG_ID, VacationResponse.builder() .id(Vacation.ID) .enabled(false) - .textBody(TEXT_BODY) + .textBody(Optional.of(TEXT_BODY)) .build())) .build(); @@ -154,12 +154,12 @@ public class SetVacationResponseMethodTest { .update(ImmutableMap.of(Vacation.ID, VacationResponse.builder() .id(Vacation.ID) .enabled(false) - .textBody(TEXT_BODY) + .textBody(Optional.of(TEXT_BODY)) .build(), WRONG_ID, VacationResponse.builder() .id(Vacation.ID) .enabled(false) - .textBody(TEXT_BODY) + .textBody(Optional.of(TEXT_BODY)) .build())) .build(); @@ -182,7 +182,7 @@ public class SetVacationResponseMethodTest { .update(ImmutableMap.of(Vacation.ID, VacationResponse.builder() .id(Vacation.ID) .enabled(false) - .textBody(TEXT_BODY) + .textBody(Optional.of(TEXT_BODY)) .subject(Optional.of(SUBJECT)) .build())) .build(); @@ -217,7 +217,7 @@ public class SetVacationResponseMethodTest { SetVacationRequest setVacationRequest = SetVacationRequest.builder() .update(ImmutableMap.of(Vacation.ID, VacationResponse.builder() .id(WRONG_ID) - .textBody(TEXT_BODY) + .textBody(Optional.of(TEXT_BODY)) .enabled(false) .build())) .build(); http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetVacationResponseTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetVacationResponseTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetVacationResponseTest.java index 4351513..d448839 100644 --- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetVacationResponseTest.java +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/GetVacationResponseTest.java @@ -20,6 +20,8 @@ package org.apache.james.jmap.model; import static org.assertj.core.api.Assertions.assertThat; +import java.util.Optional; + import org.junit.Test; public class GetVacationResponseTest { @@ -29,7 +31,7 @@ public class GetVacationResponseTest { @Test public void getVacationResponseShouldBeConstructedWithTheRightInformation() { VacationResponse vacationResponse = VacationResponse.builder() - .textBody("Any text") + .textBody(Optional.of("Any text")) .id("singleton") .build(); GetVacationResponse getVacationResponse = GetVacationResponse.builder() http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetVacationRequestTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetVacationRequestTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetVacationRequestTest.java index b46a6bd..96172f3 100644 --- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetVacationRequestTest.java +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/SetVacationRequestTest.java @@ -21,6 +21,7 @@ package org.apache.james.jmap.model; import static org.assertj.core.api.Assertions.assertThat; import java.util.AbstractMap; +import java.util.Optional; import org.apache.commons.lang.NotImplementedException; import org.junit.Test; @@ -33,7 +34,7 @@ public class SetVacationRequestTest { @Test public void setVacationRequestShouldBeConstructedWithTheRightInformation() { - VacationResponse vacationResponse = VacationResponse.builder().id(VACATION_ID).textBody("any message").build(); + VacationResponse vacationResponse = VacationResponse.builder().id(VACATION_ID).textBody(Optional.of("any message")).build(); SetVacationRequest setVacationRequest = SetVacationRequest.builder() .update(ImmutableMap.of(VACATION_ID, vacationResponse)) .build(); @@ -43,7 +44,7 @@ public class SetVacationRequestTest { @Test(expected = NotImplementedException.class) public void accountIdIsNotImplemented() { - VacationResponse vacationResponse = VacationResponse.builder().id(VACATION_ID).textBody("any message").build(); + VacationResponse vacationResponse = VacationResponse.builder().id(VACATION_ID).textBody(Optional.of("any message")).build(); SetVacationRequest.builder() .accountId("any") .update(ImmutableMap.of(VACATION_ID, vacationResponse)) http://git-wip-us.apache.org/repos/asf/james-project/blob/aa877901/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/VacationResponseTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/VacationResponseTest.java b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/VacationResponseTest.java index 63f68bc..503acdf 100644 --- a/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/VacationResponseTest.java +++ b/server/protocols/jmap/src/test/java/org/apache/james/jmap/model/VacationResponseTest.java @@ -20,6 +20,7 @@ package org.apache.james.jmap.model; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.time.ZonedDateTime; import java.util.Optional; @@ -30,6 +31,7 @@ public class VacationResponseTest { public static final String IDENTIFIER = "identifier"; public static final String MESSAGE = "A message explaining I am in vacation"; + public static final String HTML_MESSAGE = "<p>A message explaining I am in vacation</p>"; public static final ZonedDateTime FROM_DATE = ZonedDateTime.parse("2016-04-15T11:56:32.224+07:00[Asia/Vientiane]"); public static final ZonedDateTime TO_DATE = ZonedDateTime.parse("2016-04-16T11:56:32.224+07:00[Asia/Vientiane]"); public static final String SUBJECT = "subject"; @@ -41,24 +43,69 @@ public class VacationResponseTest { .enabled(true) .fromDate(Optional.of(FROM_DATE)) .toDate(Optional.of(TO_DATE)) - .textBody(MESSAGE) + .textBody(Optional.of(MESSAGE)) .subject(Optional.of(SUBJECT)) + .htmlBody(Optional.of(HTML_MESSAGE)) .build(); assertThat(vacationResponse.getId()).isEqualTo(IDENTIFIER); assertThat(vacationResponse.isEnabled()).isEqualTo(true); - assertThat(vacationResponse.getTextBody()).isEqualTo(MESSAGE); + assertThat(vacationResponse.getTextBody()).contains(MESSAGE); + assertThat(vacationResponse.getHtmlBody()).contains(HTML_MESSAGE); assertThat(vacationResponse.getFromDate()).contains(FROM_DATE); assertThat(vacationResponse.getToDate()).contains(TO_DATE); assertThat(vacationResponse.getSubject()).contains(SUBJECT); } - @Test(expected = IllegalStateException.class) - public void vacationResponseBuilderRequiresABodyText() { - VacationResponse.builder() + @Test + public void vacationResponseBuilderRequiresABodyTextOrHtmlWhenEnabled() { + assertThatThrownBy(() -> + VacationResponse.builder() + .id(IDENTIFIER) + .enabled(true) + .build()) + .isInstanceOf(IllegalStateException.class); + } + + @Test + public void vacationResponseBuilderShouldNotRequiresABodyTextOrHtmlWhenDisabled() { + VacationResponse vacationResponse = VacationResponse.builder() + .id(IDENTIFIER) + .enabled(false) + .build(); + + assertThat(vacationResponse.getId()).isEqualTo(IDENTIFIER); + assertThat(vacationResponse.isEnabled()).isEqualTo(false); + assertThat(vacationResponse.getTextBody()).isEmpty(); + assertThat(vacationResponse.getHtmlBody()).isEmpty(); + } + + @Test + public void bodyTextShouldBeEnoughWhenEnabled() { + VacationResponse vacationResponse = VacationResponse.builder() .id(IDENTIFIER) .enabled(true) + .textBody(Optional.of(MESSAGE)) .build(); + + assertThat(vacationResponse.getId()).isEqualTo(IDENTIFIER); + assertThat(vacationResponse.isEnabled()).isEqualTo(true); + assertThat(vacationResponse.getTextBody()).contains(MESSAGE); + assertThat(vacationResponse.getHtmlBody()).isEmpty(); + } + + @Test + public void htmlTextShouldBeEnoughWhenEnabled() { + VacationResponse vacationResponse = VacationResponse.builder() + .id(IDENTIFIER) + .enabled(true) + .htmlBody(Optional.of(MESSAGE)) + .build(); + + assertThat(vacationResponse.getId()).isEqualTo(IDENTIFIER); + assertThat(vacationResponse.isEnabled()).isEqualTo(true); + assertThat(vacationResponse.getTextBody()).isEmpty(); + assertThat(vacationResponse.getHtmlBody()).contains(MESSAGE); } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
