http://git-wip-us.apache.org/repos/asf/james-project/blob/ebcb09a0/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/validation/Quotas.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/validation/Quotas.java b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/validation/Quotas.java new file mode 100644 index 0000000..b088621 --- /dev/null +++ b/server/protocols/webadmin/webadmin-mailbox/src/main/java/org/apache/james/webadmin/validation/Quotas.java @@ -0,0 +1,70 @@ +/**************************************************************** + * 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.webadmin.validation; + +import java.util.Optional; + +import org.apache.james.mailbox.quota.QuotaCount; +import org.apache.james.mailbox.quota.QuotaSize; +import org.apache.james.webadmin.utils.ErrorResponder; +import org.eclipse.jetty.http.HttpStatus; + +public abstract class Quotas { + + public static QuotaCount quotaCount(String serialized) { + return minusOneToEmpty(parseToLong(serialized)) + .map(QuotaCount::count) + .orElse(QuotaCount.unlimited()); + } + + public static QuotaSize quotaSize(String serialized) { + return minusOneToEmpty(parseToLong(serialized)) + .map(QuotaSize::size) + .orElse(QuotaSize.unlimited()); + } + + private static Optional<Long> minusOneToEmpty(long value) { + if (value < -1) { + throw generateInvalidInputError().haltError(); + } + if (value == -1) { + return Optional.empty(); + } + return Optional.of(value); + } + + private static long parseToLong(String serialized) { + try { + return Long.valueOf(serialized); + } catch (IllegalArgumentException e) { + throw generateInvalidInputError() + .cause(e) + .haltError(); + } + } + + private static ErrorResponder generateInvalidInputError() { + return ErrorResponder.builder() + .statusCode(HttpStatus.BAD_REQUEST_400) + .type(ErrorResponder.ErrorType.INVALID_ARGUMENT) + .message("Invalid quota. Need to be an integer value greater or equal to -1"); + } + +}
http://git-wip-us.apache.org/repos/asf/james-project/blob/ebcb09a0/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/dto/QuotaValueDeserializerTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/dto/QuotaValueDeserializerTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/dto/QuotaValueDeserializerTest.java new file mode 100644 index 0000000..2293b50 --- /dev/null +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/dto/QuotaValueDeserializerTest.java @@ -0,0 +1,49 @@ +/**************************************************************** + * 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.webadmin.dto; + +import org.apache.james.mailbox.quota.QuotaCount; +import org.apache.james.mailbox.quota.QuotaSize; +import org.apache.james.webadmin.utils.JsonExtractException; +import org.apache.james.webadmin.utils.JsonExtractor; +import org.assertj.core.api.Assertions; +import org.junit.Test; + +import com.fasterxml.jackson.databind.module.SimpleModule; + +public class QuotaValueDeserializerTest { + + @Test + public void objectDeserializeShouldContainGivenValues() throws JsonExtractException { + String payload = "{\"count\":52,\"size\":42}"; + QuotaDTO actual = new JsonExtractor<>(QuotaDTO.class, + new SimpleModule() + .addDeserializer(QuotaCount.class, new QuotaValueDeserializer<>(QuotaCount.unlimited(), QuotaCount::count)) + .addDeserializer(QuotaSize.class, new QuotaValueDeserializer<>(QuotaSize.unlimited(), QuotaSize::size)) + ).parse(payload); + Assertions.assertThat(actual) + .isEqualTo( + QuotaDTO + .builder() + .count(java.util.Optional.of(QuotaCount.count(52))) + .size(java.util.Optional.of(QuotaSize.size(42))) + .build()); + } + +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/james-project/blob/ebcb09a0/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java index cb8f745..68dd0fa 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/GlobalQuotaRoutesTest.java @@ -20,18 +20,23 @@ package org.apache.james.webadmin.routes; import static com.jayway.restassured.RestAssured.given; +import static com.jayway.restassured.RestAssured.when; import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION; import static org.assertj.core.api.Assertions.assertThat; import java.util.Map; +import org.apache.james.mailbox.exception.MailboxException; import org.apache.james.mailbox.inmemory.quota.InMemoryPerUserMaxQuotaManager; -import org.apache.james.mailbox.model.Quota; +import org.apache.james.mailbox.quota.QuotaCount; +import org.apache.james.mailbox.quota.QuotaSize; import org.apache.james.metrics.logger.DefaultMetricFactory; import org.apache.james.webadmin.WebAdminServer; import org.apache.james.webadmin.WebAdminUtils; +import org.apache.james.webadmin.jackson.QuotaModule; import org.apache.james.webadmin.service.GlobalQuotaService; import org.apache.james.webadmin.utils.JsonTransformer; +import org.assertj.core.api.SoftAssertions; import org.eclipse.jetty.http.HttpStatus; import org.junit.After; import org.junit.Before; @@ -51,7 +56,7 @@ public class GlobalQuotaRoutesTest { maxQuotaManager = new InMemoryPerUserMaxQuotaManager(); webAdminServer = WebAdminUtils.createWebAdminServer( new DefaultMetricFactory(), - new GlobalQuotaRoutes(new GlobalQuotaService(maxQuotaManager), new JsonTransformer())); + new GlobalQuotaRoutes(new GlobalQuotaService(maxQuotaManager), new JsonTransformer(new QuotaModule()))); webAdminServer.configure(NO_CONFIGURATION); webAdminServer.await(); @@ -65,26 +70,20 @@ public class GlobalQuotaRoutesTest { } @Test - public void getCountQuotaCountShouldReturnUnlimitedByDefault() { - long quota = - given() - .get("/quota/count") - .then() - .statusCode(HttpStatus.OK_200) - .contentType(ContentType.JSON) - .extract() - .as(Long.class); - - assertThat(quota).isEqualTo(Quota.UNLIMITED); + public void getQuotaCountShouldReturnNoContentWhenUndefined() { + when() + .get("/quota/count") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); } @Test public void getCountShouldReturnStoredValue() throws Exception { int value = 42; - maxQuotaManager.setDefaultMaxMessage(value); + maxQuotaManager.setDefaultMaxMessage(QuotaCount.count(value)); Long actual = - given() + when() .get("/quota/count") .then() .statusCode(HttpStatus.OK_200) @@ -99,6 +98,7 @@ public class GlobalQuotaRoutesTest { public void putCountShouldRejectInvalid() { Map<String, Object> errors = given() .body("invalid") + .when() .put("/quota/count") .then() .statusCode(HttpStatus.BAD_REQUEST_400) @@ -108,17 +108,19 @@ public class GlobalQuotaRoutesTest { .jsonPath() .getMap("."); - assertThat(errors) - .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) - .containsEntry("type", "InvalidArgument") - .containsEntry("message", "Invalid quota. Need to be an integer value greater than 0") - .containsEntry("cause", "For input string: \"invalid\""); + SoftAssertions.assertSoftly(softly -> + softly.assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1") + .containsEntry("cause", "For input string: \"invalid\"")); } @Test public void putCountShouldRejectNegative() { Map<String, Object> errors = given() - .body("-1") + .body("-2") + .when() .put("/quota/count") .then() .statusCode(HttpStatus.BAD_REQUEST_400) @@ -128,57 +130,67 @@ public class GlobalQuotaRoutesTest { .jsonPath() .getMap("."); - assertThat(errors) - .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) - .containsEntry("type", "InvalidArgument") - .containsEntry("message", "Invalid quota. Need to be an integer value greater than 0"); + SoftAssertions.assertSoftly(softly -> + softly + .assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1")); } @Test + public void putCountShouldHandleMinusOneAsInfinite() throws MailboxException { + given() + .body("-1") + .when() + .put("/quota/count") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(maxQuotaManager.getDefaultMaxMessage()).contains(QuotaCount.unlimited()); + } + + + @Test public void putCountShouldAcceptValidValue() throws Exception { given() .body("42") + .when() .put("/quota/count") .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getDefaultMaxMessage()).isEqualTo(42); + assertThat(maxQuotaManager.getDefaultMaxMessage()).contains(QuotaCount.count(42)); } @Test public void deleteCountShouldSetQuotaToUnlimited() throws Exception { - maxQuotaManager.setDefaultMaxMessage(42); + maxQuotaManager.setDefaultMaxMessage(QuotaCount.count(42)); - given() + when() .delete("/quota/count") .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getDefaultMaxMessage()).isEqualTo(Quota.UNLIMITED); + assertThat(maxQuotaManager.getDefaultMaxMessage()).isEmpty(); } @Test - public void getSizeQuotaCountShouldReturnUnlimitedByDefault() { - long quota = - given() - .get("/quota/size") - .then() - .statusCode(HttpStatus.OK_200) - .contentType(ContentType.JSON) - .extract() - .as(Long.class); - - assertThat(quota).isEqualTo(Quota.UNLIMITED); + public void getQuotaSizeShouldReturnNothingByDefault() { + when() + .get("/quota/size") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); } @Test public void getSizeShouldReturnStoredValue() throws Exception { long value = 42; - maxQuotaManager.setDefaultMaxStorage(value); + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(value)); long quota = - given() + when() .get("/quota/size") .then() .statusCode(HttpStatus.OK_200) @@ -193,6 +205,7 @@ public class GlobalQuotaRoutesTest { public void putSizeShouldRejectInvalid() { Map<String, Object> errors = given() .body("invalid") + .when() .put("/quota/size") .then() .statusCode(HttpStatus.BAD_REQUEST_400) @@ -202,17 +215,32 @@ public class GlobalQuotaRoutesTest { .jsonPath() .getMap("."); - assertThat(errors) - .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) - .containsEntry("type", "InvalidArgument") - .containsEntry("message", "Invalid quota. Need to be an integer value greater than 0") - .containsEntry("cause", "For input string: \"invalid\""); + SoftAssertions.assertSoftly(softly -> + softly + .assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1") + .containsEntry("cause", "For input string: \"invalid\"")); + } + + @Test + public void putSizeShouldHandleMinusOneAsInfinite() throws MailboxException { + given() + .body("-1") + .when() + .put("/quota/size") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(maxQuotaManager.getDefaultMaxStorage()).contains(QuotaSize.unlimited()); } @Test public void putSizeShouldRejectNegative() { Map<String, Object> errors = given() - .body("-1") + .body("-2") + .when() .put("/quota/size") .then() .statusCode(HttpStatus.BAD_REQUEST_400) @@ -222,44 +250,47 @@ public class GlobalQuotaRoutesTest { .jsonPath() .getMap("."); - assertThat(errors) - .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) - .containsEntry("type", "InvalidArgument") - .containsEntry("message", "Invalid quota. Need to be an integer value greater than 0"); + SoftAssertions.assertSoftly(softly -> + softly + .assertThat(errors) + .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) + .containsEntry("type", "InvalidArgument") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1")); } @Test public void putSizeShouldAcceptValidValue() throws Exception { given() .body("42") + .when() .put("/quota/size") .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getDefaultMaxStorage()).isEqualTo(42); + assertThat(maxQuotaManager.getDefaultMaxStorage()).contains(QuotaSize.size(42)); } @Test public void deleteSizeShouldSetQuotaToUnlimited() throws Exception { - maxQuotaManager.setDefaultMaxStorage(42); + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(42)); - given() + when() .delete("/quota/count") .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getDefaultMaxMessage()).isEqualTo(Quota.UNLIMITED); + assertThat(maxQuotaManager.getDefaultMaxMessage()).isEmpty(); } @Test public void getQuotaShouldReturnBothWhenValueSpecified() throws Exception { int maxStorage = 42; int maxMessage = 52; - maxQuotaManager.setDefaultMaxStorage(maxStorage); - maxQuotaManager.setDefaultMaxMessage(maxMessage); + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(maxStorage)); + maxQuotaManager.setDefaultMaxMessage(QuotaCount.count(maxMessage)); JsonPath jsonPath = - given() + when() .get("/quota") .then() .statusCode(HttpStatus.OK_200) @@ -267,14 +298,16 @@ public class GlobalQuotaRoutesTest { .extract() .jsonPath(); - assertThat(jsonPath.getLong("size")).isEqualTo(maxStorage); - assertThat(jsonPath.getLong("count")).isEqualTo(maxMessage); + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(jsonPath.getLong("size")).isEqualTo(maxStorage); + softly.assertThat(jsonPath.getLong("count")).isEqualTo(maxMessage); + }); } @Test - public void getQuotaShouldReturnBothDefaultValues() { + public void getQuotaShouldReturnNothingWhenNothingSet() { JsonPath jsonPath = - given() + when() .get("/quota") .then() .statusCode(HttpStatus.OK_200) @@ -282,17 +315,18 @@ public class GlobalQuotaRoutesTest { .extract() .jsonPath(); - assertThat(jsonPath.getLong("size")).isEqualTo(Quota.UNLIMITED); - assertThat(jsonPath.getLong("count")).isEqualTo(Quota.UNLIMITED); + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(jsonPath.getObject("size", Long.class)).isNull(); + softly.assertThat(jsonPath.getObject("count", Long.class)).isNull(); + }); } @Test - public void getQuotaShouldReturnBothWhenNoCount() throws Exception { - int maxStorage = 42; - maxQuotaManager.setDefaultMaxStorage(maxStorage); + public void getQuotaShouldReturnOnlySizeWhenNoCount() throws Exception { + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(42)); JsonPath jsonPath = - given() + when() .get("/quota") .then() .statusCode(HttpStatus.OK_200) @@ -300,51 +334,111 @@ public class GlobalQuotaRoutesTest { .extract() .jsonPath(); - assertThat(jsonPath.getLong("size")).isEqualTo(maxStorage); - assertThat(jsonPath.getLong("count")).isEqualTo(Quota.UNLIMITED); + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(jsonPath.getLong("size")).isEqualTo(42); + softly.assertThat(jsonPath.getObject("count", Long.class)).isNull(); + }); } @Test - public void getQuotaShouldReturnBothWhenNoSize() throws Exception { + public void getQuotaShouldReturnOnlyCountWhenNoSize() throws Exception { int maxMessage = 42; - maxQuotaManager.setDefaultMaxMessage(maxMessage); + maxQuotaManager.setDefaultMaxMessage(QuotaCount.count(maxMessage)); JsonPath jsonPath = - given() + when() .get("/quota") - .then() + .then() .statusCode(HttpStatus.OK_200) .contentType(ContentType.JSON) .extract() .jsonPath(); - assertThat(jsonPath.getLong("size")).isEqualTo(Quota.UNLIMITED); - assertThat(jsonPath.getLong("count")).isEqualTo(maxMessage); + SoftAssertions.assertSoftly(softly -> { + softly.assertThat(jsonPath.getObject("size", Long.class)).isNull(); + softly.assertThat(jsonPath.getLong("count")).isEqualTo(maxMessage); + }); } @Test public void putQuotaShouldUpdateBothQuota() throws Exception { given() .body("{\"count\":52,\"size\":42}") + .when() .put("/quota") .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getDefaultMaxMessage()).isEqualTo(52); - assertThat(maxQuotaManager.getDefaultMaxStorage()).isEqualTo(42); + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(maxQuotaManager.getDefaultMaxMessage()).contains(QuotaCount.count(52)); + softly.assertThat(maxQuotaManager.getDefaultMaxStorage()).contains(QuotaSize.size(42)); } @Test - public void putQuotaShouldBeAbleToRemoveBothQuota() throws Exception { + public void putQuotaShouldSetBothQuotaToInfinite() throws Exception { given() .body("{\"count\":-1,\"size\":-1}") + .when() + .put("/quota") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(maxQuotaManager.getDefaultMaxMessage()).contains(QuotaCount.unlimited()); + softly.assertThat(maxQuotaManager.getDefaultMaxStorage()).contains(QuotaSize.unlimited()); + } + + @Test + public void putQuotaShouldUnsetCountWhenNull() throws Exception { + maxQuotaManager.setDefaultMaxMessage(QuotaCount.count(42)); + given() + .body("{\"count\":null,\"size\":43}") + .when() + .put("/quota") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(maxQuotaManager.getDefaultMaxMessage()).isEmpty(); + } + + @Test + public void putQuotaShouldUnsetSizeWhenNull() throws Exception { + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(44)); + given() + .body("{\"count\":45,\"size\":null}") + .when() + .put("/quota") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(maxQuotaManager.getDefaultMaxStorage()).isEmpty(); + } + + @Test + public void putQuotaShouldUnsetCountWhenAbsent() throws Exception { + maxQuotaManager.setDefaultMaxMessage(QuotaCount.count(42)); + given() + .body("{\"size\":43}") + .when() + .put("/quota") + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(maxQuotaManager.getDefaultMaxMessage()).isEmpty(); + } + + @Test + public void putQuotaShouldUnsetSizeWhenAbsent() throws Exception { + maxQuotaManager.setDefaultMaxStorage(QuotaSize.size(44)); + given() + .body("{\"count\":45}") + .when() .put("/quota") .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getDefaultMaxMessage()).isEqualTo(Quota.UNLIMITED); - assertThat(maxQuotaManager.getDefaultMaxStorage()).isEqualTo(Quota.UNLIMITED); + assertThat(maxQuotaManager.getDefaultMaxStorage()).isEmpty(); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/ebcb09a0/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java index 86a09af..da4785c 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/routes/UserQuotaRoutesTest.java @@ -21,7 +21,6 @@ package org.apache.james.webadmin.routes; import static com.jayway.restassured.RestAssured.given; import static com.jayway.restassured.RestAssured.when; -import static org.apache.james.mailbox.model.Quota.UNLIMITED; import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION; import static org.assertj.core.api.Assertions.assertThat; @@ -31,11 +30,14 @@ import org.apache.james.dnsservice.api.InMemoryDNSService; import org.apache.james.domainlist.memory.MemoryDomainList; import org.apache.james.mailbox.inmemory.quota.InMemoryPerUserMaxQuotaManager; import org.apache.james.mailbox.model.QuotaRoot; +import org.apache.james.mailbox.quota.QuotaCount; +import org.apache.james.mailbox.quota.QuotaSize; import org.apache.james.metrics.api.NoopMetricFactory; import org.apache.james.user.api.UsersRepositoryException; import org.apache.james.user.memory.MemoryUsersRepository; import org.apache.james.webadmin.WebAdminServer; import org.apache.james.webadmin.WebAdminUtils; +import org.apache.james.webadmin.jackson.QuotaModule; import org.apache.james.webadmin.service.UserQuotaService; import org.apache.james.webadmin.utils.JsonTransformer; import org.eclipse.jetty.http.HttpStatus; @@ -44,6 +46,7 @@ import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import com.google.common.collect.ImmutableSet; import com.jayway.restassured.RestAssured; import com.jayway.restassured.http.ContentType; import com.jayway.restassured.path.json.JsonPath; @@ -71,7 +74,8 @@ public class UserQuotaRoutesTest { usersRepository.setDomainList(memoryDomainList); usersRepository.addUser(BOB, PASSWORD); UserQuotaService userQuotaService = new UserQuotaService(maxQuotaManager); - UserQuotaRoutes userQuotaRoutes = new UserQuotaRoutes(usersRepository, userQuotaService, new JsonTransformer()); + QuotaModule quotaModule = new QuotaModule(); + UserQuotaRoutes userQuotaRoutes = new UserQuotaRoutes(usersRepository, userQuotaService, new JsonTransformer(quotaModule), ImmutableSet.of(quotaModule)); webAdminServer = WebAdminUtils.createWebAdminServer( new NoopMetricFactory(), userQuotaRoutes); @@ -97,23 +101,17 @@ public class UserQuotaRoutesTest { } @Test - public void getCountShouldReturnUnlimitedByDefault() throws UsersRepositoryException { - long quota = - given() - .get(QUOTA_USERS + "/" + BOB + "/" + COUNT) - .then() - .statusCode(HttpStatus.OK_200) - .contentType(ContentType.JSON) - .extract() - .as(Long.class); - - assertThat(quota).isEqualTo(UNLIMITED); + public void getCountShouldReturnNoContentByDefault() throws UsersRepositoryException { + given() + .get(QUOTA_USERS + "/" + BOB + "/" + COUNT) + .then() + .statusCode(HttpStatus.NO_CONTENT_204); } @Test public void getCountShouldReturnStoredValue() throws Exception { int value = 42; - maxQuotaManager.setMaxMessage(QuotaRoot.forUser(BOB), value); + maxQuotaManager.setMaxMessage(QuotaRoot.forUser(BOB), QuotaCount.count(value)); Long actual = given() @@ -154,14 +152,26 @@ public class UserQuotaRoutesTest { assertThat(errors) .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) .containsEntry("type", "InvalidArgument") - .containsEntry("message", "Invalid quota. Need to be an integer value greater than 0") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1") .containsEntry("cause", "For input string: \"invalid\""); } @Test - public void putCountShouldRejectNegative() throws Exception { - Map<String, Object> errors = given() + public void putCountShouldSetToInfiniteWhenMinusOne() throws Exception { + given() .body("-1") + .when() + .put(QUOTA_USERS + "/" + BOB + "/" + COUNT) + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).contains(QuotaCount.unlimited()); + } + + @Test + public void putCountShouldRejectNegativeOtherThanMinusOne() throws Exception { + Map<String, Object> errors = given() + .body("-2") .put(QUOTA_USERS + "/" + BOB + "/" + COUNT) .then() .statusCode(HttpStatus.BAD_REQUEST_400) @@ -174,7 +184,7 @@ public class UserQuotaRoutesTest { assertThat(errors) .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) .containsEntry("type", "InvalidArgument") - .containsEntry("message", "Invalid quota. Need to be an integer value greater than 0"); + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1"); } @Test @@ -185,10 +195,9 @@ public class UserQuotaRoutesTest { .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).isEqualTo(42); + assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).contains(QuotaCount.count(42)); } - @Test @Ignore("no link between quota and mailbox for now") public void putCountShouldRejectTooSmallValue() throws Exception { @@ -211,15 +220,15 @@ public class UserQuotaRoutesTest { @Test - public void deleteCountShouldSetQuotaToUnlimited() throws Exception { - maxQuotaManager.setMaxMessage(QuotaRoot.forUser(BOB), 42); + public void deleteCountShouldSetQuotaToEmpty() throws Exception { + maxQuotaManager.setMaxMessage(QuotaRoot.forUser(BOB), QuotaCount.count(42)); given() .delete(QUOTA_USERS + "/" + BOB + "/" + COUNT) .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).isEqualTo(UNLIMITED); + assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).isEmpty(); } @Test @@ -231,23 +240,17 @@ public class UserQuotaRoutesTest { } @Test - public void getSizeShouldReturnUnlimitedByDefault() throws UsersRepositoryException { - long quota = - given() - .get(QUOTA_USERS + "/" + BOB + "/" + SIZE) - .then() - .statusCode(HttpStatus.OK_200) - .contentType(ContentType.JSON) - .extract() - .as(Long.class); - - assertThat(quota).isEqualTo(UNLIMITED); + public void getSizeShouldReturnNoContentByDefault() throws UsersRepositoryException { + when() + .get(QUOTA_USERS + "/" + BOB + "/" + SIZE) + .then() + .statusCode(HttpStatus.NO_CONTENT_204); } @Test public void getSizeShouldReturnStoredValue() throws Exception { long value = 42; - maxQuotaManager.setMaxStorage(QuotaRoot.forUser(BOB), value); + maxQuotaManager.setMaxStorage(QuotaRoot.forUser(BOB), QuotaSize.size(value)); long quota = @@ -278,7 +281,7 @@ public class UserQuotaRoutesTest { assertThat(errors) .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) .containsEntry("type", "InvalidArgument") - .containsEntry("message", "Invalid quota. Need to be an integer value greater than 0") + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1") .containsEntry("cause", "For input string: \"invalid\""); } @@ -293,9 +296,21 @@ public class UserQuotaRoutesTest { } @Test - public void putSizeShouldRejectNegative() throws Exception { - Map<String, Object> errors = given() + public void putSizeShouldSetToInfiniteWhenMinusOne() throws Exception { + given() .body("-1") + .when() + .put(QUOTA_USERS + "/" + BOB + "/" + SIZE) + .then() + .statusCode(HttpStatus.NO_CONTENT_204); + + assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).contains(QuotaSize.unlimited()); + } + + @Test + public void putSizeShouldRejectNegativeOtherThanMinusOne() throws Exception { + Map<String, Object> errors = given() + .body("-2") .put(QUOTA_USERS + "/" + BOB + "/" + SIZE) .then() .statusCode(HttpStatus.BAD_REQUEST_400) @@ -308,18 +323,19 @@ public class UserQuotaRoutesTest { assertThat(errors) .containsEntry("statusCode", HttpStatus.BAD_REQUEST_400) .containsEntry("type", "InvalidArgument") - .containsEntry("message", "Invalid quota. Need to be an integer value greater than 0"); + .containsEntry("message", "Invalid quota. Need to be an integer value greater or equal to -1"); } @Test public void putSizeShouldAcceptValidValue() throws Exception { given() .body("42") + .when() .put(QUOTA_USERS + "/" + BOB + "/" + SIZE) .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).isEqualTo(42); + assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).contains(QuotaSize.size(42)); } @Test @@ -331,15 +347,15 @@ public class UserQuotaRoutesTest { } @Test - public void deleteSizeShouldSetQuotaToUnlimited() throws Exception { - maxQuotaManager.setMaxStorage(QuotaRoot.forUser(BOB), 42); + public void deleteSizeShouldSetQuotaToEmpty() throws Exception { + maxQuotaManager.setMaxStorage(QuotaRoot.forUser(BOB), QuotaSize.size(42)); given() .delete(QUOTA_USERS + "/" + BOB + "/" + SIZE) .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).isEqualTo(UNLIMITED); + assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).isEmpty(); } @Test @@ -354,8 +370,8 @@ public class UserQuotaRoutesTest { public void getQuotaShouldReturnBothWhenValueSpecified() throws Exception { int maxStorage = 42; int maxMessage = 52; - maxQuotaManager.setMaxStorage(QuotaRoot.forUser(BOB), maxStorage); - maxQuotaManager.setMaxMessage(QuotaRoot.forUser(BOB), maxMessage); + maxQuotaManager.setMaxStorage(QuotaRoot.forUser(BOB), QuotaSize.size(maxStorage)); + maxQuotaManager.setMaxMessage(QuotaRoot.forUser(BOB), QuotaCount.count(maxMessage)); JsonPath jsonPath = given() @@ -371,7 +387,7 @@ public class UserQuotaRoutesTest { } @Test - public void getQuotaShouldReturnBothDefaultValues() throws Exception { + public void getQuotaShouldReturnBothEmptyWhenDefaultValues() throws Exception { JsonPath jsonPath = given() .get(QUOTA_USERS + "/" + BOB) @@ -381,14 +397,14 @@ public class UserQuotaRoutesTest { .extract() .jsonPath(); - assertThat(jsonPath.getLong(SIZE)).isEqualTo(UNLIMITED); - assertThat(jsonPath.getLong(COUNT)).isEqualTo(UNLIMITED); + assertThat(jsonPath.getObject(SIZE, Long.class)).isNull(); + assertThat(jsonPath.getObject(COUNT, Long.class)).isNull(); } @Test - public void getQuotaShouldReturnBothWhenNoCount() throws Exception { + public void getQuotaShouldReturnSizeWhenNoCount() throws Exception { int maxStorage = 42; - maxQuotaManager.setMaxStorage(QuotaRoot.forUser(BOB), maxStorage); + maxQuotaManager.setMaxStorage(QuotaRoot.forUser(BOB), QuotaSize.size(maxStorage)); JsonPath jsonPath = given() @@ -400,13 +416,13 @@ public class UserQuotaRoutesTest { .jsonPath(); assertThat(jsonPath.getLong(SIZE)).isEqualTo(maxStorage); - assertThat(jsonPath.getLong(COUNT)).isEqualTo(UNLIMITED); + assertThat(jsonPath.getObject(COUNT, Long.class)).isNull(); } @Test public void getQuotaShouldReturnBothWhenNoSize() throws Exception { int maxMessage = 42; - maxQuotaManager.setMaxMessage(QuotaRoot.forUser(BOB), maxMessage); + maxQuotaManager.setMaxMessage(QuotaRoot.forUser(BOB), QuotaCount.count(maxMessage)); JsonPath jsonPath = @@ -418,7 +434,7 @@ public class UserQuotaRoutesTest { .extract() .jsonPath(); - assertThat(jsonPath.getLong(SIZE)).isEqualTo(UNLIMITED); + assertThat(jsonPath.getObject(SIZE, Long.class)).isNull(); assertThat(jsonPath.getLong(COUNT)).isEqualTo(maxMessage); } @@ -433,25 +449,25 @@ public class UserQuotaRoutesTest { @Test public void putQuotaShouldUpdateBothQuota() throws Exception { given() - .body("{\"" + COUNT + "\":52,\"" + SIZE + "\":42}") + .body("{\"count\":52,\"size\":42}") .put(QUOTA_USERS + "/" + BOB) .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).isEqualTo(52); - assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).isEqualTo(42); + assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).contains(QuotaCount.count(52)); + assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).contains(QuotaSize.size(42)); } @Test public void putQuotaShouldBeAbleToRemoveBothQuota() throws Exception { given() - .body("{\"" + COUNT + "\":-1,\"" + SIZE + "\":-1}") + .body("{\"count\":null,\"count\":null}") .put(QUOTA_USERS + "/" + BOB) .then() .statusCode(HttpStatus.NO_CONTENT_204); - assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).isEqualTo(UNLIMITED); - assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).isEqualTo(UNLIMITED); + assertThat(maxQuotaManager.getMaxMessage(QuotaRoot.forUser(BOB))).isEmpty(); + assertThat(maxQuotaManager.getMaxStorage(QuotaRoot.forUser(BOB))).isEmpty(); } } http://git-wip-us.apache.org/repos/asf/james-project/blob/ebcb09a0/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/validation/QuotaValueTest.java ---------------------------------------------------------------------- diff --git a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/validation/QuotaValueTest.java b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/validation/QuotaValueTest.java index 1cc2330..b57a754 100644 --- a/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/validation/QuotaValueTest.java +++ b/server/protocols/webadmin/webadmin-mailbox/src/test/java/org/apache/james/webadmin/validation/QuotaValueTest.java @@ -22,6 +22,8 @@ package org.apache.james.webadmin.validation; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import org.apache.james.mailbox.quota.QuotaCount; +import org.apache.james.mailbox.quota.QuotaSize; import org.junit.Test; import spark.HaltException; @@ -30,50 +32,60 @@ public class QuotaValueTest { @Test public void quotaCountShouldThrowWhenNotANumber() { - assertThatThrownBy(() -> QuotaValue.quotaCount("invalid")) + assertThatThrownBy(() -> Quotas.quotaCount("invalid")) .isInstanceOf(HaltException.class); } @Test public void quotaCountShouldParseZero() { - assertThat(QuotaValue.quotaCount("0").asLong()) + assertThat(Quotas.quotaCount("0").asLong()) .isEqualTo(0); } @Test public void quotaCountShouldParsePositiveValue() { - assertThat(QuotaValue.quotaCount("42").asLong()) + assertThat(Quotas.quotaCount("42").asLong()) .isEqualTo(42); } @Test + public void quotaCountShouldBeUnlimitedOnMinusOne() { + assertThat(Quotas.quotaCount("-1")).isEqualTo(QuotaCount.unlimited()); + } + + @Test public void quotaCountShouldThrowOnNegativeNumber() { - assertThatThrownBy(() -> QuotaValue.quotaCount("-1")) + assertThatThrownBy(() -> Quotas.quotaCount("-2")) .isInstanceOf(HaltException.class); } @Test public void quotaSizeShouldThrowWhenNotANumber() { - assertThatThrownBy(() -> QuotaValue.quotaSize("invalid")) + assertThatThrownBy(() -> Quotas.quotaSize("invalid")) .isInstanceOf(HaltException.class); } @Test public void quotaSizeShouldParseZero() { - assertThat(QuotaValue.quotaSize("0").asLong()) + assertThat(Quotas.quotaSize("0").asLong()) .isEqualTo(0); } @Test public void quotaSizeShouldParsePositiveValue() { - assertThat(QuotaValue.quotaSize("42").asLong()) + assertThat(Quotas.quotaSize("42").asLong()) .isEqualTo(42); } @Test + public void quotaSizeShouldBeUnlimitedOnMinusOne() { + assertThat(Quotas.quotaSize("-1")).isEqualTo(QuotaSize.unlimited()); + + } + + @Test public void quotaSizeShouldThrowOnNegativeNumber() { - assertThatThrownBy(() -> QuotaValue.quotaSize("-1")) + assertThatThrownBy(() -> Quotas.quotaSize("-2")) .isInstanceOf(HaltException.class); } - } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
