diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/BuilderDelegate.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/BuilderDelegate.java new file mode 100644 index 00000000..ae1d0947 --- /dev/null +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/BuilderDelegate.java @@ -0,0 +1,87 @@ +/* + * Copyright 2002-2021 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 + * + * https://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.springframework.graphql.test.tester; + +import java.time.Duration; + +import com.jayway.jsonpath.Configuration; +import com.jayway.jsonpath.spi.json.JacksonJsonProvider; +import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; + +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; + +/** + * Assist with collecting the input for {@link GraphQlTester.Builder}, + * essentially to avoid challenges with generics in the builder hierarchy. + * + * @author Rossen Stoyanchev + */ +final class BuilderDelegate { + + private static final boolean jackson2Present; + + static { + ClassLoader classLoader = DefaultGraphQlTester.class.getClassLoader(); + jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) + && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); + } + + + @Nullable + private Configuration jsonPathConfig; + + private Duration responseTimeout = Duration.ofSeconds(5); + + public void jsonPathConfig(@Nullable Configuration config) { + this.jsonPathConfig = config; + } + + public void responseTimeout(Duration timeout) { + Assert.notNull(timeout, "'timeout' is required"); + this.responseTimeout = timeout; + } + + public Configuration initJsonPathConfig() { + if (this.jsonPathConfig != null) { + return this.jsonPathConfig; + } + else if (jackson2Present) { + return Jackson2Configuration.create(); + } + else { + return Configuration.builder().build(); + } + } + + public Duration getResponseTimeout() { + return this.responseTimeout; + } + + + private static class Jackson2Configuration { + + static Configuration create() { + return Configuration.builder() + .jsonProvider(new JacksonJsonProvider()) + .mappingProvider(new JacksonMappingProvider()) + .build(); + } + + } + +} diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java index 6e833646..d74821e0 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultGraphQlTester.java @@ -32,8 +32,7 @@ import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.PathNotFoundException; import com.jayway.jsonpath.TypeRef; -import com.jayway.jsonpath.spi.json.JacksonJsonProvider; -import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider; +import graphql.ExecutionInput; import graphql.ExecutionResult; import graphql.GraphQLError; import org.reactivestreams.Publisher; @@ -47,7 +46,6 @@ import org.springframework.test.util.AssertionErrors; import org.springframework.test.util.JsonExpectationsHelper; import org.springframework.test.util.JsonPathExpectationsHelper; import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; @@ -58,20 +56,11 @@ import org.springframework.util.StringUtils; */ class DefaultGraphQlTester implements GraphQlTester { - private static final boolean jackson2Present; - - static { - ClassLoader classLoader = DefaultGraphQlTester.class.getClassLoader(); - jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) - && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); - } - - private final RequestStrategy requestStrategy; - DefaultGraphQlTester(GraphQlService service) { - this(new GraphQlServiceRequestStrategy(service, initJsonPathConfig())); + DefaultGraphQlTester(GraphQlService service, Configuration config, Duration responseTimeout) { + this(new GraphQlServiceRequestStrategy(service, config, responseTimeout)); } DefaultGraphQlTester(RequestStrategy requestStrategy) { @@ -84,17 +73,48 @@ class DefaultGraphQlTester implements GraphQlTester { } - protected static Configuration initJsonPathConfig() { - return (jackson2Present ? Jackson2Configuration.create() : Configuration.builder().build()); - } - @Override public RequestSpec query(String query) { return new DefaultRequestSpec(this.requestStrategy, query); } + /** - * Encapsulate how a GraphQL request is performed. + * Default implementation to build {@link GraphQlTester}. + */ + final static class DefaultBuilder implements Builder { + + private final GraphQlService service; + + private final BuilderDelegate delegate = new BuilderDelegate(); + + DefaultBuilder(GraphQlService service) { + Assert.notNull(service, "GraphQlService is required."); + this.service = service; + } + + @Override + public DefaultBuilder jsonPathConfig(Configuration config) { + this.delegate.jsonPathConfig(config); + return this; + } + + @Override + public DefaultBuilder responseTimeout(Duration timeout) { + this.delegate.responseTimeout(timeout); + return this; + } + + @Override + public GraphQlTester build() { + return new DefaultGraphQlTester( + this.service, this.delegate.initJsonPathConfig(), this.delegate.getResponseTimeout()); + } + + } + + /** + * Internal strategy abstracting how a GraphQL request is performed. */ interface RequestStrategy { @@ -121,12 +141,17 @@ class DefaultGraphQlTester implements GraphQlTester { */ protected abstract static class AbstractDirectRequestStrategy implements RequestStrategy { - protected static final Duration DEFAULT_TIMEOUT = Duration.ofSeconds(5); - private final Configuration jsonPathConfig; - protected AbstractDirectRequestStrategy(Configuration jsonPathConfig) { + private final Duration responseTimeout; + + protected AbstractDirectRequestStrategy(Configuration jsonPathConfig, Duration responseTimeout) { this.jsonPathConfig = jsonPathConfig; + this.responseTimeout = responseTimeout; + } + + protected Duration getResponseTimeout() { + return this.responseTimeout; } @Override @@ -174,13 +199,17 @@ class DefaultGraphQlTester implements GraphQlTester { private final GraphQlService graphQlService; - protected GraphQlServiceRequestStrategy(GraphQlService service, Configuration jsonPathConfig) { - super(jsonPathConfig); + protected GraphQlServiceRequestStrategy( + GraphQlService service, Configuration jsonPathConfig, Duration responseTimeout) { + + super(jsonPathConfig, responseTimeout); + Assert.notNull(service, "GraphQlService is required."); this.graphQlService = service; } protected ExecutionResult executeInternal(RequestInput input) { - ExecutionResult result = this.graphQlService.execute(input.toExecutionInput()).block(DEFAULT_TIMEOUT); + ExecutionInput executionInput = input.toExecutionInput(); + ExecutionResult result = this.graphQlService.execute(executionInput).block(getResponseTimeout()); Assert.notNull(result, "Expected ExecutionResult"); return result; } @@ -711,13 +740,4 @@ class DefaultGraphQlTester implements GraphQlTester { } - private static class Jackson2Configuration { - - static Configuration create() { - return Configuration.builder().jsonProvider(new JacksonJsonProvider()) - .mappingProvider(new JacksonMappingProvider()).build(); - } - - } - } diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTester.java index 2126d001..a3fde271 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/DefaultWebGraphQlTester.java @@ -18,7 +18,9 @@ package org.springframework.graphql.test.tester; import java.net.URI; import java.nio.charset.StandardCharsets; +import java.time.Duration; import java.util.function.Consumer; +import java.util.function.Supplier; import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.DocumentContext; @@ -30,10 +32,12 @@ import org.springframework.graphql.web.WebGraphQlHandler; import org.springframework.graphql.web.WebInput; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; +import org.springframework.lang.Nullable; 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.Assert; +import org.springframework.util.CollectionUtils; /** * Default implementation of {@link WebGraphQlTester}. @@ -42,22 +46,82 @@ import org.springframework.util.Assert; */ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQlTester { + @Nullable + private final HttpHeaders defaultHeaders; - DefaultWebGraphQlTester(WebTestClient client) { - super(new WebTestClientRequestStrategy(client, initJsonPathConfig())); - } - DefaultWebGraphQlTester(WebGraphQlHandler handler) { - super(new WebGraphQlHandlerRequestStrategy(handler, initJsonPathConfig())); + DefaultWebGraphQlTester(RequestStrategy requestStrategy, @Nullable HttpHeaders defaultHeaders) { + super(requestStrategy); + this.defaultHeaders = defaultHeaders; } @Override public WebRequestSpec query(String query) { - return new DefaultWebRequestSpec(getRequestStrategy(), query); + return new DefaultWebRequestSpec(getRequestStrategy(), query, this.defaultHeaders); } + /** + * Default implementation to build {@link WebGraphQlTester}. + */ + final static class DefaultBuilder implements WebGraphQlTester.Builder { + + private final Supplier requestStrategySupplier; + + private final BuilderDelegate delegate = new BuilderDelegate(); + + @Nullable + private HttpHeaders headers; + + DefaultBuilder(WebTestClient client) { + this.requestStrategySupplier = () -> + new WebTestClientRequestStrategy( + client.mutate().responseTimeout(this.delegate.getResponseTimeout()).build(), + this.delegate.initJsonPathConfig()); + } + + DefaultBuilder(WebGraphQlHandler handler) { + this.requestStrategySupplier = () -> + new WebGraphQlHandlerRequestStrategy(handler, + this.delegate.initJsonPathConfig(), + this.delegate.getResponseTimeout()); + } + + @Override + public DefaultBuilder jsonPathConfig(Configuration config) { + this.delegate.jsonPathConfig(config); + return this; + } + + @Override + public DefaultBuilder responseTimeout(Duration timeout) { + this.delegate.responseTimeout(timeout); + return this; + } + + @Override + public DefaultBuilder defaultHeader(String headerName, String... headerValues) { + this.headers = (this.headers != null ? this.headers : new HttpHeaders()); + for (String headerValue : headerValues) { + this.headers.add(headerName, headerValue); + } + return this; + } + + @Override + public WebGraphQlTester.Builder defaultHeaders(Consumer headersConsumer) { + this.headers = (this.headers != null ? this.headers : new HttpHeaders()); + headersConsumer.accept(this.headers); + return this; + } + + @Override + public WebGraphQlTester build() { + return new DefaultWebGraphQlTester(this.requestStrategySupplier.get(), this.headers); + } + } + /** * {@link RequestStrategy} that works as an HTTP client with requests executed through * {@link WebTestClient} that in turn may work connect with or without a live server @@ -76,12 +140,9 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl @Override public ResponseSpec execute(RequestInput requestInput) { - Assert.isInstanceOf(WebInput.class, requestInput); - WebInput webInput = (WebInput) requestInput; - EntityExchangeResult result = this.client.post() .contentType(MediaType.APPLICATION_JSON) - .headers(headers -> headers.putAll(webInput.getHeaders())) + .headers(headers -> headers.putAll(getHeaders(requestInput))) .bodyValue(requestInput) .exchange() .expectStatus() @@ -101,13 +162,10 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl @Override public SubscriptionSpec executeSubscription(RequestInput requestInput) { - Assert.isInstanceOf(WebInput.class, requestInput); - WebInput webInput = (WebInput) requestInput; - FluxExchangeResult exchangeResult = this.client.post() .contentType(MediaType.APPLICATION_JSON) .accept(MediaType.TEXT_EVENT_STREAM) - .headers(headers -> headers.putAll(webInput.getHeaders())) + .headers(headers -> headers.putAll(getHeaders(requestInput))) .bodyValue(requestInput) .exchange() .expectStatus() @@ -120,6 +178,11 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl this.jsonPathConfig, exchangeResult::assertWithDiagnostics); } + private HttpHeaders getHeaders(RequestInput requestInput) { + Assert.isInstanceOf(WebInput.class, requestInput); + return ((WebInput) requestInput).getHeaders(); + } + } /** @@ -130,27 +193,32 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl private final WebGraphQlHandler graphQlHandler; - WebGraphQlHandlerRequestStrategy(WebGraphQlHandler handler, Configuration jsonPathConfig) { - super(jsonPathConfig); + WebGraphQlHandlerRequestStrategy(WebGraphQlHandler handler, Configuration config, Duration responseTimeout) { + super(config, responseTimeout); this.graphQlHandler = handler; } - protected ExecutionResult executeInternal(RequestInput requestInput) { - Assert.isInstanceOf(WebInput.class, requestInput); - ExecutionResult result = this.graphQlHandler.handle((WebInput) requestInput).block(DEFAULT_TIMEOUT); + protected ExecutionResult executeInternal(RequestInput input) { + Assert.isInstanceOf(WebInput.class, input); + WebInput webInput = (WebInput) input; + ExecutionResult result = this.graphQlHandler.handle(webInput).block(getResponseTimeout()); Assert.notNull(result, "Expected ExecutionResult"); return result; } + } - protected static final class DefaultWebRequestSpec extends DefaultRequestSpec implements WebRequestSpec { + private static final class DefaultWebRequestSpec extends DefaultRequestSpec implements WebRequestSpec { private static final URI DEFAULT_URL = URI.create(""); private final HttpHeaders headers = new HttpHeaders(); - public DefaultWebRequestSpec(RequestStrategy requestStrategy, String query) { + DefaultWebRequestSpec(RequestStrategy requestStrategy, String query, @Nullable HttpHeaders headers) { super(requestStrategy, query); + if (!CollectionUtils.isEmpty(headers)) { + this.headers.putAll(headers); + } } @Override @@ -170,7 +238,7 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl @Override protected RequestInput createRequestInput() { RequestInput requestInput = super.createRequestInput(); - return new WebInput(DEFAULT_URL, headers, requestInput.toMap(), null); + return new WebInput(DEFAULT_URL, this.headers, requestInput.toMap(), null); } } diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java index 1461d698..5a662d31 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/GraphQlTester.java @@ -16,11 +16,12 @@ package org.springframework.graphql.test.tester; +import java.time.Duration; import java.util.List; -import java.util.Map; import java.util.function.Consumer; import java.util.function.Predicate; +import com.jayway.jsonpath.Configuration; import graphql.GraphQLError; import reactor.core.publisher.Flux; @@ -43,25 +44,65 @@ import org.springframework.lang.Nullable; public interface GraphQlTester { /** - * Prepare to perform a GraphQL request with the given operation which may be a query, - * mutation, or a subscription. + * Prepare to perform a GraphQL request with the given operation which may + * be a query, mutation, or a subscription. * @param query the operation to be performed * @return spec for response assertions * @throws AssertionError if the response status is not 200 (OK) */ - RequestSpec query(String query); + RequestSpec query(String query); /** - * Create a {@code GraphQlTester} that performs GraphQL requests through the given - * {@link GraphQlService}. + * Create a {@code GraphQlTester} that performs GraphQL requests through the + * given {@link GraphQlService}. * @param service the service to execute requests with * @return the created {@code GraphQlTester} */ static GraphQlTester create(GraphQlService service) { - return new DefaultGraphQlTester(service); + return builder(service).build(); } + /** + * Return a builder with options to initialize a {@code GraphQlTester}. + * @param service the service to execute requests with + * @return the builder to use + */ + static Builder builder(GraphQlService service) { + return new DefaultGraphQlTester.DefaultBuilder(service); + } + + + /** + * A builder to create a {@link GraphQlTester} instance. + */ + interface Builder> { + + /** + * Provide JSONPath configuration settings, including a + * {@link com.jayway.jsonpath.spi.json.JsonProvider} as well as a + * {@link com.jayway.jsonpath.spi.mapper.MappingProvider} that are used + * to serialize and deserialize GraphQL JSON content. + *

By default the configuration is to use Jackson JSON if it is + * present on the classpath. + * @param config the JSONPath configuration to use + * @return the same builder instance + */ + T jsonPathConfig(Configuration config); + + /** + * Max amount of time to wait for a GraphQL response. + *

By default this is set to 5 seconds. + * @param timeout the response timeout value + */ + T responseTimeout(Duration timeout); + + /** + * Build the {@code GraphQlTester}. + * @return the created instance + */ + GraphQlTester build(); + } /** * Declare options to perform a GraphQL request. diff --git a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlTester.java b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlTester.java index 907abf19..f4e58590 100644 --- a/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlTester.java +++ b/spring-graphql-test/src/main/java/org/springframework/graphql/test/tester/WebGraphQlTester.java @@ -88,6 +88,7 @@ public interface WebGraphQlTester extends GraphQlTester { */ WebRequestSpec query(String query); + /** * Create a {@code WebGraphQlTester} that performs GraphQL requests as an * HTTP client through the given {@link WebTestClient}. Depending on how the @@ -97,7 +98,7 @@ public interface WebGraphQlTester extends GraphQlTester { * @return the created {@code WebGraphQlTester} */ static WebGraphQlTester create(WebTestClient client) { - return new DefaultWebGraphQlTester(client); + return builder(client).build(); } /** @@ -107,7 +108,54 @@ public interface WebGraphQlTester extends GraphQlTester { * @return the created {@code WebGraphQlTester} */ static WebGraphQlTester create(WebGraphQlHandler handler) { - return new DefaultWebGraphQlTester(handler); + return builder(handler).build(); + } + + /** + * Return a builder with options to initialize a {@code WebGraphQlTester}. + * @param client the client to execute requests with + * @return the builder to use + */ + static Builder builder(WebTestClient client) { + return new DefaultWebGraphQlTester.DefaultBuilder(client); + } + + /** + * Return a builder with options to initialize a {@code WebGraphQlHandler}. + * @param handler the handler to execute requests with + * @return the builder to use + */ + static Builder builder(WebGraphQlHandler handler) { + return new DefaultWebGraphQlTester.DefaultBuilder(handler); + } + + + /** + * A builder to create a {@link WebGraphQlTester} instance. + */ + interface Builder extends GraphQlTester.Builder { + + /** + * Add the given header to all requests that haven't added it. + * @param headerName the header name + * @param headerValues the header values + */ + Builder defaultHeader(String headerName, String... headerValues); + + /** + * Variant of {@link #defaultHeader(String, String...)} that provides + * access to the underlying headers to inspect or modify directly. + * @param headersConsumer a function that consumes the {@code HttpHeaders} + */ + Builder defaultHeaders(Consumer headersConsumer); + + /** + * Build the {@code WebGraphQlTester}. + * @return the created instance + */ + @Override + WebGraphQlTester build(); + } /** diff --git a/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/WebGraphQlTesterTests.java b/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/WebGraphQlTesterTests.java index 6771913f..6db338de 100644 --- a/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/WebGraphQlTesterTests.java +++ b/spring-graphql-test/src/test/java/org/springframework/graphql/test/tester/WebGraphQlTesterTests.java @@ -71,27 +71,62 @@ public class WebGraphQlTesterTests { return Stream.of(new MockWebServerSetup(), new MockWebGraphQlHandlerSetup()); } + @ParameterizedTest @MethodSource("argumentSource") - void pathAndValueExistsAndEmptyChecks(GraphQlTesterSetup setup) throws Exception { + void headers(GraphQlTesterSetup setup) throws Exception { String query = "{me {name, friends}}"; setup.response("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}"); - GraphQlTester.ResponseSpec spec = setup.graphQlTester().query(query).execute(); + GraphQlTester.ResponseSpec spec = setup.graphQlTester().query(query) + .header("myHeader1", "myValue1a") + .header("myHeader1", "myValue1b") + .headers(headers -> headers.add("myHeader2", "myValue2")) + .execute(); - spec.path("me.name").pathExists().valueExists().valueIsNotEmpty(); - spec.path("me.friends").valueIsEmpty(); - spec.path("hero").pathDoesNotExist().valueDoesNotExist().valueIsEmpty(); + spec.path("me.name").entity(String.class).isEqualTo("Luke Skywalker"); + + setup.verifyRequest((input) -> { + assertThat(input.getQuery()).contains(query); + assertThat(input.getHeaders().get("myHeader1")).containsExactly("myValue1a", "myValue1b"); + assertThat(input.getHeaders().getFirst("myHeader2")).isEqualTo("myValue2"); + }); + setup.shutdown(); + } + + @ParameterizedTest + @MethodSource("argumentSource") + void defaultHeaders(GraphQlTesterSetup setup) throws Exception { + + String query = "{me {name, friends}}"; + setup.response("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}"); + + GraphQlTester.ResponseSpec spec = setup.graphQlTesterBuilder() + .defaultHeader("myHeader1", "myValue1a") + .defaultHeader("myHeader1", "myValue1b") + .defaultHeaders(headers -> headers.add("myHeader2", "myValue2")) + .build() + .query(query) + .execute(); + + spec.path("me.name").entity(String.class).isEqualTo("Luke Skywalker"); + + setup.verifyRequest((input) -> { + assertThat(input.getQuery()).contains(query); + assertThat(input.getHeaders().get("myHeader1")).containsExactly("myValue1a", "myValue1b"); + assertThat(input.getHeaders().getFirst("myHeader2")).isEqualTo("myValue2"); + }); - setup.verifyRequest((input) -> assertThat(input.getQuery()).contains(query)); setup.shutdown(); } private interface GraphQlTesterSetup { - GraphQlTester graphQlTester(); + WebGraphQlTester graphQlTester(); + + WebGraphQlTester.Builder graphQlTesterBuilder(); default void response(String data) throws Exception { response(data, Collections.emptyList()); @@ -115,11 +150,11 @@ public class WebGraphQlTesterTests { private final MockWebServer server; - private final GraphQlTester graphQlTester; + private final WebGraphQlTester.Builder graphQlTesterBuilder; MockWebServerSetup() { this.server = new MockWebServer(); - this.graphQlTester = WebGraphQlTester.create(initWebTestClient(this.server)); + this.graphQlTesterBuilder = WebGraphQlTester.builder(initWebTestClient(this.server)); } private static WebTestClient initWebTestClient(MockWebServer server) { @@ -128,8 +163,13 @@ public class WebGraphQlTesterTests { } @Override - public GraphQlTester graphQlTester() { - return this.graphQlTester; + public WebGraphQlTester graphQlTester() { + return this.graphQlTesterBuilder.build(); + } + + @Override + public WebGraphQlTester.Builder graphQlTesterBuilder() { + return this.graphQlTesterBuilder; } @Override @@ -160,10 +200,12 @@ public class WebGraphQlTesterTests { RecordedRequest request = this.server.takeRequest(); assertThat(request.getHeader(HttpHeaders.CONTENT_TYPE)).isEqualTo("application/json"); + HttpHeaders headers = new HttpHeaders(); + request.getHeaders().names().forEach(name -> headers.put(name, request.getHeaders().values(name))); + String content = request.getBody().readUtf8(); - Map map = new ObjectMapper().readValue(content, new TypeReference>() { - }); - WebInput webInput = new WebInput(request.getRequestUrl().uri(), new HttpHeaders(), map, null); + Map map = new ObjectMapper().readValue(content, new TypeReference>() {}); + WebInput webInput = new WebInput(request.getRequestUrl().uri(), headers, map, null); consumer.accept(webInput); } @@ -181,15 +223,20 @@ public class WebGraphQlTesterTests { private final ArgumentCaptor bodyCaptor = ArgumentCaptor.forClass(WebInput.class); - private final GraphQlTester graphQlTester; + private final WebGraphQlTester.Builder graphQlTesterBuilder; MockWebGraphQlHandlerSetup() { - this.graphQlTester = WebGraphQlTester.create(this.handler); + this.graphQlTesterBuilder = WebGraphQlTester.builder(this.handler); } @Override - public GraphQlTester graphQlTester() { - return this.graphQlTester; + public WebGraphQlTester graphQlTester() { + return this.graphQlTesterBuilder.build(); + } + + @Override + public WebGraphQlTester.Builder graphQlTesterBuilder() { + return this.graphQlTesterBuilder; } @Override