Global error filter in GraphQlTester.Builder
See gh-66
This commit is contained in:
@@ -59,8 +59,8 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
private final RequestStrategy requestStrategy;
|
||||
|
||||
|
||||
DefaultGraphQlTester(GraphQlService service, Configuration config, Duration responseTimeout) {
|
||||
this(new GraphQlServiceRequestStrategy(service, config, responseTimeout));
|
||||
DefaultGraphQlTester(GraphQlService service, GraphQlTesterBuilderConfig builderConfig) {
|
||||
this(new GraphQlServiceRequestStrategy(service, builderConfig));
|
||||
}
|
||||
|
||||
DefaultGraphQlTester(RequestStrategy requestStrategy) {
|
||||
@@ -86,29 +86,34 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
|
||||
private final GraphQlService service;
|
||||
|
||||
private final BuilderDelegate delegate = new BuilderDelegate();
|
||||
private final GraphQlTesterBuilderConfig builderConfig = new GraphQlTesterBuilderConfig();
|
||||
|
||||
DefaultBuilder(GraphQlService service) {
|
||||
Assert.notNull(service, "GraphQlService is required.");
|
||||
this.service = service;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultBuilder errorFilter(Predicate<GraphQLError> predicate) {
|
||||
this.builderConfig.errorFilter(predicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultBuilder jsonPathConfig(Configuration config) {
|
||||
this.delegate.jsonPathConfig(config);
|
||||
this.builderConfig.jsonPathConfig(config);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultBuilder responseTimeout(Duration timeout) {
|
||||
this.delegate.responseTimeout(timeout);
|
||||
this.builderConfig.responseTimeout(timeout);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GraphQlTester build() {
|
||||
return new DefaultGraphQlTester(
|
||||
this.service, this.delegate.initJsonPathConfig(), this.delegate.getResponseTimeout());
|
||||
return new DefaultGraphQlTester(this.service, this.builderConfig);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -141,24 +146,30 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
*/
|
||||
protected abstract static class AbstractDirectRequestStrategy implements RequestStrategy {
|
||||
|
||||
private final Configuration jsonPathConfig;
|
||||
private final GraphQlTesterBuilderConfig builderConfig;
|
||||
|
||||
private final Duration responseTimeout;
|
||||
|
||||
protected AbstractDirectRequestStrategy(Configuration jsonPathConfig, Duration responseTimeout) {
|
||||
this.jsonPathConfig = jsonPathConfig;
|
||||
this.responseTimeout = responseTimeout;
|
||||
protected AbstractDirectRequestStrategy(GraphQlTesterBuilderConfig builderConfig) {
|
||||
this.builderConfig = builderConfig;
|
||||
}
|
||||
|
||||
protected Duration getResponseTimeout() {
|
||||
return this.responseTimeout;
|
||||
@Nullable
|
||||
private Predicate<GraphQLError> errorFilter() {
|
||||
return this.builderConfig.getErrorFilter();
|
||||
}
|
||||
|
||||
private Configuration jsonPathConfig() {
|
||||
return this.builderConfig.getJsonPathConfig();
|
||||
}
|
||||
|
||||
protected Duration responseTimeout() {
|
||||
return this.builderConfig.getResponseTimeout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseSpec execute(RequestInput input) {
|
||||
ExecutionResult executionResult = executeInternal(input);
|
||||
DocumentContext context = JsonPath.parse(executionResult.toSpecification(), this.jsonPathConfig);
|
||||
return new DefaultResponseSpec(context, assertDecorator(input));
|
||||
DocumentContext context = JsonPath.parse(executionResult.toSpecification(), jsonPathConfig());
|
||||
return new DefaultResponseSpec(context, errorFilter(), assertDecorator(input));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -171,7 +182,7 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
assertDecorator.accept(() -> AssertionErrors.assertTrue(
|
||||
"Response has " + errors.size() + " unexpected error(s).", CollectionUtils.isEmpty(errors)));
|
||||
|
||||
return new DefaultSubscriptionSpec(result.getData(), this.jsonPathConfig, assertDecorator);
|
||||
return new DefaultSubscriptionSpec(result.getData(), errorFilter(), jsonPathConfig(), assertDecorator);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,17 +210,15 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
|
||||
private final GraphQlService graphQlService;
|
||||
|
||||
protected GraphQlServiceRequestStrategy(
|
||||
GraphQlService service, Configuration jsonPathConfig, Duration responseTimeout) {
|
||||
|
||||
super(jsonPathConfig, responseTimeout);
|
||||
protected GraphQlServiceRequestStrategy(GraphQlService service, GraphQlTesterBuilderConfig builderConfig) {
|
||||
super(builderConfig);
|
||||
Assert.notNull(service, "GraphQlService is required.");
|
||||
this.graphQlService = service;
|
||||
}
|
||||
|
||||
protected ExecutionResult executeInternal(RequestInput input) {
|
||||
ExecutionInput executionInput = input.toExecutionInput();
|
||||
ExecutionResult result = this.graphQlService.execute(executionInput).block(getResponseTimeout());
|
||||
ExecutionResult result = this.graphQlService.execute(executionInput).block(responseTimeout());
|
||||
Assert.notNull(result, "Expected ExecutionResult");
|
||||
return result;
|
||||
}
|
||||
@@ -324,19 +333,28 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
|
||||
private final Consumer<Runnable> assertDecorator;
|
||||
|
||||
ErrorsContainer(List<TestGraphQlError> errors, Consumer<Runnable> assertDecorator) {
|
||||
ErrorsContainer(
|
||||
List<TestGraphQlError> errors, @Nullable Predicate<GraphQLError> errorFilter,
|
||||
Consumer<Runnable> assertDecorator) {
|
||||
|
||||
Assert.notNull(errors, "`errors` is required");
|
||||
Assert.notNull(assertDecorator, "`assertDecorator` is required");
|
||||
this.errors = errors;
|
||||
this.assertDecorator = assertDecorator;
|
||||
filterErrors(errorFilter);
|
||||
}
|
||||
|
||||
void doAssert(Runnable task) {
|
||||
this.assertDecorator.accept(task);
|
||||
}
|
||||
|
||||
void filterErrors(Predicate<GraphQLError> errorPredicate) {
|
||||
this.errors.forEach((error) -> error.filter(errorPredicate));
|
||||
void filterErrors(@Nullable Predicate<GraphQLError> predicate) {
|
||||
if (predicate != null) {
|
||||
this.errors.forEach((error) -> {
|
||||
// Error marked "filtered" if true
|
||||
error.applyErrorFilterPredicate(predicate);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void consumeErrors(Consumer<List<GraphQLError>> consumer) {
|
||||
@@ -345,8 +363,8 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
}
|
||||
|
||||
void verifyErrors() {
|
||||
|
||||
List<TestGraphQlError> unexpected = this.errors.stream().filter((error) -> !error.isExpected())
|
||||
List<TestGraphQlError> unexpected = this.errors.stream()
|
||||
.filter(error -> !error.isExpected())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
this.assertDecorator
|
||||
@@ -366,14 +384,19 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
*/
|
||||
private static class ResponseContainer extends ErrorsContainer {
|
||||
|
||||
private static final TypeRef<List<TestGraphQlError>> ERROR_LIST_TYPE = new TypeRef<List<TestGraphQlError>>() {};
|
||||
|
||||
private static final JsonPath ERRORS_PATH = JsonPath.compile("$.errors");
|
||||
|
||||
private final DocumentContext documentContext;
|
||||
|
||||
private final String jsonContent;
|
||||
|
||||
ResponseContainer(DocumentContext documentContext, Consumer<Runnable> assertDecorator) {
|
||||
super(readErrors(documentContext), assertDecorator);
|
||||
ResponseContainer(
|
||||
DocumentContext documentContext, @Nullable Predicate<GraphQLError> errorFilter,
|
||||
Consumer<Runnable> assertDecorator) {
|
||||
|
||||
super(readErrors(documentContext), errorFilter, assertDecorator);
|
||||
this.documentContext = documentContext;
|
||||
this.jsonContent = this.documentContext.jsonString();
|
||||
}
|
||||
@@ -381,8 +404,7 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
private static List<TestGraphQlError> readErrors(DocumentContext documentContext) {
|
||||
Assert.notNull(documentContext, "DocumentContext is required");
|
||||
try {
|
||||
return documentContext.read(ERRORS_PATH, new TypeRef<List<TestGraphQlError>>() {
|
||||
});
|
||||
return documentContext.read(ERRORS_PATH, ERROR_LIST_TYPE);
|
||||
}
|
||||
catch (PathNotFoundException ex) {
|
||||
return Collections.emptyList();
|
||||
@@ -419,11 +441,14 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
/**
|
||||
* Class constructor.
|
||||
* @param documentContext the parsed response content
|
||||
* @param errorFilter a globally defined filter for expected errors (to be ignored)
|
||||
* @param assertDecorator decorator to apply around assertions, e.g. to add extra
|
||||
* contextual information such as HTTP request and response body details
|
||||
*/
|
||||
protected DefaultResponseSpec(DocumentContext documentContext, Consumer<Runnable> assertDecorator) {
|
||||
this.responseContainer = new ResponseContainer(documentContext, assertDecorator);
|
||||
protected DefaultResponseSpec(
|
||||
DocumentContext documentContext, @Nullable Predicate<GraphQLError> errorFilter,
|
||||
Consumer<Runnable> assertDecorator) {
|
||||
|
||||
this.responseContainer = new ResponseContainer(documentContext, errorFilter, assertDecorator);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -755,14 +780,19 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
|
||||
private final Publisher<ExecutionResult> publisher;
|
||||
|
||||
@Nullable
|
||||
private final Predicate<GraphQLError> errorFilter;
|
||||
|
||||
private final Configuration jsonPathConfig;
|
||||
|
||||
private final Consumer<Runnable> assertDecorator;
|
||||
|
||||
protected <T> DefaultSubscriptionSpec(Publisher<ExecutionResult> publisher, Configuration jsonPathConfig,
|
||||
Consumer<Runnable> decorator) {
|
||||
protected <T> DefaultSubscriptionSpec(
|
||||
Publisher<ExecutionResult> publisher, @Nullable Predicate<GraphQLError> errorFilter,
|
||||
Configuration jsonPathConfig, Consumer<Runnable> decorator) {
|
||||
|
||||
this.publisher = publisher;
|
||||
this.errorFilter = errorFilter;
|
||||
this.jsonPathConfig = jsonPathConfig;
|
||||
this.assertDecorator = decorator;
|
||||
}
|
||||
@@ -771,7 +801,7 @@ class DefaultGraphQlTester implements GraphQlTester {
|
||||
public Flux<ResponseSpec> toFlux() {
|
||||
return Flux.from(this.publisher).map((result) -> {
|
||||
DocumentContext context = JsonPath.parse(result.toSpecification(), this.jsonPathConfig);
|
||||
return new DefaultResponseSpec(context, this.assertDecorator);
|
||||
return new DefaultResponseSpec(context, this.errorFilter, this.assertDecorator);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -20,12 +20,14 @@ import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Duration;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jayway.jsonpath.Configuration;
|
||||
import com.jayway.jsonpath.DocumentContext;
|
||||
import com.jayway.jsonpath.JsonPath;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.GraphQLError;
|
||||
|
||||
import org.springframework.graphql.RequestInput;
|
||||
import org.springframework.graphql.web.WebGraphQlHandler;
|
||||
@@ -69,34 +71,38 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
|
||||
private final Supplier<RequestStrategy> requestStrategySupplier;
|
||||
|
||||
private final BuilderDelegate delegate = new BuilderDelegate();
|
||||
private final GraphQlTesterBuilderConfig builderConfig = new GraphQlTesterBuilderConfig();
|
||||
|
||||
@Nullable
|
||||
private HttpHeaders headers;
|
||||
|
||||
DefaultBuilder(WebTestClient client) {
|
||||
this.requestStrategySupplier = () ->
|
||||
new WebTestClientRequestStrategy(
|
||||
client.mutate().responseTimeout(this.delegate.getResponseTimeout()).build(),
|
||||
this.delegate.initJsonPathConfig());
|
||||
this.requestStrategySupplier = () -> {
|
||||
Duration timeout = this.builderConfig.getResponseTimeout();
|
||||
WebTestClient clientToUse = client.mutate().responseTimeout(timeout).build();
|
||||
return new WebTestClientRequestStrategy(clientToUse, this.builderConfig);
|
||||
};
|
||||
}
|
||||
|
||||
DefaultBuilder(WebGraphQlHandler handler) {
|
||||
this.requestStrategySupplier = () ->
|
||||
new WebGraphQlHandlerRequestStrategy(handler,
|
||||
this.delegate.initJsonPathConfig(),
|
||||
this.delegate.getResponseTimeout());
|
||||
this.requestStrategySupplier = () -> new WebGraphQlHandlerRequestStrategy(handler, this.builderConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebGraphQlTester.Builder errorFilter(Predicate<GraphQLError> predicate) {
|
||||
this.builderConfig.errorFilter(predicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultBuilder jsonPathConfig(Configuration config) {
|
||||
this.delegate.jsonPathConfig(config);
|
||||
this.builderConfig.jsonPathConfig(config);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DefaultBuilder responseTimeout(Duration timeout) {
|
||||
this.delegate.responseTimeout(timeout);
|
||||
this.builderConfig.responseTimeout(timeout);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -131,11 +137,20 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
|
||||
private final WebTestClient client;
|
||||
|
||||
private final Configuration jsonPathConfig;
|
||||
private final GraphQlTesterBuilderConfig builderConfig;
|
||||
|
||||
WebTestClientRequestStrategy(WebTestClient client, Configuration jsonPathConfig) {
|
||||
WebTestClientRequestStrategy(WebTestClient client, GraphQlTesterBuilderConfig builderConfig) {
|
||||
this.client = client;
|
||||
this.jsonPathConfig = jsonPathConfig;
|
||||
this.builderConfig = builderConfig;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private Predicate<GraphQLError> errorFilter() {
|
||||
return this.builderConfig.getErrorFilter();
|
||||
}
|
||||
|
||||
private Configuration jsonPathConfig() {
|
||||
return this.builderConfig.getJsonPathConfig();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -155,9 +170,9 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
byte[] bytes = result.getResponseBodyContent();
|
||||
Assert.notNull(bytes, "Expected GraphQL response content");
|
||||
String content = new String(bytes, StandardCharsets.UTF_8);
|
||||
DocumentContext documentContext = JsonPath.parse(content, this.jsonPathConfig);
|
||||
DocumentContext documentContext = JsonPath.parse(content, jsonPathConfig());
|
||||
|
||||
return new DefaultResponseSpec(documentContext, result::assertWithDiagnostics);
|
||||
return new DefaultResponseSpec(documentContext, errorFilter(), result::assertWithDiagnostics);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -174,8 +189,9 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
.contentType(MediaType.TEXT_EVENT_STREAM)
|
||||
.returnResult(TestExecutionResult.class);
|
||||
|
||||
return new DefaultSubscriptionSpec(exchangeResult.getResponseBody().cast(ExecutionResult.class),
|
||||
this.jsonPathConfig, exchangeResult::assertWithDiagnostics);
|
||||
return new DefaultSubscriptionSpec(
|
||||
exchangeResult.getResponseBody().cast(ExecutionResult.class),
|
||||
errorFilter(), jsonPathConfig(), exchangeResult::assertWithDiagnostics);
|
||||
}
|
||||
|
||||
private HttpHeaders getHeaders(RequestInput requestInput) {
|
||||
@@ -193,15 +209,15 @@ class DefaultWebGraphQlTester extends DefaultGraphQlTester implements WebGraphQl
|
||||
|
||||
private final WebGraphQlHandler graphQlHandler;
|
||||
|
||||
WebGraphQlHandlerRequestStrategy(WebGraphQlHandler handler, Configuration config, Duration responseTimeout) {
|
||||
super(config, responseTimeout);
|
||||
WebGraphQlHandlerRequestStrategy(WebGraphQlHandler handler, GraphQlTesterBuilderConfig builderConfig) {
|
||||
super(builderConfig);
|
||||
this.graphQlHandler = handler;
|
||||
}
|
||||
|
||||
protected ExecutionResult executeInternal(RequestInput input) {
|
||||
Assert.isInstanceOf(WebInput.class, input);
|
||||
WebInput webInput = (WebInput) input;
|
||||
ExecutionResult result = this.graphQlHandler.handle(webInput).block(getResponseTimeout());
|
||||
ExecutionResult result = this.graphQlHandler.handle(webInput).block(responseTimeout());
|
||||
Assert.notNull(result, "Expected ExecutionResult");
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -78,6 +78,16 @@ public interface GraphQlTester {
|
||||
*/
|
||||
interface Builder<T extends Builder<T>> {
|
||||
|
||||
/**
|
||||
* Add a global filter for expected errors. All errors that match the
|
||||
* given predicate are treated as expected and ignored on
|
||||
* {@link GraphQlTester.ErrorSpec#verify()} or when
|
||||
* {@link TraverseSpec#path(String) traversing} to a data path.
|
||||
* @param predicate the error filter to add
|
||||
* @return the same builder instance
|
||||
*/
|
||||
T errorFilter(Predicate<GraphQLError> predicate);
|
||||
|
||||
/**
|
||||
* Provide JSONPath configuration settings, including a
|
||||
* {@link com.jayway.jsonpath.spi.json.JsonProvider} as well as a
|
||||
@@ -424,7 +434,7 @@ public interface GraphQlTester {
|
||||
* Add a filter for expected errors. All errors that match the predicate are
|
||||
* treated as expected and ignored on {@link #verify()} or when
|
||||
* {@link TraverseSpec#path(String) traversing} to a data path.
|
||||
* @param errorPredicate the predicate to add
|
||||
* @param errorPredicate the error filter to add
|
||||
* @return the same spec to add more filters before {@link #verify()}
|
||||
*/
|
||||
ErrorSpec filter(Predicate<GraphQLError> errorPredicate);
|
||||
|
||||
@@ -16,22 +16,25 @@
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import com.jayway.jsonpath.Configuration;
|
||||
import com.jayway.jsonpath.spi.json.JacksonJsonProvider;
|
||||
import com.jayway.jsonpath.spi.mapper.JacksonMappingProvider;
|
||||
import graphql.GraphQLError;
|
||||
|
||||
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.
|
||||
* Holds the input required for {@link GraphQlTester.Builder}, providing a
|
||||
* convenient way to pass it together, while also helping to avoid challenges
|
||||
* with builder hierarchy generics.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
final class BuilderDelegate {
|
||||
final class GraphQlTesterBuilderConfig {
|
||||
|
||||
private static final boolean jackson2Present;
|
||||
|
||||
@@ -42,11 +45,18 @@ final class BuilderDelegate {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
private Predicate<GraphQLError> errorFilter;
|
||||
|
||||
@Nullable
|
||||
private Configuration jsonPathConfig;
|
||||
|
||||
private Duration responseTimeout = Duration.ofSeconds(5);
|
||||
|
||||
public void errorFilter(Predicate<GraphQLError> predicate) {
|
||||
this.errorFilter = (this.errorFilter != null ? errorFilter.and(predicate) : predicate);
|
||||
}
|
||||
|
||||
public void jsonPathConfig(@Nullable Configuration config) {
|
||||
this.jsonPathConfig = config;
|
||||
}
|
||||
@@ -56,16 +66,17 @@ final class BuilderDelegate {
|
||||
this.responseTimeout = timeout;
|
||||
}
|
||||
|
||||
public Configuration initJsonPathConfig() {
|
||||
if (this.jsonPathConfig != null) {
|
||||
return this.jsonPathConfig;
|
||||
}
|
||||
else if (jackson2Present) {
|
||||
return Jackson2Configuration.create();
|
||||
}
|
||||
else {
|
||||
return Configuration.builder().build();
|
||||
@Nullable
|
||||
public Predicate<GraphQLError> getErrorFilter() {
|
||||
return this.errorFilter;
|
||||
}
|
||||
|
||||
public Configuration getJsonPathConfig() {
|
||||
if (this.jsonPathConfig == null) {
|
||||
this.jsonPathConfig = (jackson2Present ?
|
||||
Jackson2Configuration.create() : Configuration.builder().build());
|
||||
}
|
||||
return this.jsonPathConfig;
|
||||
}
|
||||
|
||||
public Duration getResponseTimeout() {
|
||||
@@ -121,7 +121,7 @@ class TestGraphQlError implements GraphQLError {
|
||||
* Mark this error as expected if it matches the predicate.
|
||||
* @param predicate the error predicate
|
||||
*/
|
||||
void filter(Predicate<GraphQLError> predicate) {
|
||||
void applyErrorFilterPredicate(Predicate<GraphQLError> predicate) {
|
||||
this.expected |= predicate.test(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -60,10 +60,10 @@ public class GraphQlTesterTests {
|
||||
|
||||
private final GraphQlService service = mock(GraphQlService.class);
|
||||
|
||||
private final ArgumentCaptor<ExecutionInput> inputCaptor = ArgumentCaptor.forClass(ExecutionInput.class);
|
||||
|
||||
private final GraphQlTester graphQlTester = GraphQlTester.create(this.service);
|
||||
|
||||
private final ArgumentCaptor<ExecutionInput> inputCaptor = ArgumentCaptor.forClass(ExecutionInput.class);
|
||||
|
||||
|
||||
@Test
|
||||
void pathAndValueExistsAndEmptyChecks() throws Exception {
|
||||
@@ -77,7 +77,7 @@ public class GraphQlTesterTests {
|
||||
spec.path("me.friends").valueIsEmpty();
|
||||
spec.path("hero").pathDoesNotExist().valueDoesNotExist().valueIsEmpty();
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -97,7 +97,7 @@ public class GraphQlTesterTests {
|
||||
.as("Extended fields should fail in strict mode")
|
||||
.hasMessageContaining("Unexpected: name");
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -127,7 +127,7 @@ public class GraphQlTesterTests {
|
||||
.entity(new ParameterizedTypeReference<Map<String, MovieCharacter>>() {})
|
||||
.isEqualTo(Collections.singletonMap("me", luke));
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -163,7 +163,7 @@ public class GraphQlTesterTests {
|
||||
.entityList(new ParameterizedTypeReference<MovieCharacter>() {})
|
||||
.containsExactly(han, leia);
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -202,7 +202,7 @@ public class GraphQlTesterTests {
|
||||
assertThatThrownBy(() -> this.graphQlTester.query(query).executeAndVerify())
|
||||
.hasMessageContaining("Response has 1 unexpected error(s).");
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -214,7 +214,7 @@ public class GraphQlTesterTests {
|
||||
assertThatThrownBy(() -> this.graphQlTester.query(query).execute().path("me"))
|
||||
.hasMessageContaining("Response has 1 unexpected error(s).");
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -233,7 +233,7 @@ public class GraphQlTesterTests {
|
||||
.verify())
|
||||
.hasMessageContaining("Response has 1 unexpected error(s) of 2 total.");
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -252,7 +252,28 @@ public class GraphQlTesterTests {
|
||||
.path("me")
|
||||
.pathDoesNotExist();
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsFilteredGlobally() throws Exception {
|
||||
|
||||
String query = "{me {name, friends}}";
|
||||
setResponse(
|
||||
GraphqlErrorBuilder.newError().message("some error").build(),
|
||||
GraphqlErrorBuilder.newError().message("some other error").build());
|
||||
|
||||
GraphQlTester.builder(this.service)
|
||||
.errorFilter((error) -> error.getMessage().startsWith("some "))
|
||||
.build()
|
||||
.query(query)
|
||||
.execute()
|
||||
.errors()
|
||||
.verify()
|
||||
.path("me")
|
||||
.pathDoesNotExist();
|
||||
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -277,7 +298,7 @@ public class GraphQlTesterTests {
|
||||
.path("me")
|
||||
.pathDoesNotExist();
|
||||
|
||||
assertThat(getActualQuery()).contains(query);
|
||||
assertThat(this.inputCaptor.getValue().getQuery()).contains(query);
|
||||
}
|
||||
|
||||
private void setResponse(String data) throws Exception {
|
||||
@@ -300,8 +321,4 @@ public class GraphQlTesterTests {
|
||||
given(this.service.execute(this.inputCaptor.capture())).willReturn(Mono.just(result));
|
||||
}
|
||||
|
||||
private String getActualQuery() {
|
||||
return this.inputCaptor.getValue().getQuery();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -29,9 +29,11 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.GraphqlErrorBuilder;
|
||||
import okhttp3.mockwebserver.MockResponse;
|
||||
import okhttp3.mockwebserver.MockWebServer;
|
||||
import okhttp3.mockwebserver.RecordedRequest;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.MethodSource;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
@@ -60,8 +62,9 @@ import static org.mockito.Mockito.mock;
|
||||
* </ul>
|
||||
*
|
||||
* <p>
|
||||
* There is no actual handling via {@link graphql.GraphQL} in either scenario. The main
|
||||
* focus is to verify {@link GraphQlTester} request preparation and response handling.
|
||||
* There is no actual handling via {@link graphql.GraphQL} in either scenario.
|
||||
* The main focus is to verify {@link GraphQlTester} request preparation and
|
||||
* response handling.
|
||||
*/
|
||||
public class WebGraphQlTesterTests {
|
||||
|
||||
@@ -121,6 +124,28 @@ public class WebGraphQlTesterTests {
|
||||
setup.shutdown();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@MethodSource("argumentSource")
|
||||
void errorsFilteredGlobally(GraphQlTesterSetup setup) throws Exception {
|
||||
|
||||
String query = "{me {name, friends}}";
|
||||
setup.response(
|
||||
GraphqlErrorBuilder.newError().message("some error").build(),
|
||||
GraphqlErrorBuilder.newError().message("some other error").build());
|
||||
|
||||
setup.graphQlTesterBuilder()
|
||||
.errorFilter((error) -> error.getMessage().startsWith("some "))
|
||||
.build()
|
||||
.query(query)
|
||||
.execute()
|
||||
.errors()
|
||||
.verify()
|
||||
.path("me")
|
||||
.pathDoesNotExist();
|
||||
|
||||
setup.verifyRequest((input) -> assertThat(input.getQuery()).contains(query));
|
||||
}
|
||||
|
||||
|
||||
private interface GraphQlTesterSetup {
|
||||
|
||||
@@ -243,8 +268,7 @@ public class WebGraphQlTesterTests {
|
||||
public void response(@Nullable String data, List<GraphQLError> errors) throws Exception {
|
||||
ExecutionResultImpl.Builder builder = new ExecutionResultImpl.Builder();
|
||||
if (data != null) {
|
||||
builder.data(OBJECT_MAPPER.readValue(data, new TypeReference<Map<String, Object>>() {
|
||||
}));
|
||||
builder.data(OBJECT_MAPPER.readValue(data, new TypeReference<Map<String, Object>>() {}));
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(errors)) {
|
||||
builder.addErrors(errors);
|
||||
|
||||
Reference in New Issue
Block a user