Add MockExecutionGraphQlService in testFixtures
This commit is contained in:
@@ -41,20 +41,20 @@ public class GraphQlTesterBuilderTests extends GraphQlTesterTestSupport {
|
||||
DocumentSource documentSource = name -> name.equals("name") ?
|
||||
Mono.just(DOCUMENT) : Mono.error(new IllegalArgumentException());
|
||||
|
||||
setMockResponse("{}");
|
||||
getGraphQlService().setDataAsJson(DOCUMENT, "{}");
|
||||
|
||||
// Original
|
||||
GraphQlTester.Builder<?> builder = graphQlTesterBuilder().documentSource(documentSource);
|
||||
GraphQlTester tester = builder.build();
|
||||
tester.documentName("name").execute();
|
||||
|
||||
assertThat(request().getDocument()).isEqualTo(DOCUMENT);
|
||||
assertThat(getActualRequestDocument()).isEqualTo(DOCUMENT);
|
||||
|
||||
// Mutate
|
||||
tester = tester.mutate().build();
|
||||
tester.documentName("name").execute();
|
||||
|
||||
assertThat(request().getDocument()).isEqualTo(DOCUMENT);
|
||||
assertThat(getActualRequestDocument()).isEqualTo(DOCUMENT);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -62,7 +62,8 @@ public class GraphQlTesterBuilderTests extends GraphQlTesterTestSupport {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
|
||||
setMockResponse(
|
||||
getGraphQlService().setErrors(
|
||||
document,
|
||||
GraphqlErrorBuilder.newError().message("some error").build(),
|
||||
GraphqlErrorBuilder.newError().message("some other error").build());
|
||||
|
||||
@@ -74,7 +75,7 @@ public class GraphQlTesterBuilderTests extends GraphQlTesterTestSupport {
|
||||
.errors().verify()
|
||||
.path("me").pathDoesNotExist();
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,25 +16,8 @@
|
||||
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import org.springframework.graphql.execution.MockExecutionGraphQlService;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import graphql.GraphQLError;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlRequest;
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlResponse;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Base class for {@link GraphQlTester} tests.
|
||||
@@ -43,18 +26,21 @@ import static org.mockito.Mockito.mock;
|
||||
*/
|
||||
public class GraphQlTesterTestSupport {
|
||||
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
|
||||
private final ArgumentCaptor<ExecutionGraphQlRequest> requestCaptor = ArgumentCaptor.forClass(ExecutionGraphQlRequest.class);
|
||||
|
||||
private final ExecutionGraphQlService graphQlService = mock(ExecutionGraphQlService.class);
|
||||
private final MockExecutionGraphQlService graphQlService = new MockExecutionGraphQlService();
|
||||
|
||||
private final GraphQlTester.Builder<?> graphQlTesterBuilder = ExecutionGraphQlServiceTester.builder(this.graphQlService);
|
||||
|
||||
private final GraphQlTester graphQlTester = this.graphQlTesterBuilder.build();
|
||||
|
||||
|
||||
public MockExecutionGraphQlService getGraphQlService() {
|
||||
return this.graphQlService;
|
||||
}
|
||||
|
||||
protected String getActualRequestDocument() {
|
||||
return this.graphQlService.getGraphQlRequest().getDocument();
|
||||
}
|
||||
|
||||
protected GraphQlTester graphQlTester() {
|
||||
return this.graphQlTester;
|
||||
}
|
||||
@@ -63,37 +49,4 @@ public class GraphQlTesterTestSupport {
|
||||
return this.graphQlTesterBuilder;
|
||||
}
|
||||
|
||||
protected ExecutionGraphQlRequest request() {
|
||||
return this.requestCaptor.getValue();
|
||||
}
|
||||
|
||||
|
||||
protected void setMockResponse(String data) {
|
||||
setMockResponse(builder -> serialize(data, builder));
|
||||
}
|
||||
|
||||
protected void setMockResponse(GraphQLError... errors) {
|
||||
setMockResponse(builder -> builder.errors(Arrays.asList(errors)));
|
||||
}
|
||||
|
||||
private void setMockResponse(Consumer<ExecutionResultImpl.Builder> consumer) {
|
||||
|
||||
ExecutionResultImpl.Builder builder = new ExecutionResultImpl.Builder();
|
||||
consumer.accept(builder);
|
||||
ExecutionInput executionInput = ExecutionInput.newExecutionInput("{}").build();
|
||||
ExecutionResult result = builder.build();
|
||||
|
||||
given(this.graphQlService.execute(this.requestCaptor.capture()))
|
||||
.willReturn(Mono.just(new DefaultExecutionGraphQlResponse(executionInput, result)));
|
||||
}
|
||||
|
||||
private void serialize(String data, ExecutionResultImpl.Builder builder) {
|
||||
try {
|
||||
builder.data(OBJECT_MAPPER.readValue(data, Map.class));
|
||||
}
|
||||
catch (JsonProcessingException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
void hasValue() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
|
||||
GraphQlTester.Response response = graphQlTester().document(document).execute();
|
||||
response.path("me.name").hasValue();
|
||||
@@ -52,14 +52,14 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
assertThatThrownBy(() -> response.path("hero").hasValue())
|
||||
.hasMessageContaining("No value at JSON path \"$['data']['hero']");
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueIsNull() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse("{\"me\": {\"name\":null, \"friends\":null}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":null, \"friends\":null}}");
|
||||
|
||||
GraphQlTester.Response response = graphQlTester().document(document).execute();
|
||||
|
||||
@@ -69,14 +69,14 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
assertThatThrownBy(() -> response.path("me").valueIsNull())
|
||||
.hasMessageContaining("Expected null value at JSON path");
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueIsEmptyList() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
|
||||
GraphQlTester.Response response = graphQlTester().document(document).execute();
|
||||
response.path("me.friends").hasValue().entityList(MovieCharacter.class).hasSize(0);
|
||||
@@ -85,7 +85,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
@Test
|
||||
void pathDoesNotExist() {
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
|
||||
GraphQlTester.Response response = graphQlTester().document(document).execute();
|
||||
|
||||
@@ -99,7 +99,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
void matchesJson() {
|
||||
|
||||
String document = "{me {name}}";
|
||||
setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
|
||||
GraphQlTester.Response response = graphQlTester().document(document).execute();
|
||||
|
||||
@@ -111,14 +111,14 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
.as("Extended fields should fail in strict mode")
|
||||
.hasMessageContaining("Unexpected: name");
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void entity() {
|
||||
|
||||
String document = "{me {name}}";
|
||||
setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\"}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\"}}");
|
||||
|
||||
GraphQlTester.Response response = graphQlTester().document(document).execute();
|
||||
|
||||
@@ -141,14 +141,15 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
.entity(new ParameterizedTypeReference<Map<String, MovieCharacter>>() {})
|
||||
.isEqualTo(Collections.singletonMap("me", luke));
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void entityList() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse("{" +
|
||||
getGraphQlService().setDataAsJson(document,
|
||||
"{" +
|
||||
" \"me\":{" +
|
||||
" \"name\":\"Luke Skywalker\","
|
||||
+ " \"friends\":[{\"name\":\"Han Solo\"}, {\"name\":\"Leia Organa\"}]" +
|
||||
@@ -183,7 +184,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
.entityList(new ParameterizedTypeReference<MovieCharacter>() {})
|
||||
.containsExactly(han, leia);
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -195,7 +196,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
+ " }" +
|
||||
"}";
|
||||
|
||||
setMockResponse("{\"hero\": {\"name\":\"R2-D2\"}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"hero\": {\"name\":\"R2-D2\"}}");
|
||||
|
||||
GraphQlTester.Response response = graphQlTester().document(document)
|
||||
.operationName("HeroNameAndFriends")
|
||||
@@ -206,7 +207,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
|
||||
response.path("hero").entity(MovieCharacter.class).isEqualTo(MovieCharacter.create("R2-D2"));
|
||||
|
||||
ExecutionGraphQlRequest request = request();
|
||||
ExecutionGraphQlRequest request = getGraphQlService().getGraphQlRequest();
|
||||
assertThat(request.getDocument()).contains(document);
|
||||
assertThat(request.getOperationName()).isEqualTo("HeroNameAndFriends");
|
||||
assertThat(request.getVariables()).hasSize(3);
|
||||
@@ -219,42 +220,43 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
void errorsEmptyOnExecuteAndVerify() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse("{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\", \"friends\":[]}}");
|
||||
|
||||
graphQlTester().document(document).executeAndVerify();
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsCheckedOnExecuteAndVerify() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse(GraphqlErrorBuilder.newError().message("Invalid query").build());
|
||||
getGraphQlService().setError(document, builder -> builder.message("Invalid query"));
|
||||
|
||||
assertThatThrownBy(() -> graphQlTester().document(document).executeAndVerify())
|
||||
.hasMessageContaining("Response has 1 unexpected error(s)");
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsCheckedOnTraverse() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse(GraphqlErrorBuilder.newError().message("Invalid query").build());
|
||||
getGraphQlService().setError(document, builder -> builder.message("Invalid query"));
|
||||
|
||||
assertThatThrownBy(() -> graphQlTester().document(document).execute().path("me"))
|
||||
.hasMessageContaining("Response has 1 unexpected error(s)");
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsPartiallyFiltered() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse(
|
||||
getGraphQlService().setErrors(
|
||||
document,
|
||||
GraphqlErrorBuilder.newError().message("some error").build(),
|
||||
GraphqlErrorBuilder.newError().message("some other error").build());
|
||||
|
||||
@@ -266,14 +268,15 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
.verify())
|
||||
.hasMessageContaining("Response has 1 unexpected error(s) of 2 total.");
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsFiltered() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse(
|
||||
getGraphQlService().setErrors(
|
||||
document,
|
||||
GraphqlErrorBuilder.newError().message("some error").build(),
|
||||
GraphqlErrorBuilder.newError().message("some other error").build());
|
||||
|
||||
@@ -285,14 +288,15 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
.path("me")
|
||||
.pathDoesNotExist();
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsExpected() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse(
|
||||
getGraphQlService().setErrors(
|
||||
document,
|
||||
GraphqlErrorBuilder.newError().message("some error").build(),
|
||||
GraphqlErrorBuilder.newError().message("some other error").build());
|
||||
|
||||
@@ -303,14 +307,15 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
.verify()
|
||||
.path("me").pathDoesNotExist();
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
@Test
|
||||
void errorsExpectedButNotFound() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse(
|
||||
getGraphQlService().setErrors(
|
||||
document,
|
||||
GraphqlErrorBuilder.newError().message("some error").build(),
|
||||
GraphqlErrorBuilder.newError().message("some other error").build());
|
||||
|
||||
@@ -325,10 +330,8 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
void errorsConsumed() {
|
||||
|
||||
String document = "{me {name, friends}}";
|
||||
setMockResponse(GraphqlErrorBuilder.newError()
|
||||
.message("Invalid query")
|
||||
.location(new SourceLocation(1, 2))
|
||||
.build());
|
||||
getGraphQlService().setError(document, builder ->
|
||||
builder.message("Invalid query").location(new SourceLocation(1, 2)).build());
|
||||
|
||||
graphQlTester().document(document)
|
||||
.execute()
|
||||
@@ -342,7 +345,7 @@ public class GraphQlTesterTests extends GraphQlTesterTestSupport {
|
||||
})
|
||||
.path("me").pathDoesNotExist();
|
||||
|
||||
assertThat(request().getDocument()).contains(document);
|
||||
assertThat(getActualRequestDocument()).contains(document);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -17,11 +17,8 @@
|
||||
package org.springframework.graphql.test.tester;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import io.rsocket.Closeable;
|
||||
import io.rsocket.SocketAcceptor;
|
||||
@@ -36,11 +33,9 @@ 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.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
import org.springframework.graphql.GraphQlRequest;
|
||||
import org.springframework.graphql.execution.MockExecutionGraphQlService;
|
||||
import org.springframework.graphql.server.GraphQlRSocketHandler;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlResponse;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -48,7 +43,6 @@ import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.messaging.rsocket.RSocketStrategies;
|
||||
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -106,7 +100,7 @@ public class RSocketGraphQlTesterBuilderTests {
|
||||
|
||||
String document = "{me {name}}";
|
||||
MovieCharacter character = MovieCharacter.create("Luke Skywalker");
|
||||
this.builderSetup.setMockResponse(document,
|
||||
this.builderSetup.getGraphQlService().setResponse(document,
|
||||
ExecutionResultImpl.newExecutionResult()
|
||||
.data(Collections.singletonMap("me", character))
|
||||
.build());
|
||||
@@ -126,34 +120,19 @@ public class RSocketGraphQlTesterBuilderTests {
|
||||
|
||||
private static class BuilderSetup {
|
||||
|
||||
private GraphQlRequest graphQlRequest;
|
||||
|
||||
private final Map<String, ExecutionGraphQlResponse> responses = new HashMap<>();
|
||||
private final MockExecutionGraphQlService graphQlService = new MockExecutionGraphQlService();
|
||||
|
||||
@Nullable
|
||||
private Closeable server;
|
||||
|
||||
public BuilderSetup() {
|
||||
|
||||
ExecutionGraphQlResponse defaultResponse = new DefaultExecutionGraphQlResponse(
|
||||
ExecutionInput.newExecutionInput().query(DOCUMENT).build(),
|
||||
ExecutionResultImpl.newExecutionResult().build());
|
||||
|
||||
this.responses.put(DOCUMENT, defaultResponse);
|
||||
this.graphQlService.setDefaultDataAsJson("{}");
|
||||
}
|
||||
|
||||
public RSocketGraphQlTester.Builder<?> initBuilder() {
|
||||
|
||||
ExecutionGraphQlService graphQlService = request -> {
|
||||
this.graphQlRequest = request;
|
||||
String document = request.getDocument();
|
||||
ExecutionGraphQlResponse response = this.responses.get(document);
|
||||
Assert.notNull(response, "Unexpected request: " + document);
|
||||
return Mono.just(response);
|
||||
};
|
||||
|
||||
GraphQlRSocketController controller = new GraphQlRSocketController(
|
||||
new GraphQlRSocketHandler(graphQlService, Collections.emptyList(), new Jackson2JsonEncoder()));
|
||||
new GraphQlRSocketHandler(this.graphQlService, Collections.emptyList(), new Jackson2JsonEncoder()));
|
||||
|
||||
this.server = RSocketServer.create()
|
||||
.acceptor(createSocketAcceptor(controller))
|
||||
@@ -178,14 +157,12 @@ public class RSocketGraphQlTesterBuilderTests {
|
||||
return handler.responder();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void setMockResponse(String document, ExecutionResult result) {
|
||||
ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(document).build();
|
||||
this.responses.put(document, new DefaultExecutionGraphQlResponse(executionInput, result));
|
||||
public MockExecutionGraphQlService getGraphQlService() {
|
||||
return this.graphQlService;
|
||||
}
|
||||
|
||||
public GraphQlRequest getGraphQlRequest() {
|
||||
return this.graphQlRequest;
|
||||
return this.graphQlService.getGraphQlRequest();
|
||||
}
|
||||
|
||||
public void shutDown() {
|
||||
|
||||
@@ -19,11 +19,9 @@ package org.springframework.graphql.test.tester;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -34,21 +32,19 @@ 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.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.support.DocumentSource;
|
||||
import org.springframework.graphql.server.WebGraphQlRequest;
|
||||
import org.springframework.graphql.server.TestWebSocketClient;
|
||||
import org.springframework.graphql.server.TestWebSocketConnection;
|
||||
import org.springframework.graphql.client.TestWebSocketClient;
|
||||
import org.springframework.graphql.client.TestWebSocketConnection;
|
||||
import org.springframework.graphql.execution.MockExecutionGraphQlService;
|
||||
import org.springframework.graphql.server.WebGraphQlHandler;
|
||||
import org.springframework.graphql.server.WebGraphQlInterceptor;
|
||||
import org.springframework.graphql.server.WebGraphQlRequest;
|
||||
import org.springframework.graphql.server.webflux.GraphQlHttpHandler;
|
||||
import org.springframework.graphql.server.webflux.GraphQlWebSocketHandler;
|
||||
import org.springframework.graphql.support.DocumentSource;
|
||||
import org.springframework.http.codec.ClientCodecConfigurer;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.web.reactive.function.server.RouterFunction;
|
||||
import org.springframework.web.reactive.function.server.ServerResponse;
|
||||
@@ -211,15 +207,10 @@ public class WebGraphQlTesterBuilderTests {
|
||||
|
||||
private WebGraphQlRequest request;
|
||||
|
||||
private final Map<String, ExecutionGraphQlResponse> responses = new HashMap<>();
|
||||
private final MockExecutionGraphQlService graphQlService = new MockExecutionGraphQlService();
|
||||
|
||||
public WebBuilderSetup() {
|
||||
|
||||
ExecutionGraphQlResponse defaultResponse = new DefaultExecutionGraphQlResponse(
|
||||
ExecutionInput.newExecutionInput().query(DOCUMENT).build(),
|
||||
ExecutionResultImpl.newExecutionResult().build());
|
||||
|
||||
this.responses.put(DOCUMENT, defaultResponse);
|
||||
this.graphQlService.setDefaultDataAsJson("{}");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -228,12 +219,7 @@ public class WebGraphQlTesterBuilderTests {
|
||||
}
|
||||
|
||||
protected WebGraphQlHandler webGraphQlHandler() {
|
||||
return WebGraphQlHandler.builder(request -> {
|
||||
String document = request.getDocument();
|
||||
ExecutionGraphQlResponse response = this.responses.get(document);
|
||||
Assert.notNull(response, "Unexpected request: " + document);
|
||||
return Mono.just(response);
|
||||
})
|
||||
return WebGraphQlHandler.builder(this.graphQlService)
|
||||
.interceptor((input, chain) -> {
|
||||
this.request = input;
|
||||
return chain.next(request);
|
||||
@@ -243,8 +229,7 @@ public class WebGraphQlTesterBuilderTests {
|
||||
|
||||
@Override
|
||||
public void setMockResponse(String document, ExecutionResult result) {
|
||||
ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(document).build();
|
||||
this.responses.put(document, new DefaultExecutionGraphQlResponse(executionInput, result));
|
||||
this.graphQlService.setResponse(document, result);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -64,6 +64,7 @@ dependencies {
|
||||
testRuntimeOnly 'org.apache.logging.log4j:log4j-slf4j-impl'
|
||||
|
||||
testFixturesApi 'org.springframework:spring-webflux'
|
||||
testFixturesApi 'com.fasterxml.jackson.core:jackson-databind'
|
||||
}
|
||||
|
||||
test {
|
||||
|
||||
@@ -44,7 +44,7 @@ public class GraphQlClientBuilderTests extends GraphQlClientTestSupport {
|
||||
DocumentSource documentSource = name -> name.equals("name") ?
|
||||
Mono.just(DOCUMENT) : Mono.error(new IllegalArgumentException());
|
||||
|
||||
initDataResponse(DOCUMENT, "{}");
|
||||
getGraphQlService().setDataAsJson(DOCUMENT, "{}");
|
||||
|
||||
// Original
|
||||
GraphQlClient.Builder<?> builder = graphQlClientBuilder().documentSource(documentSource);
|
||||
@@ -76,7 +76,7 @@ public class GraphQlClientBuilderTests extends GraphQlClientTestSupport {
|
||||
GraphQlClientInterceptor changingInterceptor =
|
||||
initInterceptor(request -> request.getAttributes().computeIfPresent(name, (k, v) -> v + "2"));
|
||||
|
||||
initDataResponse(DOCUMENT, "{}");
|
||||
getGraphQlService().setDataAsJson(DOCUMENT, "{}");
|
||||
|
||||
// Original
|
||||
GraphQlClient.Builder<?> builder = graphQlClientBuilder().interceptor(savingInterceptor);
|
||||
|
||||
@@ -17,25 +17,9 @@
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import graphql.GraphQLError;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.support.DefaultGraphQlRequest;
|
||||
import org.springframework.graphql.GraphQlRequest;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import org.springframework.graphql.execution.MockExecutionGraphQlService;
|
||||
|
||||
/**
|
||||
* Base class for {@link GraphQlClient} tests.
|
||||
@@ -46,67 +30,27 @@ public class GraphQlClientTestSupport {
|
||||
|
||||
protected static final Duration TIMEOUT = Duration.ofSeconds(5);
|
||||
|
||||
private final MockExecutionGraphQlService graphQlService = new MockExecutionGraphQlService();
|
||||
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
private final GraphQlClient.Builder<?> clientBuilder = GraphQlClient.builder(this.graphQlService.asGraphQlTransport());
|
||||
|
||||
|
||||
private final ArgumentCaptor<GraphQlRequest> requestCaptor = ArgumentCaptor.forClass(DefaultGraphQlRequest.class);
|
||||
|
||||
private final GraphQlTransport transport = mock(GraphQlTransport.class);
|
||||
|
||||
private final GraphQlClient.Builder<?> graphQlClientBuilder = GraphQlClient.builder(this.transport);
|
||||
|
||||
private final GraphQlClient graphQlClient = this.graphQlClientBuilder.build();
|
||||
private final GraphQlClient client = this.clientBuilder.build();
|
||||
|
||||
|
||||
protected GraphQlClient graphQlClient() {
|
||||
return this.graphQlClient;
|
||||
return this.client;
|
||||
}
|
||||
|
||||
public GraphQlClient.Builder<?> graphQlClientBuilder() {
|
||||
return this.graphQlClientBuilder;
|
||||
return this.clientBuilder;
|
||||
}
|
||||
|
||||
public MockExecutionGraphQlService getGraphQlService() {
|
||||
return this.graphQlService;
|
||||
}
|
||||
|
||||
protected GraphQlRequest request() {
|
||||
return this.requestCaptor.getValue();
|
||||
}
|
||||
|
||||
|
||||
protected void initDataResponse(String document, String responseData) {
|
||||
initResponse(new DefaultGraphQlRequest(document), responseData);
|
||||
}
|
||||
|
||||
protected void initErrorResponse(String document, GraphQLError... errors) {
|
||||
initResponse(new DefaultGraphQlRequest(document), null, errors);
|
||||
}
|
||||
|
||||
protected void initResponse(String document, String responseData, GraphQLError... errors) {
|
||||
initResponse(new DefaultGraphQlRequest(document), responseData, errors);
|
||||
}
|
||||
|
||||
protected void initResponse(GraphQlRequest request, @Nullable String responseData, GraphQLError... errors) {
|
||||
ExecutionResultImpl.Builder builder = new ExecutionResultImpl.Builder();
|
||||
if (responseData != null) {
|
||||
builder.data(decode(responseData));
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(errors)) {
|
||||
builder.errors(Arrays.asList(errors));
|
||||
}
|
||||
ExecutionResult executionResult = builder.build();
|
||||
Map<String, Object> responseMap = executionResult.toSpecification();
|
||||
|
||||
when(this.transport.execute(eq(request)))
|
||||
.thenReturn(Mono.just(new ResponseMapGraphQlResponse(responseMap)));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <T> T decode(String data) {
|
||||
try {
|
||||
return (T) OBJECT_MAPPER.readValue(data, Map.class);
|
||||
}
|
||||
catch (JsonProcessingException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
return this.graphQlService.getGraphQlRequest();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ import graphql.validation.ValidationErrorType;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.core.ParameterizedTypeReference;
|
||||
import org.springframework.graphql.support.DefaultGraphQlRequest;
|
||||
import org.springframework.graphql.GraphQlRequest;
|
||||
import org.springframework.graphql.support.DefaultGraphQlRequest;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
@@ -48,7 +48,7 @@ public class GraphQlClientTests extends GraphQlClientTestSupport {
|
||||
void retrieveEntity() {
|
||||
|
||||
String document = "mockRequest1";
|
||||
initDataResponse(document, "{\"me\": {\"name\":\"Luke Skywalker\"}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\"}}");
|
||||
|
||||
MovieCharacter movieCharacter = graphQlClient().document(document)
|
||||
.retrieve("me").toEntity(MovieCharacter.class)
|
||||
@@ -61,7 +61,7 @@ public class GraphQlClientTests extends GraphQlClientTestSupport {
|
||||
void retrieveEntityList() {
|
||||
|
||||
String document = "mockRequest1";
|
||||
initDataResponse(document, "{" +
|
||||
getGraphQlService().setDataAsJson(document, "{" +
|
||||
" \"me\":{" +
|
||||
" \"name\":\"Luke Skywalker\","
|
||||
+ " \"friends\":[{\"name\":\"Han Solo\"}, {\"name\":\"Leia Organa\"}]" +
|
||||
@@ -81,7 +81,7 @@ public class GraphQlClientTests extends GraphQlClientTestSupport {
|
||||
void retrieveAndDecodeDataMap() {
|
||||
|
||||
String document = "mockRequest1";
|
||||
initDataResponse(document, "{\"me\": {\"name\":\"Luke Skywalker\"}}");
|
||||
getGraphQlService().setDataAsJson(document, "{\"me\": {\"name\":\"Luke Skywalker\"}}");
|
||||
|
||||
Map<String, MovieCharacter> map = graphQlClient().document(document)
|
||||
.retrieve("").toEntity(new ParameterizedTypeReference<Map<String, MovieCharacter>>() {})
|
||||
@@ -102,7 +102,7 @@ public class GraphQlClientTests extends GraphQlClientTestSupport {
|
||||
vars.put("keyOnly", null);
|
||||
|
||||
GraphQlRequest request = new DefaultGraphQlRequest("mockRequest1", "HeroNameAndFriends", vars);
|
||||
initResponse(request, "{\"hero\": {\"name\":\"R2-D2\"}}");
|
||||
getGraphQlService().setDataAsJson(request.getDocument(), "{\"hero\": {\"name\":\"R2-D2\"}}");
|
||||
|
||||
MovieCharacter character = graphQlClient().document(document)
|
||||
.operationName(operationName)
|
||||
@@ -119,12 +119,13 @@ public class GraphQlClientTests extends GraphQlClientTestSupport {
|
||||
void retrieveInvalidResponse() {
|
||||
|
||||
String document = "errorsOnlyResponse";
|
||||
initErrorResponse(document, new ValidationError(ValidationErrorType.InvalidSyntax));
|
||||
getGraphQlService().setErrors(document, new ValidationError(ValidationErrorType.InvalidSyntax));
|
||||
testRetrieveFieldAccessException(document, "me");
|
||||
|
||||
document = "nullDataResponse";
|
||||
GraphQLObjectType type = GraphQLObjectType.newObject().name("n").build();
|
||||
initResponse(document, "null", new NonNullableValueCoercedAsNullException("f", new ArrayList<>(), type));
|
||||
GraphQLError error = new NonNullableValueCoercedAsNullException("f", new ArrayList<>(), type);
|
||||
getGraphQlService().setDataAsJsonAndErrors(document, "null", error);
|
||||
testRetrieveFieldAccessException(document, "me");
|
||||
}
|
||||
|
||||
@@ -132,7 +133,7 @@ public class GraphQlClientTests extends GraphQlClientTestSupport {
|
||||
void retrievePartialResponse() {
|
||||
|
||||
String document = "fieldErrorResponse";
|
||||
initResponse(document, "{\"me\": {\"name\":null}}", errorForPath("/me/name"));
|
||||
getGraphQlService().setDataAsJsonAndErrors(document, "{\"me\": {\"name\":null}}", errorForPath("/me/name"));
|
||||
|
||||
MovieCharacter character = graphQlClient().document(document).retrieve("me").toEntity(MovieCharacter.class).block();
|
||||
assertThat(character).isNotNull().extracting(MovieCharacter::getName).isNull();
|
||||
@@ -152,12 +153,13 @@ public class GraphQlClientTests extends GraphQlClientTestSupport {
|
||||
void executeInvalidResponse() {
|
||||
|
||||
String document = "errorsOnlyResponse";
|
||||
initErrorResponse(document, new ValidationError(ValidationErrorType.InvalidSyntax));
|
||||
getGraphQlService().setErrors(document, new ValidationError(ValidationErrorType.InvalidSyntax));
|
||||
testExecuteFailedResponse(document);
|
||||
|
||||
document = "nullDataResponse";
|
||||
GraphQLObjectType type = GraphQLObjectType.newObject().name("n").build();
|
||||
initResponse(document, "null", new NonNullableValueCoercedAsNullException("f", new ArrayList<>(), type));
|
||||
GraphQLError error = new NonNullableValueCoercedAsNullException("f", new ArrayList<>(), type);
|
||||
getGraphQlService().setDataAsJsonAndErrors(document, "null", error);
|
||||
testExecuteFailedResponse(document);
|
||||
}
|
||||
|
||||
@@ -178,7 +180,7 @@ public class GraphQlClientTests extends GraphQlClientTestSupport {
|
||||
void executePartialResponse() {
|
||||
|
||||
String document = "fieldErrorResponse";
|
||||
initResponse(document, "{\"me\": {\"name\":null}}", errorForPath("/me/name"));
|
||||
getGraphQlService().setDataAsJsonAndErrors(document, "{\"me\": {\"name\":null}}", errorForPath("/me/name"));
|
||||
testRetrieveFieldAccessException(document, "me.name");
|
||||
|
||||
ClientGraphQlResponse response =
|
||||
|
||||
@@ -18,12 +18,8 @@ package org.springframework.graphql.client;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import io.rsocket.Closeable;
|
||||
import io.rsocket.SocketAcceptor;
|
||||
import io.rsocket.core.RSocketServer;
|
||||
@@ -34,11 +30,9 @@ import org.junit.jupiter.api.Test;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
import org.springframework.graphql.GraphQlRequest;
|
||||
import org.springframework.graphql.execution.MockExecutionGraphQlService;
|
||||
import org.springframework.graphql.server.GraphQlRSocketHandler;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlResponse;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.codec.json.Jackson2JsonEncoder;
|
||||
import org.springframework.lang.Nullable;
|
||||
@@ -46,7 +40,6 @@ import org.springframework.messaging.handler.annotation.MessageMapping;
|
||||
import org.springframework.messaging.rsocket.RSocketStrategies;
|
||||
import org.springframework.messaging.rsocket.annotation.support.RSocketMessageHandler;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -81,48 +74,41 @@ public class RSocketGraphQlClientBuilderTests {
|
||||
RSocketGraphQlClient client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
|
||||
GraphQlRequest request = this.builderSetup.getGraphQlRequest();
|
||||
GraphQlRequest request = this.builderSetup.getActualRequest();
|
||||
assertThat(request).isNotNull();
|
||||
|
||||
// Mutate: still works (carries over original default)
|
||||
client = client.mutate().build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
|
||||
request = this.builderSetup.getGraphQlRequest();
|
||||
request = this.builderSetup.getActualRequest();
|
||||
assertThat(request).isNotNull();
|
||||
}
|
||||
|
||||
|
||||
private static class BuilderSetup {
|
||||
|
||||
private GraphQlRequest graphQlRequest;
|
||||
|
||||
private final Map<String, ExecutionGraphQlResponse> responses = new HashMap<>();
|
||||
private final MockExecutionGraphQlService graphQlService = new MockExecutionGraphQlService();
|
||||
|
||||
@Nullable
|
||||
private Closeable server;
|
||||
|
||||
public BuilderSetup() {
|
||||
this.graphQlService.setDefaultDataAsJson("{}");
|
||||
}
|
||||
|
||||
ExecutionGraphQlResponse defaultResponse = new DefaultExecutionGraphQlResponse(
|
||||
ExecutionInput.newExecutionInput().query(DOCUMENT).build(),
|
||||
ExecutionResultImpl.newExecutionResult().build());
|
||||
public MockExecutionGraphQlService getGraphQlService() {
|
||||
return this.graphQlService;
|
||||
}
|
||||
|
||||
this.responses.put(DOCUMENT, defaultResponse);
|
||||
public GraphQlRequest getActualRequest() {
|
||||
return this.graphQlService.getGraphQlRequest();
|
||||
}
|
||||
|
||||
public RSocketGraphQlClient.Builder<?> initBuilder() {
|
||||
|
||||
ExecutionGraphQlService graphQlService = request -> {
|
||||
this.graphQlRequest = request;
|
||||
String document = request.getDocument();
|
||||
ExecutionGraphQlResponse response = this.responses.get(document);
|
||||
Assert.notNull(response, "Unexpected request: " + document);
|
||||
return Mono.just(response);
|
||||
};
|
||||
|
||||
GraphQlRSocketController controller = new GraphQlRSocketController(
|
||||
new GraphQlRSocketHandler(graphQlService, Collections.emptyList(), new Jackson2JsonEncoder()));
|
||||
new GraphQlRSocketHandler(this.graphQlService, Collections.emptyList(), new Jackson2JsonEncoder()));
|
||||
|
||||
this.server = RSocketServer.create()
|
||||
.acceptor(createSocketAcceptor(controller))
|
||||
@@ -147,16 +133,6 @@ public class RSocketGraphQlClientBuilderTests {
|
||||
return handler.responder();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void setMockResponse(String document, ExecutionResult result) {
|
||||
ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(document).build();
|
||||
this.responses.put(document, new DefaultExecutionGraphQlResponse(executionInput, result));
|
||||
}
|
||||
|
||||
public GraphQlRequest getGraphQlRequest() {
|
||||
return this.graphQlRequest;
|
||||
}
|
||||
|
||||
public void shutDown() {
|
||||
if (this.server != null) {
|
||||
this.server.dispose();
|
||||
|
||||
@@ -19,12 +19,9 @@ package org.springframework.graphql.client;
|
||||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
@@ -34,22 +31,18 @@ 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.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.support.DocumentSource;
|
||||
import org.springframework.graphql.server.WebGraphQlRequest;
|
||||
import org.springframework.graphql.server.TestWebSocketClient;
|
||||
import org.springframework.graphql.server.TestWebSocketConnection;
|
||||
import org.springframework.graphql.execution.MockExecutionGraphQlService;
|
||||
import org.springframework.graphql.server.WebGraphQlHandler;
|
||||
import org.springframework.graphql.server.WebGraphQlInterceptor;
|
||||
import org.springframework.graphql.server.WebGraphQlRequest;
|
||||
import org.springframework.graphql.server.webflux.GraphQlHttpHandler;
|
||||
import org.springframework.graphql.server.webflux.GraphQlWebSocketHandler;
|
||||
import org.springframework.graphql.support.DocumentSource;
|
||||
import org.springframework.http.codec.ClientCodecConfigurer;
|
||||
import org.springframework.http.codec.json.Jackson2JsonDecoder;
|
||||
import org.springframework.http.server.reactive.HttpHandler;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.test.web.reactive.server.HttpHandlerConnector;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.MimeType;
|
||||
import org.springframework.web.reactive.function.client.WebClient;
|
||||
import org.springframework.web.reactive.function.server.HandlerStrategies;
|
||||
@@ -99,7 +92,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
WebGraphQlClient client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
|
||||
WebGraphQlRequest request = builderSetup.getWebGraphQlRequest();
|
||||
WebGraphQlRequest request = builderSetup.getActualRequest();
|
||||
assertThat(request.getUri().toString()).isEqualTo(url);
|
||||
assertThat(request.getHeaders().get("h")).containsExactly("one");
|
||||
|
||||
@@ -107,14 +100,14 @@ public class WebGraphQlClientBuilderTests {
|
||||
builder = client.mutate().headers(headers -> headers.add("h", "two"));
|
||||
client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
assertThat(builderSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one", "two");
|
||||
assertThat(builderSetup.getActualRequest().getHeaders().get("h")).containsExactly("one", "two");
|
||||
|
||||
// Mutate to replace header
|
||||
builder = client.mutate().header("h", "three", "four");
|
||||
client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
|
||||
request = builderSetup.getWebGraphQlRequest();
|
||||
request = builderSetup.getActualRequest();
|
||||
assertThat(request.getUri().toString()).isEqualTo(url);
|
||||
assertThat(request.getHeaders().get("h")).containsExactly("three", "four");
|
||||
}
|
||||
@@ -129,7 +122,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
HttpGraphQlClient client = builder.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
assertThat(clientSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one");
|
||||
assertThat(clientSetup.getActualRequest().getHeaders().get("h")).containsExactly("one");
|
||||
|
||||
// Mutate to add header value
|
||||
HttpGraphQlClient.Builder<?> builder2 = client.mutate()
|
||||
@@ -137,7 +130,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
client = builder2.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
assertThat(clientSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("one", "two");
|
||||
assertThat(clientSetup.getActualRequest().getHeaders().get("h")).containsExactly("one", "two");
|
||||
|
||||
// Mutate to replace header
|
||||
HttpGraphQlClient.Builder<?> builder3 = client.mutate()
|
||||
@@ -145,7 +138,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
client = builder3.build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
assertThat(clientSetup.getWebGraphQlRequest().getHeaders().get("h")).containsExactly("three");
|
||||
assertThat(clientSetup.getActualRequest().getHeaders().get("h")).containsExactly("three");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -160,14 +153,14 @@ public class WebGraphQlClientBuilderTests {
|
||||
WebGraphQlClient client = builder.build();
|
||||
client.documentName("name").execute().block(TIMEOUT);
|
||||
|
||||
WebGraphQlRequest request = builderSetup.getWebGraphQlRequest();
|
||||
WebGraphQlRequest request = builderSetup.getActualRequest();
|
||||
assertThat(request.getDocument()).isEqualTo(DOCUMENT);
|
||||
|
||||
// Mutate
|
||||
client = client.mutate().build();
|
||||
client.documentName("name").execute().block(TIMEOUT);
|
||||
|
||||
request = builderSetup.getWebGraphQlRequest();
|
||||
request = builderSetup.getActualRequest();
|
||||
assertThat(request.getDocument()).isEqualTo(DOCUMENT);
|
||||
}
|
||||
|
||||
@@ -178,7 +171,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
WebGraphQlClient client = builderSetup.initBuilder().url("/graphql one").build();
|
||||
client.document(DOCUMENT).execute().block(TIMEOUT);
|
||||
|
||||
assertThat(builderSetup.getWebGraphQlRequest().getUri().toString()).isEqualTo("/graphql%20one");
|
||||
assertThat(builderSetup.getActualRequest().getUri().toString()).isEqualTo("/graphql%20one");
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@@ -192,7 +185,7 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
String document = "{me {name}}";
|
||||
MovieCharacter character = MovieCharacter.create("Luke Skywalker");
|
||||
builderSetup.setMockResponse(document,
|
||||
builderSetup.getGraphQlService().setResponse(document,
|
||||
ExecutionResultImpl.newExecutionResult()
|
||||
.data(Collections.singletonMap("me", character))
|
||||
.build());
|
||||
@@ -211,12 +204,12 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
private interface ClientBuilderSetup {
|
||||
|
||||
MockExecutionGraphQlService getGraphQlService();
|
||||
|
||||
WebGraphQlRequest getActualRequest();
|
||||
|
||||
WebGraphQlClient.Builder<?> initBuilder();
|
||||
|
||||
void setMockResponse(String document, ExecutionResult result);
|
||||
|
||||
WebGraphQlRequest getWebGraphQlRequest();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -224,24 +217,24 @@ public class WebGraphQlClientBuilderTests {
|
||||
|
||||
private WebGraphQlRequest graphQlRequest;
|
||||
|
||||
private final Map<String, ExecutionGraphQlResponse> responses = new HashMap<>();
|
||||
private final MockExecutionGraphQlService graphQlService = new MockExecutionGraphQlService();
|
||||
|
||||
public AbstractBuilderSetup() {
|
||||
this.graphQlService.setDefaultDataAsJson("{}");
|
||||
}
|
||||
|
||||
ExecutionGraphQlResponse defaultResponse = new DefaultExecutionGraphQlResponse(
|
||||
ExecutionInput.newExecutionInput().query(DOCUMENT).build(),
|
||||
ExecutionResultImpl.newExecutionResult().build());
|
||||
@Override
|
||||
public MockExecutionGraphQlService getGraphQlService() {
|
||||
return this.graphQlService;
|
||||
}
|
||||
|
||||
this.responses.put(DOCUMENT, defaultResponse);
|
||||
@Override
|
||||
public WebGraphQlRequest getActualRequest() {
|
||||
return this.graphQlRequest;
|
||||
}
|
||||
|
||||
protected WebGraphQlHandler webGraphQlHandler() {
|
||||
return WebGraphQlHandler.builder(request -> {
|
||||
String document = request.getDocument();
|
||||
ExecutionGraphQlResponse response = this.responses.get(document);
|
||||
Assert.notNull(response, "Unexpected request: " + document);
|
||||
return Mono.just(response);
|
||||
})
|
||||
return WebGraphQlHandler.builder(this.graphQlService)
|
||||
.interceptor((request, chain) -> {
|
||||
this.graphQlRequest = request;
|
||||
return chain.next(graphQlRequest);
|
||||
@@ -249,17 +242,6 @@ public class WebGraphQlClientBuilderTests {
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMockResponse(String document, ExecutionResult result) {
|
||||
ExecutionInput executionInput = ExecutionInput.newExecutionInput().query(document).build();
|
||||
this.responses.put(document, new DefaultExecutionGraphQlResponse(executionInput, result));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebGraphQlRequest getWebGraphQlRequest() {
|
||||
return this.graphQlRequest;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -35,8 +35,6 @@ import org.springframework.graphql.GraphQlRequest;
|
||||
import org.springframework.graphql.GraphQlResponse;
|
||||
import org.springframework.graphql.ResponseError;
|
||||
import org.springframework.graphql.support.DefaultGraphQlRequest;
|
||||
import org.springframework.graphql.server.TestWebSocketClient;
|
||||
import org.springframework.graphql.server.TestWebSocketConnection;
|
||||
import org.springframework.graphql.server.support.GraphQlWebSocketMessage;
|
||||
import org.springframework.graphql.server.support.GraphQlWebSocketMessageType;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.server;
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.graphql.server;
|
||||
package org.springframework.graphql.client;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2002-2022 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.execution;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import graphql.ExecutionInput;
|
||||
import graphql.ExecutionResult;
|
||||
import graphql.ExecutionResultImpl;
|
||||
import graphql.GraphQLError;
|
||||
import graphql.GraphqlErrorBuilder;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.graphql.ExecutionGraphQlRequest;
|
||||
import org.springframework.graphql.ExecutionGraphQlResponse;
|
||||
import org.springframework.graphql.ExecutionGraphQlService;
|
||||
import org.springframework.graphql.GraphQlRequest;
|
||||
import org.springframework.graphql.GraphQlResponse;
|
||||
import org.springframework.graphql.client.GraphQlTransport;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlRequest;
|
||||
import org.springframework.graphql.support.DefaultExecutionGraphQlResponse;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class MockExecutionGraphQlService implements ExecutionGraphQlService {
|
||||
|
||||
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
||||
|
||||
|
||||
private ExecutionGraphQlRequest graphQlRequest;
|
||||
|
||||
private final Map<String, ExecutionGraphQlResponse> responses = new HashMap<>();
|
||||
|
||||
@Nullable
|
||||
private ExecutionGraphQlResponse defaultResponse;
|
||||
|
||||
|
||||
public void setDefaultDataAsJson(String dataJson) {
|
||||
ExecutionInput input = ExecutionInput.newExecutionInput().query("").build();
|
||||
ExecutionResult result = ExecutionResultImpl.newExecutionResult().data(decode(dataJson)).build();
|
||||
this.defaultResponse = new DefaultExecutionGraphQlResponse(input, result);
|
||||
}
|
||||
|
||||
public void setDataAsJson(String document, String dataJson) {
|
||||
setResponse(document, decode(dataJson));
|
||||
}
|
||||
|
||||
public void setErrors(String document, GraphQLError... errors) {
|
||||
setResponse(document, null, errors);
|
||||
}
|
||||
|
||||
public void setError(String document, Consumer<GraphqlErrorBuilder<?>> errorBuilderConsumer) {
|
||||
GraphqlErrorBuilder<?> errorBuilder = GraphqlErrorBuilder.newError();
|
||||
errorBuilderConsumer.accept(errorBuilder);
|
||||
setResponse(document, null, errorBuilder.build());
|
||||
}
|
||||
|
||||
public void setDataAsJsonAndErrors(String document, String dataJson, GraphQLError... errors) {
|
||||
setResponse(document, decode(dataJson), errors);
|
||||
}
|
||||
|
||||
private void setResponse(String document, @Nullable Map<String, Object> data, GraphQLError... errors) {
|
||||
ExecutionResultImpl.Builder builder = new ExecutionResultImpl.Builder();
|
||||
if (data != null) {
|
||||
builder.data(data);
|
||||
}
|
||||
if (!ObjectUtils.isEmpty(errors)) {
|
||||
builder.errors(Arrays.asList(errors));
|
||||
}
|
||||
setResponse(document, builder.build());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public void setResponse(String document, ExecutionResult result) {
|
||||
ExecutionInput input = ExecutionInput.newExecutionInput().query(document).build();
|
||||
this.responses.put(document, new DefaultExecutionGraphQlResponse(input, result));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String, Object> decode(String json) {
|
||||
try {
|
||||
return OBJECT_MAPPER.readValue(json, Map.class);
|
||||
}
|
||||
catch (JsonProcessingException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ExecutionGraphQlRequest getGraphQlRequest() {
|
||||
return this.graphQlRequest;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Mono<ExecutionGraphQlResponse> execute(ExecutionGraphQlRequest request) {
|
||||
this.graphQlRequest = request;
|
||||
String document = request.getDocument();
|
||||
ExecutionGraphQlResponse response = this.responses.getOrDefault(document, this.defaultResponse);
|
||||
Assert.notNull(response, "Unexpected request: " + document);
|
||||
return Mono.just(response);
|
||||
}
|
||||
|
||||
public GraphQlTransport asGraphQlTransport() {
|
||||
return new GraphQlTransport() {
|
||||
|
||||
@Override
|
||||
public Mono<GraphQlResponse> execute(GraphQlRequest request) {
|
||||
ExecutionGraphQlRequest executionRequest = toExecutionRequest(request);
|
||||
return MockExecutionGraphQlService.this.execute(executionRequest).cast(GraphQlResponse.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Flux<GraphQlResponse> executeSubscription(GraphQlRequest request) {
|
||||
return Flux.error(new UnsupportedOperationException());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private ExecutionGraphQlRequest toExecutionRequest(GraphQlRequest request) {
|
||||
return new DefaultExecutionGraphQlRequest(
|
||||
request.getDocument(), request.getOperationName(), request.getVariables(), "1", null);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user