You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by bt...@apache.org on 2019/05/16 08:48:17 UTC
[james-project] 02/23: JAMES-2149 Domain routes should handle
aliases
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-project.git
commit abaa0021c6c9f2d17d84f84052b77f0959c984d0
Author: Benoit Tellier <bt...@linagora.com>
AuthorDate: Mon May 13 17:50:40 2019 +0700
JAMES-2149 Domain routes should handle aliases
Add the following CRUD routes and their unit tests:
GET /domains/domain.tld/aliases
PUT /domains/domain.tld/aliases/alias.domain.tld
DELETE /domains/domain.tld/aliases/alias.domain.tld
---
.../james/webadmin/dto/DomainAliasResponse.java | 51 ++++
.../james/webadmin/routes/DomainsRoutes.java | 162 +++++++++++--
.../webadmin/dto/DomainAliasResponseTest.java | 31 +++
.../james/webadmin/routes/DomainsRoutesTest.java | 257 ++++++++++++++++++++-
4 files changed, 479 insertions(+), 22 deletions(-)
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DomainAliasResponse.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DomainAliasResponse.java
new file mode 100644
index 0000000..141faf9
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/dto/DomainAliasResponse.java
@@ -0,0 +1,51 @@
+/****************************************************************
+ * 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 java.util.Objects;
+
+import org.apache.james.rrt.lib.MappingSource;
+
+public class DomainAliasResponse {
+ private final MappingSource source;
+
+ public DomainAliasResponse(MappingSource source) {
+ this.source = source;
+ }
+
+ public String getSource() {
+ return source.getFixedDomain();
+ }
+
+ @Override
+ public final boolean equals(Object o) {
+ if (o instanceof DomainAliasResponse) {
+ DomainAliasResponse that = (DomainAliasResponse) o;
+
+ return Objects.equals(this.source, that.source);
+ }
+ return false;
+ }
+
+ @Override
+ public final int hashCode() {
+ return Objects.hash(source);
+ }
+}
diff --git a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainsRoutes.java b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainsRoutes.java
index 321b2c7..8625498 100644
--- a/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainsRoutes.java
+++ b/server/protocols/webadmin/webadmin-data/src/main/java/org/apache/james/webadmin/routes/DomainsRoutes.java
@@ -34,8 +34,13 @@ import javax.ws.rs.Produces;
import org.apache.james.core.Domain;
import org.apache.james.domainlist.api.DomainList;
import org.apache.james.domainlist.api.DomainListException;
+import org.apache.james.rrt.api.RecipientRewriteTable;
+import org.apache.james.rrt.api.RecipientRewriteTableException;
+import org.apache.james.rrt.lib.Mapping;
+import org.apache.james.rrt.lib.MappingSource;
import org.apache.james.webadmin.Constants;
import org.apache.james.webadmin.Routes;
+import org.apache.james.webadmin.dto.DomainAliasResponse;
import org.apache.james.webadmin.utils.ErrorResponder;
import org.apache.james.webadmin.utils.ErrorResponder.ErrorType;
import org.apache.james.webadmin.utils.JsonTransformer;
@@ -43,13 +48,18 @@ import org.eclipse.jetty.http.HttpStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import com.github.steveash.guavate.Guavate;
import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
+import spark.HaltException;
import spark.Request;
import spark.Response;
import spark.Service;
@@ -58,22 +68,31 @@ import spark.Service;
@Path(DomainsRoutes.DOMAINS)
@Produces("application/json")
public class DomainsRoutes implements Routes {
-
- private static final String DOMAIN_NAME = ":domainName";
- private static final Logger LOGGER = LoggerFactory.getLogger(DomainsRoutes.class);
+ @FunctionalInterface
+ interface MappingOperation {
+ void perform(MappingSource mappingSource, Mapping mapping) throws RecipientRewriteTableException;
+ }
public static final String DOMAINS = "/domains";
- public static final String SPECIFIC_DOMAIN = DOMAINS + SEPARATOR + DOMAIN_NAME;
- public static final int MAXIMUM_DOMAIN_SIZE = 256;
-
+ private static final Logger LOGGER = LoggerFactory.getLogger(DomainsRoutes.class);
+ private static final String DOMAIN_NAME = ":domainName";
+ private static final String SOURCE_DOMAIN = ":sourceDomain";
+ private static final String DESTINATION_DOMAIN = ":destinationDomain";
+ private static final String SPECIFIC_DOMAIN = DOMAINS + SEPARATOR + DOMAIN_NAME;
+ private static final String ALIASES = "aliases";
+ private static final String DOMAIN_ALIASES = SPECIFIC_DOMAIN + SEPARATOR + ALIASES;
+ private static final String SPECIFIC_ALIAS = DOMAINS + SEPARATOR + DESTINATION_DOMAIN + SEPARATOR + ALIASES + SEPARATOR + SOURCE_DOMAIN;
+ private static final int MAXIMUM_DOMAIN_SIZE = 256;
private final DomainList domainList;
+ private final RecipientRewriteTable recipientRewriteTable;
private final JsonTransformer jsonTransformer;
private Service service;
@Inject
- public DomainsRoutes(DomainList domainList, JsonTransformer jsonTransformer) {
+ public DomainsRoutes(DomainList domainList, RecipientRewriteTable recipientRewriteTable, JsonTransformer jsonTransformer) {
this.domainList = domainList;
+ this.recipientRewriteTable = recipientRewriteTable;
this.jsonTransformer = jsonTransformer;
}
@@ -86,13 +105,16 @@ public class DomainsRoutes implements Routes {
public void define(Service service) {
this.service = service;
+ // Domain endpoints
defineGetDomains();
-
defineDomainExists();
-
defineAddDomain();
-
defineDeleteDomain();
+
+ // Domain aliases endpoints
+ defineListAliases(service);
+ defineAddAlias(service);
+ defineRemoveAlias(service);
}
@DELETE
@@ -156,9 +178,59 @@ public class DomainsRoutes implements Routes {
jsonTransformer);
}
+ @GET
+ @Path("/{domainName}/aliases")
+ @ApiOperation(value = "Getting all aliases for a domain")
+ @ApiImplicitParams({
+ @ApiImplicitParam(required = true, dataType = "string", name = "domainName", paramType = "path")
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.OK_200, message = "OK", response = List.class),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public void defineListAliases(Service service) {
+ service.get(DOMAIN_ALIASES, this::listDomainAliases, jsonTransformer);
+ }
+
+ @DELETE
+ @Path("/{destinationDomain}/aliases/{sourceDomain}")
+ @ApiOperation(value = "Remove an alias for a specific domain")
+ @ApiImplicitParams({
+ @ApiImplicitParam(required = true, dataType = "string", name = "sourceDomain", paramType = "path"),
+ @ApiImplicitParam(required = true, dataType = "string", name = "destinationDomain", paramType = "path")
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK", response = List.class),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public void defineRemoveAlias(Service service) {
+ service.delete(SPECIFIC_ALIAS, this::removeDomainAlias, jsonTransformer);
+ }
+
+ @PUT
+ @Path("/{destinationDomain}/aliases/{sourceDomain}")
+ @ApiOperation(value = "Add an alias for a specific domain")
+ @ApiImplicitParams({
+ @ApiImplicitParam(required = true, dataType = "string", name = "sourceDomain", paramType = "path"),
+ @ApiImplicitParam(required = true, dataType = "string", name = "destinationDomain", paramType = "path")
+ })
+ @ApiResponses(value = {
+ @ApiResponse(code = HttpStatus.NO_CONTENT_204, message = "OK", response = List.class),
+ @ApiResponse(code = HttpStatus.NOT_FOUND_404, message = "The domain does not exist."),
+ @ApiResponse(code = HttpStatus.INTERNAL_SERVER_ERROR_500,
+ message = "Internal server error - Something went bad on the server side.")
+ })
+ public void defineAddAlias(Service service) {
+ service.put(SPECIFIC_ALIAS, this::addDomainAlias, jsonTransformer);
+ }
+
private String removeDomain(Request request, Response response) {
try {
- Domain domain = checkValidDomain(request);
+ Domain domain = checkValidDomain(request.params(DOMAIN_NAME));
domainList.removeDomain(domain);
} catch (DomainListException e) {
LOGGER.info("{} did not exists", request.params(DOMAIN_NAME));
@@ -168,7 +240,7 @@ public class DomainsRoutes implements Routes {
}
private String addDomain(Request request, Response response) {
- Domain domain = checkValidDomain(request);
+ Domain domain = checkValidDomain(request.params(DOMAIN_NAME));
try {
addDomain(domain);
response.status(204);
@@ -192,8 +264,7 @@ public class DomainsRoutes implements Routes {
return Constants.EMPTY_BODY;
}
- private Domain checkValidDomain(Request request) {
- String domainName = request.params(DOMAIN_NAME);
+ private Domain checkValidDomain(String domainName) {
try {
return Domain.of(domainName);
} catch (IllegalArgumentException e) {
@@ -212,16 +283,67 @@ public class DomainsRoutes implements Routes {
}
private Response exists(Request request, Response response) throws DomainListException {
- Domain domain = checkValidDomain(request);
+ Domain domain = checkValidDomain(request.params(DOMAIN_NAME));
+
if (!domainList.containsDomain(domain)) {
- throw ErrorResponder.builder()
- .statusCode(HttpStatus.NOT_FOUND_404)
- .type(ErrorType.INVALID_ARGUMENT)
- .message("The domain list does not contain: " + domain.name())
- .haltError();
+ throw domainNotFound(domain);
} else {
response.status(HttpStatus.NO_CONTENT_204);
return response;
}
}
+
+ private ImmutableSet<DomainAliasResponse> listDomainAliases(Request request, Response response) throws DomainListException, RecipientRewriteTableException {
+ Domain domain = checkValidDomain(request.params(DOMAIN_NAME));
+
+ if (!hasAliases(domain)) {
+ throw domainHasNoAliases(domain);
+ } else {
+ return recipientRewriteTable.listSources(Mapping.domain(domain))
+ .map(DomainAliasResponse::new)
+ .collect(Guavate.toImmutableSet());
+ }
+ }
+
+ private String addDomainAlias(Request request, Response response) throws DomainListException, RecipientRewriteTableException {
+ return performOperationOnAlias(request, response, recipientRewriteTable::addMapping);
+ }
+
+ private String removeDomainAlias(Request request, Response response) throws DomainListException, RecipientRewriteTableException {
+ return performOperationOnAlias(request, response, recipientRewriteTable::removeMapping);
+ }
+
+ private String performOperationOnAlias(Request request, Response response, MappingOperation operation) throws DomainListException, RecipientRewriteTableException {
+ Domain sourceDomain = checkValidDomain(request.params(SOURCE_DOMAIN));
+ Domain destinationDomain = checkValidDomain(request.params(DESTINATION_DOMAIN));
+
+ if (!domainList.containsDomain(sourceDomain)) {
+ throw domainNotFound(sourceDomain);
+ }
+
+ operation.perform(MappingSource.fromDomain(sourceDomain), Mapping.domain(destinationDomain));
+ response.status(HttpStatus.NO_CONTENT_204);
+ return Constants.EMPTY_BODY;
+ }
+
+ private boolean hasAliases(Domain domain) throws DomainListException, RecipientRewriteTableException {
+ return domainList.containsDomain(domain)
+ || recipientRewriteTable.listSources(Mapping.domain(domain)).findFirst().isPresent();
+ }
+
+ private HaltException domainNotFound(Domain domain) {
+ return ErrorResponder.builder()
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .type(ErrorType.INVALID_ARGUMENT)
+ .message("The domain list does not contain: " + domain.name())
+ .haltError();
+ }
+
+ private HaltException domainHasNoAliases(Domain domain) {
+ return ErrorResponder.builder()
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .type(ErrorType.INVALID_ARGUMENT)
+ .message("The following domain is not in the domain list and has no registered local aliases: " + domain.name())
+ .haltError();
+ }
}
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DomainAliasResponseTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DomainAliasResponseTest.java
new file mode 100644
index 0000000..f8fb107
--- /dev/null
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/dto/DomainAliasResponseTest.java
@@ -0,0 +1,31 @@
+/****************************************************************
+ * 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.junit.jupiter.api.Test;
+
+import nl.jqno.equalsverifier.EqualsVerifier;
+
+class DomainAliasResponseTest {
+ @Test
+ void shouldMatchBeanContract() {
+ EqualsVerifier.forClass(DomainAliasResponse.class).verify();
+ }
+}
\ No newline at end of file
diff --git a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
index 82b7dde..d5f28bd 100644
--- a/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
+++ b/server/protocols/webadmin/webadmin-data/src/test/java/org/apache/james/webadmin/routes/DomainsRoutesTest.java
@@ -25,6 +25,9 @@ import static io.restassured.RestAssured.with;
import static org.apache.james.webadmin.Constants.SEPARATOR;
import static org.apache.james.webadmin.WebAdminServer.NO_CONFIGURATION;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.Matchers.containsInAnyOrder;
+import static org.hamcrest.Matchers.hasSize;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
@@ -40,6 +43,7 @@ import org.apache.james.domainlist.api.DomainList;
import org.apache.james.domainlist.api.DomainListException;
import org.apache.james.domainlist.memory.MemoryDomainList;
import org.apache.james.metrics.logger.DefaultMetricFactory;
+import org.apache.james.rrt.memory.MemoryRecipientRewriteTable;
import org.apache.james.webadmin.WebAdminServer;
import org.apache.james.webadmin.WebAdminUtils;
import org.apache.james.webadmin.utils.JsonTransformer;
@@ -54,14 +58,17 @@ import io.restassured.http.ContentType;
public class DomainsRoutesTest {
- public static final String DOMAIN = "domain";
+ private static final String DOMAIN = "domain";
+ private static final String ALIAS_DOMAIN = "alias.domain";
+ private static final String ALIAS_DOMAIN_2 = "alias.domain.bis";
+ public static final String EXTERNAL_DOMAIN = "external.domain.tld";
private WebAdminServer webAdminServer;
private void createServer(DomainList domainList) throws Exception {
webAdminServer = WebAdminUtils.createWebAdminServer(
new DefaultMetricFactory(),
- new DomainsRoutes(domainList, new JsonTransformer()));
+ new DomainsRoutes(domainList, new MemoryRecipientRewriteTable(), new JsonTransformer()));
webAdminServer.configure(NO_CONFIGURATION);
webAdminServer.await();
@@ -255,6 +262,252 @@ public class DomainsRoutesTest {
.statusCode(HttpStatus.NOT_FOUND_404);
}
+ @Nested
+ class DomainAlias{
+ @Test
+ void getAliasesShouldReturnNotFoundWhenDomainDoesNotExist() {
+ when()
+ .get(DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("The following domain is not in the domain list and has no registered local aliases: domain"));
+ }
+
+ @Test
+ void getAliasesShouldReturnEmptyWhenNone() {
+ with().put(DOMAIN);
+
+ when()
+ .get(DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body(".", hasSize(0));
+ }
+
+ @Test
+ void getAliasesShouldReturnCreatedAliases() {
+ with().put(DOMAIN);
+ with().put(ALIAS_DOMAIN);
+ with().put(ALIAS_DOMAIN_2);
+
+ with().put(DOMAIN + "/aliases/" + ALIAS_DOMAIN);
+ with().put(DOMAIN + "/aliases/" + ALIAS_DOMAIN_2);
+
+ when()
+ .get(DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", containsInAnyOrder(ALIAS_DOMAIN, ALIAS_DOMAIN_2));
+ }
+
+ @Test
+ void putShouldBeIdempotent() {
+ with().put(DOMAIN);
+ with().put(ALIAS_DOMAIN);
+
+ with().put(DOMAIN + "/aliases/" + ALIAS_DOMAIN);
+ with().put(DOMAIN + "/aliases/" + ALIAS_DOMAIN);
+
+ when()
+ .get(DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", containsInAnyOrder(ALIAS_DOMAIN));
+ }
+
+ @Test
+ void deleteShouldNotFailOnNonExistingEvents() {
+ with().put(DOMAIN);
+ with().put(ALIAS_DOMAIN);
+
+ with().delete(DOMAIN + "/aliases/" + ALIAS_DOMAIN);
+
+ when()
+ .get(DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("", hasSize(0));
+ }
+
+ @Test
+ void putShouldLowercaseDomain() {
+ with().put(DOMAIN);
+ with().put(ALIAS_DOMAIN);
+
+ with().put(DOMAIN + "/aliases/" + "Alias.Domain");
+
+ when()
+ .get(DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", containsInAnyOrder(ALIAS_DOMAIN));
+ }
+
+ @Test
+ void getAliasesShouldNotReturnDeletedAliases() {
+ with().put(DOMAIN);
+ with().put(ALIAS_DOMAIN);
+
+ with().put(DOMAIN + "/aliases/" + ALIAS_DOMAIN);
+ with().delete(DOMAIN + "/aliases/" + ALIAS_DOMAIN);
+
+ when()
+ .get(DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body(".", hasSize(0));
+ }
+
+ @Test
+ void deleteShouldReturnNotFoundWhenAliasDomainDoesNotExist() {
+ with().put(DOMAIN);
+
+ when()
+ .delete(DOMAIN + "/aliases/" + ALIAS_DOMAIN)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("The domain list does not contain: " + ALIAS_DOMAIN));
+ }
+
+ @Test
+ void putShouldReturnNotFoundWhenAliasDomainDoesNotExist() {
+ with().put(DOMAIN);
+
+ when()
+ .put(DOMAIN + "/aliases/" + ALIAS_DOMAIN)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.NOT_FOUND_404)
+ .body("statusCode", is(HttpStatus.NOT_FOUND_404))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("The domain list does not contain: " + ALIAS_DOMAIN));
+ }
+
+ @Test
+ void putShouldNotFailOnExternalDomainAlias() {
+ with().put(DOMAIN);
+
+ when()
+ .put(EXTERNAL_DOMAIN + "/aliases/" + DOMAIN).prettyPeek()
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.NO_CONTENT_204);
+ }
+
+ @Test
+ void deleteShouldNotFailOnExternalDomainDestinationForAnAlias() {
+ with().put(DOMAIN);
+
+ when()
+ .delete(EXTERNAL_DOMAIN + "/aliases/" + DOMAIN)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.NO_CONTENT_204);
+ }
+
+ @Test
+ void getAliasesShouldListAliasesForExternalDomains() {
+ with().put(DOMAIN);
+
+ with().put(EXTERNAL_DOMAIN + "/aliases/" + DOMAIN);
+
+ when()
+ .get(EXTERNAL_DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", containsInAnyOrder(DOMAIN));
+ }
+
+ @Test
+ void deleteShouldRemoveExternalDomainAlias() {
+ with().put(DOMAIN);
+
+ with().put(EXTERNAL_DOMAIN + "/aliases/" + DOMAIN);
+
+ with().delete(EXTERNAL_DOMAIN + "/aliases/" + DOMAIN);
+
+ when()
+ .get(DOMAIN + "/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.OK_200)
+ .body("source", hasSize(0));
+ }
+
+ @Test
+ void putShouldReturnBadRequestWhenDestinationDomainIsInvalid() {
+ when()
+ .put("invalid@domain/aliases/" + ALIAS_DOMAIN)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("Invalid request for domain creation invalid@domain"));
+ }
+
+ @Test
+ void putShouldReturnBadRequestWhenSourceDomainIsInvalid() {
+ when()
+ .put("domain/aliases/invalid@alias.domain")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("Invalid request for domain creation invalid@alias.domain"));
+ }
+
+ @Test
+ void deleteShouldReturnBadRequestWhenDestinationDomainIsInvalid() {
+ when()
+ .delete("invalid@domain/aliases/" + ALIAS_DOMAIN)
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("Invalid request for domain creation invalid@domain"));
+ }
+
+ @Test
+ void deleteShouldReturnBadRequestWhenSourceDomainIsInvalid() {
+ when()
+ .delete("domain/aliases/invalid@alias.domain")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("Invalid request for domain creation invalid@alias.domain"));
+ }
+
+ @Test
+ void getAliasesShouldReturnBadRequestWhenDomainIsInvalid() {
+ when()
+ .get("invalid@domain/aliases")
+ .then()
+ .contentType(ContentType.JSON)
+ .statusCode(HttpStatus.BAD_REQUEST_400)
+ .body("statusCode", is(HttpStatus.BAD_REQUEST_400))
+ .body("type", is("InvalidArgument"))
+ .body("message", is("Invalid request for domain creation invalid@domain"));
+ }
+ }
+
}
@Nested
---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org