From 9178668f847ea102d579d432a76bf91acf9c6175 Mon Sep 17 00:00:00 2001
From: Olga Maciaszek-Sharma
+ * given().config(newConfig().logConfig(new LogConfig(captor, true))). .. + *+ * + *
newConfig()
can be statically imported from {@link RestAssuredWebTestClientConfig}.
+ */
+ public static RestAssuredWebTestClientConfig config;
+
+ /**
+ * Specify a default request specification that will be sent with each request. E,g.
+ * + * RestAssuredWebTestClient.requestSpecification = new WebTestClientRequestSpecBuilder().addParam("parameter1", "value1").build(); + *+ * + * means that for each request by Rest Assured "parameter1" will be equal to "value1". + */ + public static WebTestClientRequestSpecification requestSpecification; + + /** + * Specify a default response specification that will be sent with each request. E,g. + *
+ * RestAssuredWebTestClient.responseSpecification = new ResponseSpecBuilder().expectStatusCode(200).build(); + *+ * + * means that for each response Rest Assured will assert that the status code is equal to 200. + */ + public static ResponseSpecification responseSpecification = null; + + /** + * The base path that's used by REST assured when making requests. The base path is prepended to the request path. + * Default value is
/
.
+ */
+ public static String basePath = "/";
+
+ private static WebTestClientFactory webTestClientFactory = null;
+
+ /**
+ * Set a {@link WebTestClient} instance that REST Assured will use when making requests unless overwritten
+ * by a {@link WebTestClientRequestSpecification}.
+ *
+ * @param webTestClient The WebTestClient instance to use.
+ */
+ public static void webTestClient(WebTestClient webTestClient) {
+ RestAssuredWebTestClient.webTestClientFactory = new WrapperWebTestClientFactory(webTestClient);
+ }
+
+ /**
+ * This is usually the entry-point of the API if you need to specify parameters or a body in the request. For example:
+ *
+ * + * given(). + * param("x", "y"). + * when(). + * get("/something"). + * then(). + * statusCode(200). + * body("x.y", notNullValue()); + *+ * Note that this method is the same as {@link #with()} but with another syntax. + * + * @return a {@link WebTestClientRequestSpecification}. + */ + public static WebTestClientRequestSpecification given() { + return new WebTestClientRequestSpecificationImpl(webTestClientFactory, config, basePath, requestSpecification, + responseSpecification); + } + + /** + * This is usually the entry-point of the API if you need to specify parameters or a body in the request. For example: + * Note that this method is the same as {@link #given()} but with another syntax. + * + * @return A {@link WebTestClientRequestSpecification}. + */ + public static WebTestClientRequestSpecification with() { + return given(); + } + + /** + * Build a {@link WebTestClient} by registering one or more {@code @Controller}'s + * instances and configuring WebTestClient programmatically. + * This allows full control over the instantiation, configuration and initialization of + * controllers, and their dependencies, similar to plain unit tests while + * also making it possible to test one controller at a time. + * + *
It uses {@link WebTestClient#bindToController(Object...)} under the hood. + * It also allows you to pass {@link WebTestClientConfigurer} and {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction} + * instances that are used to set up the {@link WebTestClient} instance. + *
+ * + * @param controllersOrConfigurersOrExchangeFilterFunctions one or more {@link org.springframework.stereotype.Controller @Controller}s to test, + * as well as {@link WebTestClientConfigurer}s + * and {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction}s to apply. + */ + public static void standaloneSetup(Object... controllersOrConfigurersOrExchangeFilterFunctions) { + webTestClientFactory = StandaloneWebTestClientFactory.of(controllersOrConfigurersOrExchangeFilterFunctions); + } + + /** + * Build a {@link WebTestClient} by using a provided {@link RouterFunction} + * for configuring WebTestClient programmatically. + * This allows full control over the instantiation, configuration and initialization of + * router functions, and their dependencies, similar to plain unit tests while + * also making it possible to test one router function at a time. + *+ *
+ * It uses {@link WebTestClient#bindToRouterFunction(RouterFunction)} under the hood. + * It also allows you to pass {@link WebTestClientConfigurer} and {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction} + * instances that are used to set up the {@link WebTestClient} instance + * + * + * @param routerFunction {@link RouterFunction} to build WebTestClient. + * @param configurersOrExchangeFilterFunctions {@link WebTestClientConfigurer}s and {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction}s to apply. + */ + public static void standaloneSetup(RouterFunction routerFunction, Object... configurersOrExchangeFilterFunctions) { + webTestClientFactory = StandaloneWebTestClientFactory.of(routerFunction, configurersOrExchangeFilterFunctions); + } + + /** + * Build a {@link WebTestClient} by using a provided {@link org.springframework.test.web.reactive.server.WebTestClient.Builder} + * for configuring WebTestClient programmatically. + * This allows full control over the instantiation and initialization of + * controllers, and their dependencies, similar to plain unit tests while + * also making it possible to test one controller at a time. + * + * @param builder {@link org.springframework.test.web.reactive.server.WebTestClient.Builder} to build WebTestClient. + */ + public static void standaloneSetup(WebTestClient.Builder builder) { + webTestClientFactory = new BuilderBasedWebTestClientFactory(builder); + } + + /** + * Build a {@link WebTestClient} using the given, fully initialized, i.e. + * refreshed, {@link WebApplicationContext} and assign it to REST Assured. + *
+ * This is really an alias for {@link #webAppContextSetup(WebApplicationContext, Object...)}.
+ * The passed {@link WebApplicationContext} will be used as {@link ApplicationContext}.
+ *
+ * @param context The web application context to use
+ * @param configurersOrExchangeFilterFunctions {@link WebTestClientConfigurer}s and {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction}s to apply.
+ */
+ public static void webAppContextSetup(WebApplicationContext context, Object... configurersOrExchangeFilterFunctions) {
+ webTestClientFactory = StandaloneWebTestClientFactory.of(context, configurersOrExchangeFilterFunctions);
+ }
+
+ /**
+ * Build a {@link WebTestClient} using the given, fully initialized, i.e.
+ * refreshed, {@link ApplicationContext} and assign it to REST Assured.
+ *
+ * @param context The application context to use
+ * @param configurersOrExchangeFilterFunctions {@link WebTestClientConfigurer}s and {@link org.springframework.web.reactive.function.client.ExchangeFilterFunction}s to apply.
+ */
+ public static void applicationContextSetup(ApplicationContext context,
+ Object... configurersOrExchangeFilterFunctions) {
+ webTestClientFactory = StandaloneWebTestClientFactory.of(context, configurersOrExchangeFilterFunctions);
+ }
+
+ /**
+ * Reset all static configurations to their default values.
+ */
+ public static void reset() {
+ webTestClientFactory = null;
+ config = null;
+ basePath = "/";
+ responseSpecification = null;
+ requestSpecification = null;
+ }
+
+ /**
+ * Perform a GET request to a
+ * This is just a shortcut for:
+ *
+ * This is just a shortcut for:
+ *
+ * Note that if you need to add parameters, headers, cookies or other request properties use the {@link #given()} method.
+ *
+ * Usage example:
+ * path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do get("/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse get(String path, Object... pathParams) {
+ return given().get(path, pathParams);
+ }
+
+ /**
+ * Perform a GET request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters.
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse get(String path, MapuriFunction
.
+ *
+ * @param uriFunction The {@code Functionpath
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do post("/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse post(String path, Object... pathParams) {
+ return given().post(path, pathParams);
+ }
+
+ /**
+ * Perform a GET request to a uri
.
+ *
+ * @param uri The uri to send the request to.
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse get(URI uri) {
+ return given().get(uri);
+ }
+
+ /**
+ * Perform a GET request to a url
.
+ *
+ * @param url The url to send the request to.
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse get(URL url) {
+ return given().get(url);
+ }
+
+ /**
+ * Perform a GET request to the statically configured base path.
+ *
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse get() {
+ return given().get();
+ }
+
+ /**
+ * Perform a request to the pre-configured path (by default http://localhost:8080
).
+ *
+ * @param method The HTTP method to use
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse request(Method method) {
+ return given().request(method);
+ }
+
+ /**
+ * Perform a custom HTTP request to the pre-configured path (by default http://localhost:8080
).
+ *
+ * @param method The HTTP method to use
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse request(String method) {
+ return given().request(method);
+ }
+
+ /**
+ * Perform a HTTP request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param method The HTTP method to use
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do request(Method.TRACE,"/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse request(Method method, String path, Object... pathParams) {
+ return given().request(method, path, pathParams);
+ }
+
+ /**
+ * Perform a custom HTTP request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param method The HTTP method to use
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do request("method","/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse request(String method, String path, Object... pathParams) {
+ return given().request(method, path, pathParams);
+ }
+
+ /**
+ * Perform a request to a uri
.
+ *
+ * @param method The HTTP method to use
+ * @param uri The uri to send the request to.
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse request(Method method, URI uri) {
+ return given().request(method, uri);
+ }
+
+ /**
+ * Perform a request to a path generated from the provided {@link Function} uriFunction
.
+ *
+ * @param method The HTTP method to use
+ * @param uriFunction The {@code Functionurl
.
+ *
+ * @param method The HTTP method to use
+ * @param url The url to send the request to.
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse request(Method method, URL url) {
+ return given().request(method, url);
+ }
+
+ /**
+ * Perform a custom HTTP request to a uri
.
+ *
+ * @param method The HTTP method to use
+ * @param uri The uri to send the request to.
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse request(String method, URI uri) {
+ return given().request(method, uri);
+ }
+
+ /**
+ * Perform a request to a path generated from the provided {@link Function} uriFunction
.
+ *
+ * @param method The HTTP method to use
+ * @param uriFunction The {@code Functionurl
.
+ *
+ * @param method The HTTP method to use
+ * @param url The url to send the request to.
+ * @return The response of the GET request.
+ */
+ public static WebTestClientResponse request(String method, URL url) {
+ return given().request(method, url);
+ }
+
+ /**
+ * Perform a POST request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse post(String path, Mappath
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do put("/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse put(String path, Object... pathParams) {
+ return given().put(path, pathParams);
+ }
+
+ /**
+ * Perform a POST request to a path generated from the provided {@link Function} uriFunction
.
+ *
+ * @param uriFunction The {@code Functionuri
.
+ *
+ * @param uri The uri to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse post(URI uri) {
+ return given().post(uri);
+ }
+
+ /**
+ * Perform a POST request to a url
.
+ *
+ * @param url The url to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse post(URL url) {
+ return given().post(url);
+ }
+
+ /**
+ * Perform a POST request to the statically configured base path.
+ *
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse post() {
+ return given().post();
+ }
+
+ /**
+ * Perform a DELETE request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do delete("/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse delete(String path, Object... pathParams) {
+ return given().delete(path, pathParams);
+ }
+
+ public static WebTestClientResponse put(String path, MapuriFunction
.
+ *
+ * @param uriFunction The {@code Functionuri
.
+ *
+ * @param uri The uri to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse put(URI uri) {
+ return given().put(uri);
+ }
+
+ public static WebTestClientResponse put(URL url) {
+ return given().put(url);
+ }
+
+ /**
+ * Perform a PUT request to the statically configured base path.
+ *
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse put() {
+ return given().put();
+ }
+
+ /**
+ * Perform a DELETE request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse delete(String path, Mappath
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do head("/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse head(String path, Object... pathParams) {
+ return given().head(path, pathParams);
+ }
+
+ /**
+ * Perform a DELETE request to a path generated from the provided {@link Function} uriFunction
.
+ *
+ * @param uriFunction The {@code Functionuri
.
+ *
+ * @param uri The uri to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse delete(URI uri) {
+ return given().delete(uri);
+ }
+
+ /**
+ * Perform a DELETE request to a url
.
+ *
+ * @param url The url to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse delete(URL url) {
+ return given().delete(url);
+ }
+
+ /**
+ * Perform a DELETE request to the statically configured base path.
+ *
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse delete() {
+ return given().delete();
+ }
+
+ /**
+ * Perform a HEAD request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse head(String path, Mappath
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do head("/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse patch(String path, Object... pathParams) {
+ return given().patch(path, pathParams);
+ }
+
+ /**
+ * Perform a HEAD request to a path generated from the provided {@link Function} uriFunction
.
+ *
+ * @param uriFunction The {@code Functionuri
.
+ *
+ * @param uri The uri to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse head(URI uri) {
+ return given().head(uri);
+ }
+
+ /**
+ * Perform a HEAD request to a url
.
+ *
+ * @param url The url to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse head(URL url) {
+ return given().head(url);
+ }
+
+ /**
+ * Perform a HEAD request to the statically configured base path.
+ *
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse head() {
+ return given().head();
+ }
+
+ /**
+ * Perform a PATCH request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse patch(String path, MapuriFunction
.
+ *
+ * @param uriFunction The {@code Functionuri
.
+ *
+ * @param uri The uri to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse patch(URI uri) {
+ return given().patch(uri);
+ }
+
+ /**
+ * Perform a PATCH request to a url
.
+ *
+ * @param url The url to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse patch(URL url) {
+ return given().patch(url);
+ }
+
+ /**
+ * Perform a PATCH request to the statically configured base path.
+ *
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse patch() {
+ return given().patch();
+ }
+
+ /**
+ * Perform a OPTIONS request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters. E.g. if path is "/book/{hotelId}/{roomNumber}" you can do head("/book/{hotelName}/{roomNumber}", "Hotels R Us", 22);
.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse options(String path, Object... pathParams) {
+ return given().options(path, pathParams);
+ }
+
+ /**
+ * Perform a OPTIONS request to a path
. Normally the path doesn't have to be fully-qualified e.g. you don't need to
+ * specify the path as http://localhost:8080/path. In this case it's enough to use /path.
+ *
+ * @param path The path to send the request to.
+ * @param pathParams The path parameters.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse options(String path, MapuriFunction
.
+ *
+ * @param uriFunction The {@code Functionuri
.
+ *
+ * @param uri The uri to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse options(URI uri) {
+ return given().options(uri);
+ }
+
+ /**
+ * Perform a OPTIONS request to a url
.
+ *
+ * @param url The url to send the request to.
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse options(URL url) {
+ return given().options(url);
+ }
+
+ /**
+ * Perform a OPTIONS request to the statically configured base path.
+ *
+ * @return The response of the request.
+ */
+ public static WebTestClientResponse options() {
+ return given().options();
+ }
+
+ /**
+ * Enable logging of both the request and the response if REST Assured test validation fails with log detail equal to {@link LogDetail#ALL}.
+ *
+ *
+ * RestAssuredWebTestClient.config = new RestAssuredWebTestClientConfig().logConfig(logConfig().enableLoggingOfRequestAndResponseIfValidationFails());
+ *
+ */
+ public static void enableLoggingOfRequestAndResponseIfValidationFails() {
+ enableLoggingOfRequestAndResponseIfValidationFails(LogDetail.ALL);
+ }
+
+ /**
+ * Enable logging of both the request and the response if REST Assured test validation fails with the specified log detail.
+ *
+ *
+ * RestAssured.config = new RestAssuredWebTestClientConfig().logConfig(logConfig().enableLoggingOfRequestAndResponseIfValidationFails(logDetail));
+ *
+ *
+ * @param logDetail The log detail to show in the log
+ */
+ public static void enableLoggingOfRequestAndResponseIfValidationFails(LogDetail logDetail) {
+ config = config == null ? new RestAssuredWebTestClientConfig() : config;
+ config = config.logConfig(logConfig().enableLoggingOfRequestAndResponseIfValidationFails(logDetail));
+ // Update request specification if already defined otherwise it'll override the configs.
+ // Note that request spec also influence response spec when it comes to logging if validation fails
+ // due to the way filters work
+ if (requestSpecification instanceof WebTestClientRequestSpecificationImpl) {
+ RestAssuredWebTestClientConfig restAssuredConfig = ((WebTestClientRequestSpecificationImpl) requestSpecification)
+ .getRestAssuredWebTestClientConfig();
+ if (restAssuredConfig == null) {
+ restAssuredConfig = config;
+ } else {
+ LogConfig logConfigForRequestSpec = restAssuredConfig.getLogConfig().enableLoggingOfRequestAndResponseIfValidationFails(logDetail);
+ restAssuredConfig = restAssuredConfig.logConfig(logConfigForRequestSpec);
+ }
+ requestSpecification.config(restAssuredConfig);
+ }
+ }
+
+ /**
+ * This is usually the entry-point of the API if you need to specify parameters or a body in the request. For example:
+ *
+ *
+ * when().
+ * get("/x").
+ * then().
+ * body("x.y.z1", equalTo("Z1")).
+ * body("x.y.z2", equalTo("Z2"));
+ *
+ *
+ * RestAssuredWebTestClient.config = new RestAssuredWebTestClientConfig().logConfig(new LogConfig(captor, true));
+ *
+ *
+ * given().param("name", "value").when().get("/x"). .. + *
+ * + * @param updateStrategy The update strategy to use for request parameters + * @return A new instance of {@link WebTestClientParamConfig} + */ + public WebTestClientParamConfig requestParamsUpdateStrategy(UpdateStrategy updateStrategy) { + return new WebTestClientParamConfig(queryParamsUpdateStrategy, formParamsUpdateStrategy, + updateStrategy, attributeUpdateStrategy, true); + } + + + /** + * Set query parameter update strategy to the given value. + * + * @param updateStrategy The update strategy to use for query parameters + * @return A new instance of {@link WebTestClientParamConfig} + */ + public WebTestClientParamConfig queryParamsUpdateStrategy(UpdateStrategy updateStrategy) { + return new WebTestClientParamConfig(updateStrategy, formParamsUpdateStrategy, + requestParameterUpdateStrategy, attributeUpdateStrategy, true); + } + + /** + * Syntactic sugar. + * + * @return The same WebTestClientParamConfig instance. + */ + public WebTestClientParamConfig and() { + return this; + } + + /** + * Syntactic sugar. + * + * @return The same WebTestClientParamConfig instance. + */ + public WebTestClientParamConfig with() { + return this; + } + + /** + * Set attribute update strategy to the given value. + * + * @param updateStrategy The update strategy to use for attribute parameters + * @return A new instance of {@link WebTestClientParamConfig} + */ + public WebTestClientParamConfig attributeUpdateStrategy(UpdateStrategy updateStrategy) { + return new WebTestClientParamConfig(queryParamsUpdateStrategy, formParamsUpdateStrategy, + requestParameterUpdateStrategy, updateStrategy, true); + } + +} diff --git a/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/internal/BuilderBasedWebTestClientFactory.java b/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/internal/BuilderBasedWebTestClientFactory.java new file mode 100644 index 000000000..a370437d9 --- /dev/null +++ b/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/internal/BuilderBasedWebTestClientFactory.java @@ -0,0 +1,43 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.restassured.module.webtestclient.internal; + +import io.restassured.module.webtestclient.config.WebTestClientConfig; + +import org.springframework.test.web.reactive.server.WebTestClient; + +public class BuilderBasedWebTestClientFactory implements WebTestClientFactory { + + private final WebTestClient.Builder builder; + + public BuilderBasedWebTestClientFactory(WebTestClient.Builder builder) { + this.builder = builder; + } + + @Override + public synchronized WebTestClient build(WebTestClientConfig webTestClientConfig) { + if (!isAssigned()) { + throw new IllegalStateException("You haven't configured a MockMVC instance. You can do this statically\n\nRestAssuredMockMvc.mockMvc(..)\nRestAssuredMockMvc.standaloneSetup(..);\nRestAssuredMockMvc.webAppContextSetup(..);\n\nor using the DSL:\n\ngiven().\n\t\tmockMvc(..). ..\n"); + } + return builder.build(); + } + + @Override + public boolean isAssigned() { + return builder != null; + } +} diff --git a/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/internal/ExchangeResultConverter.java b/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/internal/ExchangeResultConverter.java new file mode 100644 index 000000000..3dec09b1b --- /dev/null +++ b/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/internal/ExchangeResultConverter.java @@ -0,0 +1,101 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.restassured.module.webtestclient.internal; + +import io.restassured.filter.time.TimingFilter; +import io.restassured.http.Cookie; +import io.restassured.http.Cookies; +import io.restassured.http.Header; +import io.restassured.http.Headers; +import io.restassured.internal.ResponseParserRegistrar; +import io.restassured.internal.log.LogRepository; +import io.restassured.module.spring.commons.config.ConfigConverter; +import io.restassured.module.webtestclient.config.RestAssuredWebTestClientConfig; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseCookie; +import org.springframework.test.web.reactive.server.EntityExchangeResult; +import org.springframework.test.web.reactive.server.FluxExchangeResult; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.MimeType; +import org.springframework.util.MultiValueMap; + +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import static java.util.Optional.ofNullable; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + +class ExchangeResultConverter { + + WebTestClientRestAssuredResponseImpl toRestAssuredResponse(FluxExchangeResult+ * { + * "userId" : "my-id", + * "playerId" : "my-id" + * } + *+ * you can then test it like this: + *
+ * get("/x").then().body("userId", equalToPath("playerId")); + *+ * + * @param path The path to check + * @return A {@link ResponseAwareMatcher} + */ + public static ResponseAwareMatcher
+ * { + * "userId" : "my-id", + * "href" : "http://localhost:8080/my-id" + * } + *+ * you can then test it like this: + *
+ * get("/x").then().body("href", endsWithPath("userId")); + *+ * + * @param path The path to check + * @return A {@link ResponseAwareMatcher} + */ + public static ResponseAwareMatcher
+ * { + * "userId" : "my-id", + * "baseUri" : "http://localhost:8080", + * "href" : "http://localhost:8080/my-id" + * } + *+ * you can then test it like this: + *
+ * get("/x").then().body("href", startsWithPath("baseUri")); + *+ * + * @param path The path to check + * @return A {@link ResponseAwareMatcher} + */ + public static ResponseAwareMatcher
+ * { + * "userId" : "my-id", + * "href" : "http://localhost:8080/my-id" + * } + *+ * you can then test it like this: + *
+ * get("/x").then().body("href", containsPath("userId")); + *+ * + * @param path The path to check + * @return A {@link ResponseAwareMatcher} + */ + public static ResponseAwareMatcher
+ *RestAssuredWebTestClient.given() + * .standaloneSetup(new GreetingController(), documentationConfiguration(restDocumentation)) + * .queryParam("name", "John") + * .when() + * .consumeWith(document("greeting", + * pathParameters( + * parameterWithName("path").description("The path to greeting")), + * responseFields( + * fieldWithPath("id").description("The ID of the greeting"), + * fieldWithPath("content").description("The content of the greeting")) + * )) + * .get("/{path}", "greeting") + *+ * + * @param consumer to be applied on the exchange result. + * @return a {@link WebTestClientRequestSender} instance. + */ + WebTestClientRequestSender consumeWith(Consumer
+ * Note that {@link #setBody(Object, ObjectMapperType)} + * are the same except for the syntactic difference. + *
+ * + * @param object The object to serialize and send with the request + * @param mapper The object mapper + * @return The request specification + */ + public WebTestClientRequestSpecBuilder setBody(Object object, ObjectMapper mapper) { + spec.body(object, mapper); + return this; + } + + /** + * Specify an Object request content that will automatically be serialized to JSON or XML and sent with the request using a specific object mapper type. + * This works for the POST, PATCH and PUT methods only. Trying to do this for the other http methods will cause an exception to be thrown. + *+ * Example of use: + *
+ * Message message = new Message(); + * message.setMessage("My beautiful message"); + * + * given(). + * body(message, ObjectMapper.GSON). + * expect(). + * content(equalTo("Response to a beautiful message")). + * when(). + * post("/beautiful-message"); + *+ * + * Note that {@link #setBody(Object, ObjectMapper)} + * are the same except for the syntactic difference. + * + * + * @param object The object to serialize and send with the request + * @param mapperType The object mapper type to be used + * @return The request specification + */ + public WebTestClientRequestSpecBuilder setBody(Object object, ObjectMapperType mapperType) { + spec.body(object, mapperType); + return this; + } + + /** + * Add cookies to be sent with the request as Map e.g: + * + * @param cookies The Map containing the cookie names and their values to set in the request. + * @return The request specification builder + */ + public WebTestClientRequestSpecBuilder addCookies(Map
+ * RestAssuredWebTestClient.config = newConfig().sessionConfig(new SessionConfig().sessionIdName(<sessionIdName>)); + *+ * or you can use the {@link #setSessionId(String, String)} method to set it for this request only. + * + * @param sessionIdValue The session id value. + * @return The request specification + */ + public WebTestClientRequestSpecBuilder setSessionId(String sessionIdValue) { + spec.sessionId(sessionIdValue); + return this; + } + + /** + * Set the session id name and value for this request. It'll override the default session id name from the configuration (by default this is {@value SessionConfig#DEFAULT_SESSION_ID_NAME}). + * You can configure the default session id name by using: + *
+ * RestAssuredWebTestClient.config = newConfig().sessionConfig(new SessionConfig().sessionIdName(<sessionIdName>)); + *+ * and then you can use the {@link WebTestClientRequestSpecBuilder#setSessionId(String)} method to set the session id value without specifying the name for each request. + * + * @param sessionIdName The session id name + * @param sessionIdValue The session id value. + * @return The request specification + */ + public WebTestClientRequestSpecBuilder setSessionId(String sessionIdName, String sessionIdValue) { + spec.sessionId(sessionIdName, sessionIdValue); + return this; + } + + /** + * Merge this builder with settings from another specification. Note that the supplied specification + * can overwrite data in the current specification. The following settings are overwritten: + *
null
no config will be used.
+ * @return The request specification builder
+ */
+ public WebTestClientRequestSpecBuilder setConfig(RestAssuredWebTestClientConfig config) {
+ spec.config(config);
+ return this;
+ }
+
+ /**
+ * Build the request specification.
+ *
+ * @return The assembled request specification
+ */
+ public WebTestClientRequestSpecification build() {
+ return spec;
+ }
+
+ /**
+ * Set the basePath property of the WebTestClientRequestSpecBuilder instead of using static field RestAssuredWebTestClient.basePath.
+ *
+ * + * WebTestClientRequestSpecBuilder builder = new WebTestClientRequestSpecBuilder(); + * builder.setBasePath("/something"); + * WebTestClientRequestSpecification specs = builder.build(); + * given().spec(specs) + *+ * + * @param basePath + * @return WebTestClientRequestSpecBuilder + */ + public WebTestClientRequestSpecBuilder setBasePath(String basePath) { + spec.basePath(basePath); + return this; + } + + /** + * The webTestClient instance to use. + * + * Note that this will override the any {@link org.springframework.test.web.reactive.server.WebTestClient} instances configured by other setters.* + * + * @param webTestClient The WebTestClient instance + * @return WebTestClientRequestSpecBuilder + */ + public WebTestClientRequestSpecBuilder setWebTestClient(WebTestClient webTestClient) { + spec.webTestClient(webTestClient); + return this; + } + + /** + * The standalone setup to be used by supplying a set of controllers. + * + * Note that this will override the any {@link WebTestClient} instances configured by other setters. + * + * @param controllers The controllers to use + * @return WebTestClientRequestSpecBuilder + * + * @see WebTestClientRequestSpecification#standaloneSetup(Object...) + */ + public WebTestClientRequestSpecBuilder setStandaloneSetup(Object... controllers) { + spec.standaloneSetup(controllers); + return this; + } + + /** + * Initialize with a WebTestClientBuilder that will be used to create the {@link WebTestClient} instance. + * + * Note that this will override the any {@link WebTestClient} instances configured by other setters. + * + * @param builder The builder to use + * @return WebTestClientRequestSpecBuilder + * + * @see WebTestClientRequestSpecification#standaloneSetup(WebTestClient.Builder) + */ + public WebTestClientRequestSpecBuilder setStandaloneSetup(WebTestClient.Builder builder) { + spec.standaloneSetup(builder); + return this; + } + + /** + * Initialize with a {@link WebApplicationContext} that will be used to create the {@link WebTestClient} instance. + * + * Note that this will override the any {@link WebTestClient} instances configured by other setters. + * + * @param context The WebApplicationContext to use + * @param WebTestClientConfigurers {@link org.springframework.test.web.reactive.server.WebTestClientConfigurer}'s to be applied when creating a {@link WebTestClient} instance of this WebApplicationContext (optional) + * @return WebTestClientRequestSpecBuilder + * + * @see WebTestClientRequestSpecification#webAppContextSetup(WebApplicationContext, WebTestClientConfigurer...) + */ + public WebTestClientRequestSpecBuilder setWebAppContextSetup(WebApplicationContext context, WebTestClientConfigurer... WebTestClientConfigurers) { + spec.webAppContextSetup(context, WebTestClientConfigurers); + return this; + } + + /** + * Enabled logging with the specified log detail. Set a {@link LogConfig} to configure the print stream and pretty printing options. + * + * @param logDetail The log detail. + * @return WebTestClientRequestSpecBuilder + */ + public WebTestClientRequestSpecBuilder log(LogDetail logDetail) { + notNull(logDetail, LogDetail.class); + LogConfig logConfig = spec.getRestAssuredWebTestClientConfig().getLogConfig(); + PrintStream printStream = logConfig.defaultStream(); + boolean prettyPrintingEnabled = logConfig.isPrettyPrintingEnabled(); + boolean shouldUrlEncodeRequestUri = logConfig.shouldUrlEncodeRequestUri(); + spec.setRequestLoggingFilter(new RequestLoggingFilter(logDetail, prettyPrintingEnabled, printStream, shouldUrlEncodeRequestUri)); + return this; + } + + /** + * Returns the same WebTestClientRequestSpecBuilder instance for syntactic sugar. + * + * @return WebTestClientRequestSpecBuilder + */ + public WebTestClientRequestSpecBuilder and() { + return this; + } +} + diff --git a/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/specification/WebTestClientRequestSpecification.java b/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/specification/WebTestClientRequestSpecification.java new file mode 100644 index 000000000..68b90d873 --- /dev/null +++ b/modules/spring-web-test-client/src/main/java/io/restassured/module/webtestclient/specification/WebTestClientRequestSpecification.java @@ -0,0 +1,929 @@ +/* + * Copyright 2018 the original author or authors. + * + * Licensed 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 io.restassured.module.webtestclient.specification; + +import io.restassured.config.SessionConfig; +import io.restassured.http.ContentType; +import io.restassured.http.Cookie; +import io.restassured.http.Cookies; +import io.restassured.http.Header; +import io.restassured.http.Headers; +import io.restassured.mapper.ObjectMapper; +import io.restassured.mapper.ObjectMapperType; +import io.restassured.module.spring.commons.config.SpecificationConfig; +import io.restassured.module.webtestclient.config.RestAssuredWebTestClientConfig; +import org.springframework.context.ApplicationContext; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.reactive.server.WebTestClientConfigurer; +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.reactive.function.server.RouterFunction; + +import java.io.File; +import java.io.InputStream; +import java.util.Collection; +import java.util.Map; + +public interface WebTestClientRequestSpecification extends WebTestClientRequestSender { + + /** + * Specify the content type of the request. + * + * @param contentType The content type of the request + * @return The request specification + * + * @see ContentType + */ + WebTestClientRequestSpecification contentType(ContentType contentType); + + /** + * Specify the content type of the request. + * + * @param contentType The content type of the request + * @return The request specification + * + * @see ContentType + */ + WebTestClientRequestSpecification contentType(String contentType); + + /** + * Specify the accept header of the request. This just a shortcut for: + *
+ * header("Accept", contentType); + *+ * + * @param contentType The content type whose accept header {@link ContentType#getAcceptHeader()} will be used as Accept header in the request. + * @return The request specification + * + * @see ContentType + * @see #header(String, Object, Object...) + */ + WebTestClientRequestSpecification accept(ContentType contentType); + + /** + * Specify the accept header of the request. This just a shortcut for: + *
+ * header("Accept", contentType); + *+ * + * @param mediaTypes The media type(s) that will be used as Accept header in the request. + * @return The request specification + * + * @see ContentType + * @see #header(String, Object, Object...) + */ + WebTestClientRequestSpecification accept(String mediaTypes); + + /** + * Specify the headers that'll be sent with the request. This is done by specifying the headers in name-value pairs, e.g: + *
+ * given().headers("headerName1", "headerValue1", "headerName2", "headerValue2").then().expect().body(equalTo("something")).when().get("/headers"); + *+ * + * This will send a GET request to "/headers" with two headers: + *
+ * Map<String, String> headers = new HashMap<String, String>(); + * parameters.put("headerName1", "headerValue1"); + * parameters.put("headerName2", "headerValue2"); + * given().headers(headers).then().expect().body(equalTo("something")).when().get("/headers"); + *+ * + * This will send a GET request to "/headers" with two headers: + *
+ * Header first = new Header("headerName1", "headerValue1"); + * Header second = new Header("headerName2", "headerValue2"); + * Headers headers = new Header(first, second); + * given().headers(headers).then().expect().body(equalTo("something")).when().get("/headers"); + *+ * + * This will send a GET request to "/headers" with two headers: + *
+ *
+ * given().header("username", "John").and().expect().body(equalTo("something")).when().get("/header"); + *+ * This will set the header
username=John
in the GET request to "/header".
+ *
+ *
+ * + * You can also specify several headers like this: + *
+ * given().header("username", "John").and().header("zipCode", "12345").and().expect().body(equalTo("something")).when().get("/header"); + *+ * + * + * If you specify
additionalHeaderValues
then the Header will be a multi-value header. This means that you'll create several headers with the
+ * same name but with different values.
+ *
+ * @param headerName The header name
+ * @param headerValue The header value
+ * @param additionalHeaderValues Additional header values. This will actually create two headers with the same name but with different values.
+ * @return The request specification
+ *
+ * @see #headers(String, Object, Object...)
+ */
+ WebTestClientRequestSpecification header(String headerName, Object headerValue, Object... additionalHeaderValues);
+
+ /**
+ * Specify a {@link Header} to send with the request.
+ * + *
+ * Header someHeader = new Header("some_name", "some_value"); + * given().header(someHeader).and().expect().body(equalTo("x")).when().get("/header"); + *+ * This will set the header
some_name=some_value
in the GET request to "/header".
+ *
+ *
+ * @param header The header to add to the request
+ * @return The request specification
+ *
+ * @see #headers(Headers)
+ */
+ WebTestClientRequestSpecification header(Header header);
+
+ /**
+ * Returns the {@link WebTestClientRequestLogSpecification} that allows you to log different parts of the {@link WebTestClientRequestSpecification}.
+ * This is mainly useful for debug purposes when writing your tests.
+ *
+ * @return the request log specification
+ */
+ WebTestClientRequestLogSpecification log();
+
+ /**
+ * Specify the parameters that'll be sent with the request. This is done by specifying the parameters in name-value pairs, e.g:
+ * + * given().params("username", "John", "token", "1234").when().get("/parameters").then().assertThat().body(equalTo("username, token")); + *+ * + * This will send a GET request to "/parameters" with two parameters: + *
+ * Map<String, String> parameters = new HashMap<String, String>(); + * parameters.put("username", "John"); + * parameters.put("token", "1234"); + * given().params(parameters).when().get("/cookie").then().assertThat().body(equalTo("username, token")).; + *+ * + * This will send a GET request to "/cookie" with two parameters: + *
+ *
+ * given().parameter("username", "John").and().expect().body(equalTo("username")).when().get("/cookie"); + *+ * This will set the parameter
username=John
in the GET request to "/cookie".
+ *
+ *
+ * + * You can also specify several parameters like this: + *
+ * given().param("username", "John").and().param("password", "1234").when().get("/cookie").then().assertThat().body(equalTo("username")).; + *+ * + * + * @param parameterName The parameter name + * @param parameterValues Zero to many parameter values for this parameter name + * @return The request specification + * + * @see #params(String, Object, Object...) + */ + WebTestClientRequestSpecification param(String parameterName, Object... parameterValues); + + /** + * Specify a multi-value parameter that'll be sent with the request e.g: + *
+ *
+ * given().param("cars", asList("Volvo", "Saab"))..; + *+ * This will set the parameter
cars=Volvo
and cars=Saab
.
+ *
+ *
+ * @param parameterName The parameter name
+ * @param parameterValues The parameter values
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification param(String parameterName, Collection> parameterValues);
+
+ /**
+ * Specify the query parameters that'll be sent with the request. Note that this method is the same as {@link #params(String, Object, Object...)}
+ * for all http methods except for POST where {@link #params(String, Object, Object...)} sets the form parameters and this method sets the
+ * query parameters.
+ *
+ * @param firstParameterName The name of the first parameter
+ * @param firstParameterValue The value of the first parameter
+ * @param parameterNameValuePairs The value of the first parameter followed by additional parameters in name-value pairs.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification queryParams(String firstParameterName, Object firstParameterValue, Object... parameterNameValuePairs);
+
+ /**
+ * Specify the query parameters that'll be sent with the request. Note that this method is the same as {@link #params(Map)}
+ * for all http methods except for POST where {@link #params(Map)} sets the form parameters and this method sets the
+ * query parameters.
+ *
+ * @param parametersMap The Map containing the parameter names and their values to send with the request.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification queryParams(Map+ *
+ * given().queryParam("cars", asList("Volvo", "Saab"))..; + *+ * This will set the parameter
cars=Volvo
and cars=Saab
.
+ *
+ *
+ * Note that this method is the same as {@link #param(String, java.util.Collection)}
+ * for all http methods except for POST where {@link #param(String, java.util.Collection)} adds a form parameter and
+ * this method sets a query parameter.
+ *
+ * @param parameterName The parameter name
+ * @param parameterValues The parameter values
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification queryParam(String parameterName, Collection> parameterValues);
+
+ /**
+ * Specify the form parameters that'll be sent with the request. Note that this method is the same as {@link #params(String, Object, Object...)}
+ * for all http methods except for POST where {@link #params(String, Object, Object...)} sets the form parameters and this method sets the
+ * form parameters.
+ *
+ * @param firstParameterName The name of the first parameter
+ * @param firstParameterValue The value of the first parameter
+ * @param parameterNameValuePairs The value of the first parameter followed by additional parameters in name-value pairs.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification formParams(String firstParameterName, Object firstParameterValue, Object... parameterNameValuePairs);
+
+ /**
+ * Specify the form parameters that'll be sent with the request. Note that this method is the same as {@link #params(Map)}
+ * for all http methods except for POST where {@link #params(Map)} sets the form parameters and this method sets the
+ * form parameters.
+ *
+ * @param parametersMap The Map containing the parameter names and their values to send with the request.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification formParams(Map+ *
+ * given().formParam("cars", asList("Volvo", "Saab"))..; + *+ * This will set the parameter
cars=Volvo
and cars=Saab
.
+ *
+ *
+ * Note that this method is the same as {@link #param(String, java.util.Collection)}
+ * for all http methods except for POST where {@link #param(String, java.util.Collection)} adds a form parameter and
+ * this method sets a form parameter.
+ *
+ * @param parameterName The parameter name
+ * @param parameterValues The parameter values
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification formParam(String parameterName, Collection> parameterValues);
+
+ /**
+ * Specify a single-value request attribute
+ *
+ * @param attributeName The attribute name
+ * @param attributeValue The attribute value
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification attribute(String attributeName, Object attributeValue);
+
+ /**
+ * Specify request attributes as a map
+ *
+ * @param attributesMap The Map containing the request attribute names and their values
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification attributes(Map+ * Example of use: + *
+ * given().body("{ \"message\" : \"hello world\"}").then().expect().body(equalTo("hello world")).when().post("/json"); + *+ * This will POST a request containing JSON to "/json" and expect that the response body equals to "hello world". + * + * + * + * @param body The body to send. + * @return The request specification + */ + WebTestClientRequestSpecification body(String body); + + /** + * Specify a byte array request body that'll be sent with the request. This only works for the + * POST http method. Trying to do this for the other http methods will cause an exception to be thrown. + *
+ * Example of use: + *
+ * byte[] someBytes = .. + * given().body(someBytes).then().expect().body(equalTo("hello world")).when().post("/json"); + *+ * This will POST a request containing
someBytes
to "/json" and expect that the response body equals to "hello world".
+ *
+ *
+ *
+ * @param body The body to send.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification body(byte[] body);
+
+ /**
+ * Specify file content that'll be sent with the request. This only works for the
+ * POST, PATCH and PUT http method. Trying to do this for the other http methods will cause an exception to be thrown.
+ * + * Example of use: + *
+ * File myFile = .. + * given().content(myFile).when().post("/json").then().content(equalTo("hello world")); + *+ * This will POST a request containing
myFile
to "/json" and expect that the response content equals to "hello world".
+ *
+ *
+ *
+ * @param body The content to send.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification body(File body);
+
+ /**
+ * Specify an Object request content that will automatically be serialized to JSON or XML and sent with the request.
+ * If the object is a primitive or Number the object will
+ * be converted to a String and put in the request body. This works for the POST and PUT methods only.
+ * Trying to do this for the other http methods will cause an exception to be thrown.
+ * + * Example of use: + *
+ * Message message = new Message(); + * message.setMessage("My beautiful message"); + * + * given(). + * contentType("application/json"). + * body(message). + * expect(). + * content(equalTo("Response to a beautiful message")). + * when(). + * post("/beautiful-message"); + *+ * + * Since the content-type is "application/json" then REST Assured will automatically try to serialize the object using + * Jackson or Gson if they are + * available in the classpath. If any of these frameworks are not in the classpath then an exception is thrown. + *
+ * Message message = new Message(); + * message.setMessage("My beautiful message"); + * + * given(). + * body(message, new MyObjectMapper()). + * expect(). + * content(equalTo("Response to a beautiful message")). + * when(). + * post("/beautiful-message"); + *+ * + * @param object The object to serialize and send with the request + * @param mapper The object mapper + * @return The request specification + */ + WebTestClientRequestSpecification body(Object object, ObjectMapper mapper); + + /** + * Specify an Object request content that will automatically be serialized to JSON or XML and sent with the request using a specific object mapper type. + * This works for the POST, PATCH and PUT methods only. Trying to do this for the other http methods will cause an exception to be thrown. + * + * Example of use: + *
+ * Message message = new Message(); + * message.setMessage("My beautiful message"); + * + * given(). + * body(message, ObjectMapper.GSON). + * expect(). + * content(equalTo("Response to a beautiful message")). + * when(). + * post("/beautiful-message"); + *+ * + * @param object The object to serialize and send with the request + * @param mapperType The object mapper type to be used + * @return The request specification + */ + WebTestClientRequestSpecification body(Object object, ObjectMapperType mapperType); + + /** + * Specify the cookies that'll be sent with the request. This is done by specifying the cookies in name-value pairs, e.g: + *
+ * given().cookies("username", "John", "token", "1234").then().expect().body(equalTo("username, token")).when().get("/cookie"); + *+ * + * This will send a GET request to "/cookie" with two cookies: + *
+ * Map<String, String> cookies = new HashMap<String, String>(); + * cookies.put("username", "John"); + * cookies.put("token", "1234"); + * given().cookies(cookies).then().expect().body(equalTo("username, token")).when().get("/cookie"); + *+ * + * This will send a GET request to "/cookie" with two cookies: + *
+ * Cookie cookie1 = Cookie.Builder("username", "John").setComment("comment 1").build(); + * Cookie cookie2 = Cookie.Builder("token", 1234).setComment("comment 2").build(); + * Cookies cookies = new Cookies(cookie1, cookie2); + * given().cookies(cookies).then().expect().body(equalTo("username, token")).when().get("/cookie"); + *+ * + * This will send a GET request to "/cookie" with two cookies: + *
+ *
+ * given().cookie("username", "John").and().expect().body(equalTo("username")).when().get("/cookie"); + *+ * This will set the cookie
username=John
in the GET request to "/cookie".
+ *
+ *
+ * + * You can also specify several cookies like this: + *
+ * given().cookie("username", "John").and().cookie("password", "1234").and().expect().body(equalTo("username")).when().get("/cookie"); + *+ * + * + * If you specify
additionalValues
then the Cookie will be a multi-value cookie. This means that you'll create several cookies with the
+ * same name but with different values.
+ *
+ * @param cookieName The cookie cookieName
+ * @param value The cookie value
+ * @param additionalValues Additional cookies values. This will actually create two cookies with the same name but with different values.
+ * @return The request specification
+ *
+ * @see #cookies(String, Object, Object...)
+ */
+ WebTestClientRequestSpecification cookie(String cookieName, Object value, Object... additionalValues);
+
+ /**
+ * Specify a {@link Cookie} to send with the request.
+ * + *
+ * Cookie someCookie = new Cookie.Builder("some_cookie", "some_value").setSecured(true).build(); + * given().cookie(someCookie).and().expect().body(equalTo("x")).when().get("/cookie"); + *+ * This will set the cookie
someCookie
in the GET request to "/cookie".
+ *
+ *
+ * @param cookie The cookie to add to the request
+ * @return The request specification
+ *
+ * @see #cookies(Cookies)
+ */
+ WebTestClientRequestSpecification cookie(Cookie cookie);
+
+ /**
+ * Specify a file to upload to the server using multi-part form data uploading.
+ * It will assume that the control name is file and the mime-type is application/octet-stream.
+ * If this is not what you want please use an overloaded method.
+ *
+ * @param file The file to upload
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(File file);
+
+ /**
+ * Specify a file to upload to the server using multi-part form data uploading with a specific
+ * control name. It will use the mime-type application/octet-stream.
+ * If this is not what you want please use an overloaded method.
+ *
+ * @param file The file to upload
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, File file);
+
+ /**
+ * Specify a file to upload to the server using multi-part form data uploading with a specific
+ * control name and mime-type.
+ *
+ * @param file The file to upload
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param mimeType The mime-type
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, File file, String mimeType);
+
+ /**
+ * Specify an object that will be serialized to JSON and uploaded to the server using multi-part form data
+ * uploading with a specific control name. It will use mime-type application/json.
+ * If this is not what you want please use an overloaded method.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param object The object to serialize to JSON or XML and send to the server
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, Object object);
+
+ /**
+ * Specify an object that will be serialized and uploaded to the server using multi-part form data
+ * uploading with a specific control name.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param object The object to serialize to JSON or XML and send to the server
+ * @param mimeType The mime-type
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, Object object, String mimeType);
+
+ /**
+ * Specify an object that will be serialized and uploaded to the server using multi-part form data
+ * uploading with a specific control name.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param filename The name of the content you're uploading
+ * @param object The object to serialize to JSON or XML and send to the server
+ * @param mimeType The mime-type
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, String filename, Object object, String mimeType);
+
+ /**
+ * Specify a byte-array to upload to the server using multi-part form data.
+ * It will use the mime-type application/octet-stream. If this is not what you want please use an overloaded method.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param fileName The name of the content you're uploading
+ * @param bytes The bytes you want to send
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, String fileName, byte[] bytes);
+
+ /**
+ * Specify a byte-array to upload to the server using multi-part form data.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param fileName The name of the content you're uploading
+ * @param bytes The bytes you want to send
+ * @param mimeType The mime-type
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, String fileName, byte[] bytes, String mimeType);
+
+ /**
+ * Specify an inputstream to upload to the server using multi-part form data.
+ * It will use the mime-type application/octet-stream. If this is not what you want please use an overloaded method.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param fileName The name of the content you're uploading
+ * @param stream The stream you want to send
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, String fileName, InputStream stream);
+
+ /**
+ * Specify an inputstream to upload to the server using multi-part form data.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param fileName The name of the content you're uploading
+ * @param stream The stream you want to send
+ * @param mimeType The mime-type
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, String fileName, InputStream stream, String mimeType);
+
+ /**
+ * Specify a string to send to the server using multi-part form data.
+ * It will use the mime-type text/plain. If this is not what you want please use an overloaded method.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param contentBody The string to send
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, String contentBody);
+
+ /**
+ * Specify a string to send to the server using multi-part form data with a specific mime-type.
+ *
+ * @param controlName Defines the control name of the body part. In HTML this is the attribute name of the input tag.
+ * @param contentBody The string to send
+ * @param mimeType The mime-type
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification multiPart(String controlName, String contentBody, String mimeType);
+
+ /**
+ * Define a REST Assured WebTestClient configuration. E.g.
+ * + * given().config(newConfig().logConfig(new LogConfig(captor, true))). .. + *+ * + *
newConfig()
can be statically imported from {@link RestAssuredWebTestClientConfig}.
+ *
+ * @param config The configuration to use for this request. If null
no config will be used.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification config(RestAssuredWebTestClientConfig config);
+
+ WebTestClientRequestSpecification config(SpecificationConfig config);
+
+ /**
+ * Add request data from a pre-defined specification. E.g.
+ * + * WebTestClientRequestSpecification requestSpec = new WebTestClientRequestSpecBuilder().addParam("parameter1", "value1").build(); + * + * given(). + * spec(requestSpec). + * param("parameter2", "value2"). + * when(). + * get("/something"); + *+ * + * This is useful when you want to reuse an entire specification across multiple requests. + * + * The specification passed to this method is merged with the current specification. Note that the supplied specification + * can overwrite data in the current specification. The following settings are overwritten: + *
requestSpecificationToMerge
)+ * RestAssured.config = newConfig().sessionConfig(new SessionConfig().sessionIdName(<sessionIdName>)); + *+ * or you can use the {@link #sessionId(String, String)} method to set it for this request only. + * + * @param sessionIdValue The session id value. + * @return The request specification + */ + WebTestClientRequestSpecification sessionId(String sessionIdValue); + + /** + * Set the session id name and value for this request. It'll override the default session id name from the configuration (by default this is {@value SessionConfig#DEFAULT_SESSION_ID_NAME}). + * You can configure the default session id name by using: + *
+ * RestAssured.config = newConfig().sessionConfig(new SessionConfig().sessionIdName(<sessionIdName>)); + *+ * and then you can use the {@link #sessionId(String)} method to set the session id value without specifying the name for each request. + * + * @param sessionIdName The session id name + * @param sessionIdValue The session id value. + * @return The request specification + */ + WebTestClientRequestSpecification sessionId(String sessionIdName, String sessionIdValue); + + /** + * Call this method when you're done setting up the request specification. + * + * @return The {@link WebTestClientRequestSender} that let's you send the request. + */ + WebTestClientRequestSender when(); + + /** + * Build a {@link WebTestClient} by registering one or more {@code @Controller}'s + * instances and configuring Spring infrastructure programmatically. + * This allows full control over the instantiation and initialization of + * controllerOrWebTestClientConfigurer, and their dependencies, similar to plain unit tests while + * also making it possible to test one controller at a time. + * + *
This uses the {@link WebTestClient#bindToController(Object...)} method under the hood. + *
+ * + * @param controllerOrWebTestClientConfigurer one or more {@link org.springframework.stereotype.Controller @Controller}'s to test + * or a combination of controllers and {@link WebTestClientConfigurer} + */ + WebTestClientRequestSpecification standaloneSetup(Object... controllerOrWebTestClientConfigurer); + + /** + * Build a {@link WebTestClient} by using a provided {@code AbstractWebTestClientBuilder} + * for configuring Spring infrastructure programmatically. + * This allows full control over the instantiation and initialization of + * controllers, and their dependencies, similar to plain unit tests while + * also making it possible to test one controller at a time. + * + *This uses the {@link WebTestClient.Builder} to set up the WebTestClient instance.
+ *
+ * @param builder {@link WebTestClient.Builder} to build the WebTestClient instance.
+ */
+ WebTestClientRequestSpecification standaloneSetup(WebTestClient.Builder builder);
+
+ WebTestClientRequestSpecification standaloneSetup(RouterFunction routerFunction, WebTestClientConfigurer... configurers);
+
+ /**
+ * Provide a {@link org.springframework.test.web.reactive.server.WebTestClient} instance to that REST Assured will use when making this request.
+ *
+ * @param webTestClient WebTestClient instance to use.
+ * @return The request specification
+ */
+ WebTestClientRequestSpecification webTestClient(WebTestClient webTestClient);
+
+ /**
+ * Build a {@link WebTestClient} using the given, fully initialized, i.e.
+ * refreshed, {@link WebApplicationContext} and assign it to REST Assured.
+ *
+ * This method has been kept for consistency, but, actually, it is only be used as {@link ApplicationContext}.
+ * The effect of calling this method is same as for {@link WebTestClientRequestSpecification#applicationContextSetup(ApplicationContext, WebTestClientConfigurer...)}
+ *
+ * @param context The web application context to use
+ * @param configurers {@link WebTestClientConfigurer}'s to be applied when creating a {@link WebTestClient} instance of this WebApplicationContext (optional)
+ */
+ WebTestClientRequestSpecification webAppContextSetup(WebApplicationContext context, WebTestClientConfigurer... configurers);
+
+ WebTestClientRequestSpecification applicationContextSetup(ApplicationContext context, WebTestClientConfigurer... configurers);
+
+ /**
+ * Syntactic sugar
+ *
+ * @return The same {@link WebTestClientRequestSpecification} instance.
+ */
+ WebTestClientRequestSpecification and();
+}
diff --git a/modules/spring-web-test-client/src/test/java/io/restassured/module/webtestclient/BasePathTest.java b/modules/spring-web-test-client/src/test/java/io/restassured/module/webtestclient/BasePathTest.java
new file mode 100644
index 000000000..b127e3d94
--- /dev/null
+++ b/modules/spring-web-test-client/src/test/java/io/restassured/module/webtestclient/BasePathTest.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2016-2018 the original author or authors.
+ *
+ * Licensed 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 io.restassured.module.webtestclient;
+
+import io.restassured.module.webtestclient.setup.BasePathController;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import static io.restassured.module.webtestclient.RestAssuredWebTestClient.given;
+import static org.hamcrest.Matchers.equalTo;
+
+public class BasePathTest {
+
+ @Before
+ public void
+ given_rest_assured_is_initialized_with_controller() {
+ RestAssuredWebTestClient.standaloneSetup(new BasePathController());
+ }
+
+ @After
+ public void
+ rest_assured_is_reset_after_each_test() {
+ RestAssuredWebTestClient.reset();
+ }
+
+ @Test
+ public void
+ base_path_is_prepended_to_path() {
+ RestAssuredWebTestClient.basePath = "/my-path";
+
+ given()
+ .param("name", "Johan")
+ .when()
+ .get("/greetingPath")
+ .then()
+ .statusCode(200)
+ .body("content", equalTo("Hello, Johan!"));
+ }
+
+ @Test
+ public void
+ default_base_path_is_slash() {
+ given()
+ .param("name", "Johan")
+ .when()
+ .get()
+ .then()
+ .statusCode(200)
+ .body("content", equalTo("Hello, Johan!"));
+ }
+
+ @Test
+ public void
+ double_slashes_are_prevented() {
+ RestAssuredWebTestClient.basePath = "/my-path/";
+
+ given()
+ .param("name", "Johan")
+ .when()
+ .get("/greetingPath")
+ .then()
+ .statusCode(200)
+ .body("content", equalTo("Hello, Johan!"));
+ }
+
+ @Test
+ public void
+ base_path_can_end_with_slash_and_path_doesnt_have_to_begin_with_slash() {
+ RestAssuredWebTestClient.basePath = "/my-path/";
+
+ given().
+ param("name", "Johan")
+ .when()
+ .get("greetingPath")
+ .then()
+ .statusCode(200)
+ .body("content", equalTo("Hello, Johan!"));
+ }
+
+ @Test
+ public void
+ base_path_doesnt_have_to_end_with_slash_even_though_path_doesnt_begin_with_slash2() {
+ RestAssuredWebTestClient.basePath = "/my-path";
+
+ given()
+ .param("name", "Johan")
+ .when()
+ .get("greetingPath")
+ .then()
+ .statusCode(200)
+ .body("content", equalTo("Hello, Johan!"));
+ }
+}
diff --git a/modules/spring-web-test-client/src/test/java/io/restassured/module/webtestclient/ContentTypeTest.java b/modules/spring-web-test-client/src/test/java/io/restassured/module/webtestclient/ContentTypeTest.java
new file mode 100644
index 000000000..057daef87
--- /dev/null
+++ b/modules/spring-web-test-client/src/test/java/io/restassured/module/webtestclient/ContentTypeTest.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2016-2018 the original author or authors.
+ *
+ * Licensed 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 io.restassured.module.webtestclient;
+
+import io.restassured.config.EncoderConfig;
+import io.restassured.http.ContentType;
+import io.restassured.module.webtestclient.setup.ContentTypeProcessor;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.springframework.web.reactive.function.server.RouterFunction;
+import org.springframework.web.reactive.function.server.ServerResponse;
+
+import static java.nio.charset.StandardCharsets.UTF_16;
+import static org.hamcrest.Matchers.contains;
+import static org.hamcrest.Matchers.equalTo;
+import static org.hamcrest.Matchers.not;
+import static org.springframework.http.HttpMethod.GET;
+import static org.springframework.web.reactive.function.server.RequestPredicates.method;
+import static org.springframework.web.reactive.function.server.RequestPredicates.path;
+import static org.springframework.web.reactive.function.server.RouterFunctions.route;
+
+public class ContentTypeTest {
+
+ @BeforeClass
+ public static void configureWebTestClientInstance() {
+ RouterFunction