JSON config in ExecutionGraphQlServiceTester builder

See gh-345
This commit is contained in:
rstoyanchev
2022-04-12 15:15:07 +01:00
parent 85dc2e5145
commit 218b16e022
4 changed files with 113 additions and 2 deletions

View File

@@ -17,9 +17,13 @@
package org.springframework.graphql.test.tester;
import java.util.Collections;
import java.util.function.Consumer;
import org.springframework.core.codec.Decoder;
import org.springframework.core.codec.Encoder;
import org.springframework.graphql.ExecutionGraphQlService;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
@@ -36,6 +40,12 @@ final class DefaultExecutionGraphQlServiceTesterBuilder
private final ExecutionGraphQlService service;
@Nullable
private Encoder<?> encoder;
@Nullable
private Decoder<?> decoder;
DefaultExecutionGraphQlServiceTesterBuilder(ExecutionGraphQlService service) {
Assert.notNull(service, "GraphQlService is required");
@@ -46,14 +56,36 @@ final class DefaultExecutionGraphQlServiceTesterBuilder
this.service = transport.getGraphQlService();
}
@Override
public DefaultExecutionGraphQlServiceTesterBuilder encoder(Encoder<?> encoder) {
this.encoder = encoder;
return this;
}
@Override
public DefaultExecutionGraphQlServiceTesterBuilder decoder(Decoder<?> decoder) {
this.decoder = decoder;
return this;
}
@Override
public ExecutionGraphQlServiceTester build() {
registerJsonPathMappingProvider();
GraphQlServiceGraphQlTransport transport = new GraphQlServiceGraphQlTransport(this.service);
GraphQlTester tester = super.buildGraphQlTester(transport);
return new DefaultExecutionGraphQlServiceTester(tester, transport, getBuilderInitializer());
}
private void registerJsonPathMappingProvider() {
if (this.encoder != null && this.decoder != null) {
configureJsonPathConfig(config -> {
EncoderDecoderMappingProvider provider = new EncoderDecoderMappingProvider(
Collections.singletonList(this.encoder), Collections.singletonList(this.decoder));
return config.mappingProvider(provider);
});
}
}
/**
* Default {@link ExecutionGraphQlServiceTester} implementation.

View File

@@ -16,6 +16,8 @@
package org.springframework.graphql.test.tester;
import org.springframework.core.codec.Decoder;
import org.springframework.core.codec.Encoder;
import org.springframework.graphql.ExecutionGraphQlService;
/**
@@ -52,6 +54,18 @@ public interface ExecutionGraphQlServiceTester extends GraphQlTester {
*/
interface Builder<B extends Builder<B>> extends GraphQlTester.Builder<B> {
/**
* Configure the JSON encoder to use for mapping response data to
* higher level objects.
*/
B encoder(Encoder<?> encoder);
/**
* Configure the JSON decoder to use for mapping response data to
* higher level objects.
*/
B decoder(Decoder<?> decoder);
/**
* Build a {@link ExecutionGraphQlServiceTester} instance.
*/

View File

@@ -16,12 +16,23 @@
package org.springframework.graphql.test.tester;
import java.util.Collections;
import java.util.Map;
import graphql.ExecutionResultImpl;
import graphql.GraphqlErrorBuilder;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import org.springframework.core.ResolvableType;
import org.springframework.core.codec.DecodingException;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.graphql.ExecutionGraphQlService;
import org.springframework.graphql.support.DocumentSource;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
import org.springframework.lang.Nullable;
import org.springframework.util.MimeType;
import static org.assertj.core.api.Assertions.assertThat;
@@ -65,6 +76,34 @@ public class GraphQlTesterBuilderTests extends GraphQlTesterTestSupport {
assertThat(getActualRequestDocument()).isEqualTo(DOCUMENT);
}
@Test
void codecConfigurerRegistersJsonPathMappingProvider() {
TestJackson2JsonDecoder testDecoder = new TestJackson2JsonDecoder();
ExecutionGraphQlServiceTester.Builder<?> builder = graphQlTesterBuilder()
.encoder(new Jackson2JsonEncoder())
.decoder(testDecoder);
String document = "{me {name}}";
MovieCharacter character = MovieCharacter.create("Luke Skywalker");
getGraphQlService().setResponse(document,
ExecutionResultImpl.newExecutionResult()
.data(Collections.singletonMap("me", character))
.build());
GraphQlTester client = builder.build();
GraphQlTester.Response response = client.document(document).execute();
testDecoder.resetLastValue();
assertThat(testDecoder.getLastValue()).isNull();
assertThat(response).isNotNull();
response.path("me").entity(MovieCharacter.class).isEqualTo(character);
response.path("me").matchesJson("{name:\"Luke Skywalker\"}");
assertThat(testDecoder.getLastValue()).isEqualTo(character);
}
@Test
void errorsFilteredGlobally() {
@@ -86,4 +125,29 @@ public class GraphQlTesterBuilderTests extends GraphQlTesterTestSupport {
assertThat(getActualRequestDocument()).contains(document);
}
private static class TestJackson2JsonDecoder extends Jackson2JsonDecoder {
@Nullable
private Object lastValue;
@Nullable
Object getLastValue() {
return this.lastValue;
}
@Override
public Object decode(DataBuffer dataBuffer, ResolvableType targetType,
@Nullable MimeType mimeType, @Nullable Map<String, Object> hints) throws DecodingException {
this.lastValue = super.decode(dataBuffer, targetType, mimeType, hints);
return this.lastValue;
}
void resetLastValue() {
this.lastValue = null;
}
}
}

View File

@@ -28,7 +28,8 @@ public class GraphQlTesterTestSupport {
private final MockExecutionGraphQlService graphQlService = new MockExecutionGraphQlService();
private final GraphQlTester.Builder<?> graphQlTesterBuilder = ExecutionGraphQlServiceTester.builder(this.graphQlService);
private final ExecutionGraphQlServiceTester.Builder<?> graphQlTesterBuilder =
ExecutionGraphQlServiceTester.builder(this.graphQlService);
private final GraphQlTester graphQlTester = this.graphQlTesterBuilder.build();
@@ -45,7 +46,7 @@ public class GraphQlTesterTestSupport {
return this.graphQlTester;
}
public GraphQlTester.Builder<?> graphQlTesterBuilder() {
public ExecutionGraphQlServiceTester.Builder<?> graphQlTesterBuilder() {
return this.graphQlTesterBuilder;
}