WebGraphQlTester supports HTTP header input
Closes gh-64
This commit is contained in:
@@ -66,6 +66,7 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
&& ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader);
|
||||
}
|
||||
|
||||
|
||||
private final RequestStrategy requestStrategy;
|
||||
|
||||
|
||||
@@ -77,13 +78,19 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
this.requestStrategy = requestStrategy;
|
||||
}
|
||||
|
||||
|
||||
protected RequestStrategy getRequestStrategy() {
|
||||
return this.requestStrategy;
|
||||
}
|
||||
|
||||
|
||||
protected static Configuration initJsonPathConfig() {
|
||||
return (jackson2Present ? Jackson2Configuration.create() : Configuration.builder().build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestSpec query(String query) {
|
||||
return new DefaultRequestSpec(query);
|
||||
return new DefaultRequestSpec(this.requestStrategy, query);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,7 +189,9 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
/**
|
||||
* {@link RequestSpec} that collects the query, operationName, and variables.
|
||||
*/
|
||||
private final class DefaultRequestSpec implements RequestSpec {
|
||||
protected static class DefaultRequestSpec implements RequestSpec {
|
||||
|
||||
private final RequestStrategy requestStrategy;
|
||||
|
||||
private final String query;
|
||||
|
||||
@@ -191,8 +200,10 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
|
||||
private final Map<String, Object> variables = new LinkedHashMap<>();
|
||||
|
||||
private DefaultRequestSpec(String query) {
|
||||
protected DefaultRequestSpec(RequestStrategy requestStrategy, String query) {
|
||||
Assert.notNull(requestStrategy, "RequestStrategy is required");
|
||||
Assert.notNull(query, "`query` is required");
|
||||
this.requestStrategy = requestStrategy;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
@@ -216,21 +227,25 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
|
||||
@Override
|
||||
public ResponseSpec execute() {
|
||||
RequestInput input = new RequestInput(this.query, this.operationName, this.variables);
|
||||
return DefaultGraphQlTester.this.requestStrategy.execute(input);
|
||||
RequestInput input = createRequestInput();
|
||||
return this.requestStrategy.execute(input);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeAndVerify() {
|
||||
RequestInput input = new RequestInput(this.query, this.operationName, this.variables);
|
||||
ResponseSpec spec = DefaultGraphQlTester.this.requestStrategy.execute(input);
|
||||
RequestInput input = createRequestInput();
|
||||
ResponseSpec spec = this.requestStrategy.execute(input);
|
||||
spec.path("$.errors").valueIsEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public SubscriptionSpec executeSubscription() {
|
||||
RequestInput input = new RequestInput(this.query, this.operationName, this.variables);
|
||||
return DefaultGraphQlTester.this.requestStrategy.executeSubscription(input);
|
||||
RequestInput input = createRequestInput();
|
||||
return this.requestStrategy.executeSubscription(input);
|
||||
}
|
||||
|
||||
protected RequestInput createRequestInput() {
|
||||
return new RequestInput(this.query, this.operationName, this.variables);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.graphql.test.tester;
|
||||
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.jayway.jsonpath.Configuration;
|
||||
import com.jayway.jsonpath.DocumentContext;
|
||||
@@ -51,6 +52,12 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public WebRequestSpec query(String query) {
|
||||
return new DefaultWebRequestSpec(getRequestStrategy(), query);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@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
|
||||
@@ -69,9 +76,20 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
|
||||
@Override
|
||||
public ResponseSpec execute(RequestInput requestInput) {
|
||||
EntityExchangeResult<byte[]> result = this.client.post().contentType(MediaType.APPLICATION_JSON)
|
||||
.bodyValue(requestInput).exchange().expectStatus().isOk().expectHeader()
|
||||
.contentType(MediaType.APPLICATION_JSON).expectBody().returnResult();
|
||||
Assert.isInstanceOf(WebInput.class, requestInput);
|
||||
WebInput webInput = (WebInput) requestInput;
|
||||
|
||||
EntityExchangeResult<byte[]> result = this.client.post()
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.headers(headers -> headers.putAll(webInput.getHeaders()))
|
||||
.bodyValue(requestInput)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectHeader()
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.expectBody()
|
||||
.returnResult();
|
||||
|
||||
byte[] bytes = result.getResponseBodyContent();
|
||||
Assert.notNull(bytes, "Expected GraphQL response content");
|
||||
@@ -83,9 +101,19 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
|
||||
@Override
|
||||
public SubscriptionSpec executeSubscription(RequestInput requestInput) {
|
||||
Assert.isInstanceOf(WebInput.class, requestInput);
|
||||
WebInput webInput = (WebInput) requestInput;
|
||||
|
||||
FluxExchangeResult<TestExecutionResult> exchangeResult = this.client.post()
|
||||
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.TEXT_EVENT_STREAM).bodyValue(requestInput)
|
||||
.exchange().expectStatus().isOk().expectHeader().contentType(MediaType.TEXT_EVENT_STREAM)
|
||||
.contentType(MediaType.APPLICATION_JSON)
|
||||
.accept(MediaType.TEXT_EVENT_STREAM)
|
||||
.headers(headers -> headers.putAll(webInput.getHeaders()))
|
||||
.bodyValue(requestInput)
|
||||
.exchange()
|
||||
.expectStatus()
|
||||
.isOk()
|
||||
.expectHeader()
|
||||
.contentType(MediaType.TEXT_EVENT_STREAM)
|
||||
.returnResult(TestExecutionResult.class);
|
||||
|
||||
return new DefaultSubscriptionSpec(exchangeResult.getResponseBody().cast(ExecutionResult.class),
|
||||
@@ -100,10 +128,6 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
*/
|
||||
private static class WebGraphQlHandlerRequestStrategy extends AbstractDirectRequestStrategy {
|
||||
|
||||
private static final URI DEFAULT_URL = URI.create("http://localhost:8080/graphql");
|
||||
|
||||
private static final HttpHeaders DEFAULT_HEADERS = new HttpHeaders();
|
||||
|
||||
private final WebGraphQlHandler graphQlHandler;
|
||||
|
||||
WebGraphQlHandlerRequestStrategy(WebGraphQlHandler handler, Configuration jsonPathConfig) {
|
||||
@@ -111,12 +135,44 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
this.graphQlHandler = handler;
|
||||
}
|
||||
|
||||
protected ExecutionResult executeInternal(RequestInput input) {
|
||||
WebInput webInput = new WebInput(DEFAULT_URL, DEFAULT_HEADERS, input.toMap(), null);
|
||||
ExecutionResult result = this.graphQlHandler.handle(webInput).block(DEFAULT_TIMEOUT);
|
||||
protected ExecutionResult executeInternal(RequestInput requestInput) {
|
||||
Assert.isInstanceOf(WebInput.class, requestInput);
|
||||
ExecutionResult result = this.graphQlHandler.handle((WebInput) requestInput).block(DEFAULT_TIMEOUT);
|
||||
Assert.notNull(result, "Expected ExecutionResult");
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
protected 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) {
|
||||
super(requestStrategy, query);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebRequestSpec header(String headerName, String... headerValues) {
|
||||
for (String headerValue : headerValues) {
|
||||
this.headers.add(headerName, headerValue);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebRequestSpec headers(Consumer<HttpHeaders> headersConsumer) {
|
||||
headersConsumer.accept(this.headers);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RequestInput createRequestInput() {
|
||||
RequestInput requestInput = super.createRequestInput();
|
||||
return new WebInput(DEFAULT_URL, headers, requestInput.toMap(), null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
*/
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
|
||||
/**
|
||||
@@ -79,6 +82,12 @@ import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
*/
|
||||
public interface WebGraphQlTester extends GraphQlTester {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>The returned spec for Web request input also allows adding HTTP headers.
|
||||
*/
|
||||
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
|
||||
@@ -101,4 +110,31 @@ public interface WebGraphQlTester extends GraphQlTester {
|
||||
return new DefaultWebGraphQlTester(handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extends {@link GraphQlTester.RequestSpec} with further input options
|
||||
* applicable to Web requests.
|
||||
*/
|
||||
interface WebRequestSpec extends RequestSpec {
|
||||
|
||||
/**
|
||||
* Add the given, single header value under the given name.
|
||||
* @param headerName the header name
|
||||
* @param headerValues the header value(s)
|
||||
* @return the same instance
|
||||
*/
|
||||
WebRequestSpec header(String headerName, String... headerValues);
|
||||
|
||||
/**
|
||||
* Manipulate the request's headers with the given consumer. The
|
||||
* headers provided to the consumer are "live", so that the consumer can
|
||||
* be used to {@linkplain HttpHeaders#set(String, String) overwrite}
|
||||
* existing header values, {@linkplain HttpHeaders#remove(Object) remove}
|
||||
* values, or use any of the other {@link HttpHeaders} methods.
|
||||
* @param headersConsumer a function that consumes the {@code HttpHeaders}
|
||||
* @return this builder
|
||||
*/
|
||||
WebRequestSpec headers(Consumer<HttpHeaders> headersConsumer);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user