From bf9c5849194401bcb60e97fbaa8e69dac01fe06f Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 19 Apr 2024 16:18:48 +0100 Subject: [PATCH 1/2] Minor refactoring in HTTP handler tests Change WebFlux handler to actually decode from JSON rather than take an already decoded SerializableGraphQlRequest. See gh-948 --- .../webflux/GraphQlHttpHandlerTests.java | 91 ++++++++++--------- .../webmvc/GraphQlHttpHandlerTests.java | 88 +++++++++--------- 2 files changed, 96 insertions(+), 83 deletions(-) diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java index 30d8cbf8..a21c68e9 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java @@ -23,22 +23,24 @@ import java.util.Locale; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import org.junit.jupiter.api.Test; -import reactor.core.publisher.Mono; +import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; +import reactor.test.StepVerifier; -import org.springframework.graphql.GraphQlRequest; import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.server.support.SerializableGraphQlRequest; import org.springframework.http.MediaType; +import org.springframework.http.codec.DecoderHttpMessageReader; import org.springframework.http.codec.EncoderHttpMessageWriter; +import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.HttpMessageWriter; +import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.http.codec.json.Jackson2JsonEncoder; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.mock.http.server.reactive.MockServerHttpResponse; -import org.springframework.mock.web.reactive.function.server.MockServerRequest; import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.result.view.ViewResolver; -import org.springframework.web.server.ServerWebExchange; import static org.assertj.core.api.Assertions.assertThat; @@ -48,95 +50,100 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class GraphQlHttpHandlerTests { - private final GraphQlHttpHandler greetingHandler = GraphQlSetup.schemaContent("type Query { greeting: String }") - .queryFetcher("greeting", (env) -> "Hello").toHttpHandlerWebFlux(); + private static final List> MESSAGE_READERS = + List.of(new DecoderHttpMessageReader<>(new Jackson2JsonDecoder())); + + private final GraphQlHttpHandler greetingHandler = + GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", (env) -> "Hello") + .toHttpHandlerWebFlux(); @Test - void shouldProduceApplicationJsonByDefault() { - MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/") - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.ALL).build(); - + void shouldProduceApplicationJsonByDefault() throws Exception { String document = "{greeting}"; - MockServerHttpResponse httpResponse = handleRequest( - httpRequest, this.greetingHandler, initRequest(document)); + MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/") + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.ALL) + .body(initRequestBody(document)); - assertThat(httpResponse.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON); + MockServerHttpResponse response = handleRequest(httpRequest, this.greetingHandler); + + assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON); + StepVerifier.create(response.getBodyAsString()) + .expectNext("{\"data\":{\"greeting\":\"Hello\"}}") + .verifyComplete(); } @Test - void shouldProduceApplicationGraphQl() { + void shouldProduceApplicationGraphQl() throws Exception { MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/") - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_GRAPHQL_RESPONSE).build(); + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_GRAPHQL_RESPONSE) + .body(initRequestBody("{greeting}")); - MockServerHttpResponse httpResponse = handleRequest( - httpRequest, this.greetingHandler, initRequest("{greeting}")); + MockServerHttpResponse httpResponse = handleRequest(httpRequest, this.greetingHandler); assertThat(httpResponse.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_GRAPHQL_RESPONSE); } @Test - void shouldProduceApplicationJson() { + void shouldProduceApplicationJson() throws Exception { MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/") - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).build(); + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_JSON) + .body(initRequestBody("{greeting}")); - MockServerHttpResponse httpResponse = handleRequest( - httpRequest, this.greetingHandler, initRequest("{greeting}")); + MockServerHttpResponse httpResponse = handleRequest(httpRequest, this.greetingHandler); assertThat(httpResponse.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON); } @Test - void locale() { + void locale() throws Exception { GraphQlHttpHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }") .queryFetcher("greeting", (env) -> "Hello in " + env.getLocale()) .toHttpHandlerWebFlux(); MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/") - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_GRAPHQL_RESPONSE) - .acceptLanguageAsLocales(Locale.FRENCH).build(); + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_GRAPHQL_RESPONSE) + .acceptLanguageAsLocales(Locale.FRENCH) + .body(initRequestBody("{greeting}")); - MockServerHttpResponse httpResponse = handleRequest( - httpRequest, handler, initRequest("{greeting}")); + MockServerHttpResponse httpResponse = handleRequest(httpRequest, handler); assertThat(httpResponse.getBodyAsString().block()) .isEqualTo("{\"data\":{\"greeting\":\"Hello in fr\"}}"); } @Test - void shouldSetExecutionId() { + void shouldSetExecutionId() throws Exception { GraphQlHttpHandler handler = GraphQlSetup.schemaContent("type Query { showId: String }") .queryFetcher("showId", (env) -> env.getExecutionId().toString()) .toHttpHandlerWebFlux(); MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/") - .contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_GRAPHQL_RESPONSE).build(); + .contentType(MediaType.APPLICATION_JSON) + .accept(MediaType.APPLICATION_GRAPHQL_RESPONSE) + .body(initRequestBody("{showId}")); - MockServerHttpResponse httpResponse = handleRequest( - httpRequest, handler, initRequest("{showId}")); + MockServerHttpResponse httpResponse = handleRequest(httpRequest, handler); DocumentContext document = JsonPath.parse(httpResponse.getBodyAsString().block()); String id = document.read("data.showId", String.class); assertThat(id).isEqualTo(httpRequest.getId()); } - private static SerializableGraphQlRequest initRequest(String document) { + private static String initRequestBody(String document) throws Exception { SerializableGraphQlRequest request = new SerializableGraphQlRequest(); request.setQuery(document); - return request; + return new ObjectMapper().writeValueAsString(request); } - private MockServerHttpResponse handleRequest( - MockServerHttpRequest httpRequest, GraphQlHttpHandler handler, GraphQlRequest body) { - + private MockServerHttpResponse handleRequest(MockServerHttpRequest httpRequest, GraphQlHttpHandler handler) { MockServerWebExchange exchange = MockServerWebExchange.from(httpRequest); - - MockServerRequest serverRequest = MockServerRequest.builder() - .exchange(exchange) - .uri(((ServerWebExchange) exchange).getRequest().getURI()) - .method(((ServerWebExchange) exchange).getRequest().getMethod()) - .headers(((ServerWebExchange) exchange).getRequest().getHeaders()) - .body(Mono.just(body)); + ServerRequest serverRequest = ServerRequest.create(exchange, MESSAGE_READERS); handler.handleRequest(serverRequest) .flatMap(response -> response.writeTo(exchange, new DefaultContext())) diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java index da8d7cf7..90d7f547 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java @@ -21,6 +21,7 @@ import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Map; import java.util.UUID; import com.jayway.jsonpath.DocumentContext; @@ -29,9 +30,11 @@ import graphql.execution.preparsed.persisted.ApolloPersistedQuerySupport; import graphql.execution.preparsed.persisted.InMemoryPersistedQueryCache; import jakarta.servlet.ServletException; import org.junit.jupiter.api.Test; +import org.testcontainers.shaded.com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.graphql.GraphQlSetup; +import org.springframework.graphql.server.support.SerializableGraphQlRequest; import org.springframework.http.MediaType; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; @@ -57,23 +60,24 @@ public class GraphQlHttpHandlerTests { private final GraphQlHttpHandler greetingHandler = GraphQlSetup.schemaContent("type Query { greeting: String }") .queryFetcher("greeting", (env) -> "Hello").toHttpHandler(); + @Test void shouldProduceApplicationJsonByDefault() throws Exception { - MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ greeting }\"}", "*/*"); - MockHttpServletResponse servletResponse = handleRequest(servletRequest, this.greetingHandler); - assertThat(servletResponse.getContentType()).isEqualTo(MediaType.APPLICATION_JSON_VALUE); + MockHttpServletRequest request = createServletRequest("{ greeting }", "*/*"); + MockHttpServletResponse response = handleRequest(request, this.greetingHandler); + assertThat(response.getContentType()).isEqualTo(MediaType.APPLICATION_JSON_VALUE); } @Test void shouldProduceApplicationGraphQl() throws Exception { - MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ greeting }\"}", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE); - MockHttpServletResponse servletResponse = handleRequest(servletRequest, this.greetingHandler); - assertThat(servletResponse.getContentType()).isEqualTo(MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE); + MockHttpServletRequest request = createServletRequest("{ greeting }", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE); + MockHttpServletResponse response = handleRequest(request, this.greetingHandler); + assertThat(response.getContentType()).isEqualTo(MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE); } @Test void shouldProduceApplicationJson() throws Exception { - MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ greeting }\"}", "application/json"); + MockHttpServletRequest servletRequest = createServletRequest("{ greeting }", "application/json"); MockHttpServletResponse servletResponse = handleRequest(servletRequest, this.greetingHandler); assertThat(servletResponse.getContentType()).isEqualTo("application/json"); } @@ -83,14 +87,15 @@ public class GraphQlHttpHandlerTests { GraphQlHttpHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }") .queryFetcher("greeting", (env) -> "Hello in " + env.getLocale()) .toHttpHandler(); - MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ greeting }\"}", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE); + + MockHttpServletRequest request = createServletRequest( + "{ greeting }", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE); + LocaleContextHolder.setLocale(Locale.FRENCH); try { - MockHttpServletResponse servletResponse = handleRequest(servletRequest, handler); - - assertThat(servletResponse.getContentAsString()) - .isEqualTo("{\"data\":{\"greeting\":\"Hello in fr\"}}"); + MockHttpServletResponse response = handleRequest(request, handler); + assertThat(response.getContentAsString()).isEqualTo("{\"data\":{\"greeting\":\"Hello in fr\"}}"); } finally { LocaleContextHolder.resetLocaleContext(); @@ -103,10 +108,12 @@ public class GraphQlHttpHandlerTests { .queryFetcher("showId", (env) -> env.getExecutionId().toString()) .toHttpHandler(); - MockHttpServletRequest servletRequest = createServletRequest("{\"query\":\"{ showId }\"}", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE); + MockHttpServletRequest request = createServletRequest( + "{ showId }", MediaType.APPLICATION_GRAPHQL_RESPONSE_VALUE); - MockHttpServletResponse servletResponse = handleRequest(servletRequest, handler); - DocumentContext document = JsonPath.parse(servletResponse.getContentAsString()); + MockHttpServletResponse response = handleRequest(request, handler); + + DocumentContext document = JsonPath.parse(response.getContentAsString()); String id = document.read("data.showId", String.class); assertThatNoException().isThrownBy(() -> UUID.fromString(id)); } @@ -121,44 +128,44 @@ public class GraphQlHttpHandlerTests { .configureGraphQl(builder -> builder.preparsedDocumentProvider(documentProvider)) .toHttpHandler(); - String document = """ - { - "query" : "{__typename}", - "extensions": { - "persistedQuery": { - "version":1, - "sha256Hash":"ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38" - } - } - }"""; + SerializableGraphQlRequest request = new SerializableGraphQlRequest(); + request.setQuery("{__typename}"); + request.setExtensions(Map.of("persistedQuery", Map.of( + "version", "1", + "sha256Hash", "ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"))); - MockHttpServletResponse servletResponse = handleRequest(createServletRequest(document, "*/*"), handler); - assertThat(servletResponse.getContentAsString()).isEqualTo("{\"data\":{\"__typename\":\"Query\"}}"); + MockHttpServletResponse response = handleRequest(createServletRequest(request, "*/*"), handler); + assertThat(response.getContentAsString()).isEqualTo("{\"data\":{\"__typename\":\"Query\"}}"); - document = """ - { - "extensions":{ - "persistedQuery":{ - "version":1, - "sha256Hash":"ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38" - } - } - }"""; + request = new SerializableGraphQlRequest(); + request.setQuery("{__typename}"); + request.setExtensions(Map.of("persistedQuery", Map.of( + "version", "1", + "sha256Hash", "ecf4edb46db40b5132295c0291d62fb65d6759a9eedfa4d5d612dd5ec54a6b38"))); - servletResponse = handleRequest(createServletRequest(document, "*/*"), handler); - assertThat(servletResponse.getContentAsString()).isEqualTo("{\"data\":{\"__typename\":\"Query\"}}"); + response = handleRequest(createServletRequest(request, "*/*"), handler); + assertThat(response.getContentAsString()).isEqualTo("{\"data\":{\"__typename\":\"Query\"}}"); } + private MockHttpServletRequest createServletRequest(String document, String accept) throws Exception { + SerializableGraphQlRequest request = new SerializableGraphQlRequest(); + request.setQuery(document); + return createServletRequest(request, accept); + } - private MockHttpServletRequest createServletRequest(String query, String accept) { + private MockHttpServletRequest createServletRequest(SerializableGraphQlRequest request, String accept) throws Exception { MockHttpServletRequest servletRequest = new MockHttpServletRequest("POST", "/"); servletRequest.setContentType(MediaType.APPLICATION_JSON_VALUE); - servletRequest.setContent(query.getBytes(StandardCharsets.UTF_8)); + servletRequest.setContent(initRequestBody(request)); servletRequest.addHeader("Accept", accept); servletRequest.setAsyncSupported(true); return servletRequest; } + private static byte[] initRequestBody(SerializableGraphQlRequest request) throws Exception { + return new ObjectMapper().writeValueAsString(request).getBytes(StandardCharsets.UTF_8); + } + private MockHttpServletResponse handleRequest( MockHttpServletRequest servletRequest, GraphQlHttpHandler handler) throws ServletException, IOException { @@ -180,7 +187,6 @@ public class GraphQlHttpHandlerTests { public List> messageConverters() { return MESSAGE_READERS; } - } } From 7dd9cf54ca8e7b47b2718488ee2542a569ba0478 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 19 Apr 2024 16:45:21 +0100 Subject: [PATCH 2/2] Support application/graphql for request body Closes gh-948 --- .../server/webflux/GraphQlHttpHandler.java | 20 ++++++++++++++++ .../server/webmvc/GraphQlHttpHandler.java | 23 +++++++++++++++++++ .../webflux/GraphQlHttpHandlerTests.java | 16 +++++++++++++ .../webmvc/GraphQlHttpHandlerTests.java | 13 ++++++++++- 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlHttpHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlHttpHandler.java index 9dd32592..26ac915e 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlHttpHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphQlHttpHandler.java @@ -25,13 +25,16 @@ import org.apache.commons.logging.LogFactory; import reactor.core.publisher.Mono; import org.springframework.core.ParameterizedTypeReference; +import org.springframework.core.io.buffer.DataBuffer; import org.springframework.graphql.server.WebGraphQlHandler; import org.springframework.graphql.server.WebGraphQlRequest; import org.springframework.graphql.server.support.SerializableGraphQlRequest; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.util.Assert; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; +import org.springframework.web.server.UnsupportedMediaTypeStatusException; /** * WebFlux.fn Handler for GraphQL over HTTP requests. @@ -73,6 +76,9 @@ public class GraphQlHttpHandler { */ public Mono handleRequest(ServerRequest serverRequest) { return serverRequest.bodyToMono(SerializableGraphQlRequest.class) + .onErrorResume( + UnsupportedMediaTypeStatusException.class, + (ex) -> applyApplicationGraphQlFallback(ex, serverRequest)) .flatMap((body) -> { WebGraphQlRequest graphQlRequest = new WebGraphQlRequest( serverRequest.uri(), serverRequest.headers().asHttpHeaders(), @@ -95,6 +101,20 @@ public class GraphQlHttpHandler { }); } + private static Mono applyApplicationGraphQlFallback( + UnsupportedMediaTypeStatusException ex, ServerRequest request) { + + // Spec requires application/json but some clients still use application/graphql + return "application/graphql".equals(request.headers().firstHeader(HttpHeaders.CONTENT_TYPE)) ? + ServerRequest.from(request) + .headers((headers) -> headers.setContentType(MediaType.APPLICATION_JSON)) + .body(request.bodyToFlux(DataBuffer.class)) + .build() + .bodyToMono(SerializableGraphQlRequest.class) + .log() : + Mono.error(ex); + } + private static MediaType selectResponseMediaType(ServerRequest serverRequest) { for (MediaType accepted : serverRequest.headers().accept()) { if (SUPPORTED_MEDIA_TYPES.contains(accepted)) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java index 393d4dc0..c9c459cb 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandler.java @@ -35,6 +35,7 @@ import org.springframework.graphql.server.WebGraphQlHandler; import org.springframework.graphql.server.WebGraphQlRequest; import org.springframework.graphql.server.support.SerializableGraphQlRequest; import org.springframework.http.HttpCookie; +import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.util.AlternativeJdkIdGenerator; import org.springframework.util.Assert; @@ -146,6 +147,28 @@ public class GraphQlHttpHandler { catch (IOException ex) { throw new ServerWebInputException("I/O error while reading request body", null, ex); } + catch (HttpMediaTypeNotSupportedException ex) { + return applyApplicationGraphQlFallback(request, ex); + } + } + + private static SerializableGraphQlRequest applyApplicationGraphQlFallback( + ServerRequest request, HttpMediaTypeNotSupportedException ex) throws HttpMediaTypeNotSupportedException { + + // Spec requires application/json but some clients still use application/graphql + if ("application/graphql".equals(request.headers().firstHeader(HttpHeaders.CONTENT_TYPE))) { + try { + request = ServerRequest.from(request) + .headers((headers) -> headers.setContentType(MediaType.APPLICATION_JSON)) + .body(request.body(byte[].class)) + .build(); + return request.body(SerializableGraphQlRequest.class); + } + catch (Throwable ex2) { + // ignore + } + } + throw ex; } private static MediaType selectResponseMediaType(ServerRequest serverRequest) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java index a21c68e9..10cc70cc 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphQlHttpHandlerTests.java @@ -75,6 +75,22 @@ public class GraphQlHttpHandlerTests { .verifyComplete(); } + @Test + void shouldSupportApplicationGraphQl() throws Exception { + String document = "{greeting}"; + MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/") + .contentType(MediaType.parseMediaType("application/graphql")) + .accept(MediaType.ALL) + .body(initRequestBody(document)); + + MockServerHttpResponse response = handleRequest(httpRequest, this.greetingHandler); + + assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON); + StepVerifier.create(response.getBodyAsString()) + .expectNext("{\"data\":{\"greeting\":\"Hello\"}}") + .verifyComplete(); + } + @Test void shouldProduceApplicationGraphQl() throws Exception { MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/") diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java index 90d7f547..ecdf04ce 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphQlHttpHandlerTests.java @@ -36,6 +36,7 @@ import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.server.support.SerializableGraphQlRequest; import org.springframework.http.MediaType; +import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.mock.web.MockHttpServletRequest; @@ -55,7 +56,7 @@ import static org.assertj.core.api.Assertions.assertThatNoException; public class GraphQlHttpHandlerTests { private static final List> MESSAGE_READERS = - Collections.singletonList(new MappingJackson2HttpMessageConverter()); + List.of(new MappingJackson2HttpMessageConverter(), new ByteArrayHttpMessageConverter()); private final GraphQlHttpHandler greetingHandler = GraphQlSetup.schemaContent("type Query { greeting: String }") .queryFetcher("greeting", (env) -> "Hello").toHttpHandler(); @@ -66,6 +67,16 @@ public class GraphQlHttpHandlerTests { MockHttpServletRequest request = createServletRequest("{ greeting }", "*/*"); MockHttpServletResponse response = handleRequest(request, this.greetingHandler); assertThat(response.getContentType()).isEqualTo(MediaType.APPLICATION_JSON_VALUE); + assertThat(response.getContentAsString()).isEqualTo("{\"data\":{\"greeting\":\"Hello\"}}"); + } + + @Test + void shouldSupportApplicationGraphQl() throws Exception { + MockHttpServletRequest request = createServletRequest("{ greeting }", "*/*"); + request.setContentType("application/graphql"); + + MockHttpServletResponse response = handleRequest(request, this.greetingHandler); + assertThat(response.getContentAsString()).isEqualTo("{\"data\":{\"greeting\":\"Hello\"}}"); } @Test