diff --git a/samples/webmvc-http/build.gradle b/samples/webmvc-http/build.gradle index 35fa059a..cfa83f51 100644 --- a/samples/webmvc-http/build.gradle +++ b/samples/webmvc-http/build.gradle @@ -16,6 +16,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' developmentOnly 'org.springframework.boot:spring-boot-devtools' runtimeOnly 'com.h2database:h2' + testImplementation 'org.springframework:spring-webflux' testImplementation 'org.springframework.boot:spring-boot-starter-test' } test { diff --git a/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/JsonRequest.java b/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/JsonRequest.java new file mode 100644 index 00000000..5e8f01bd --- /dev/null +++ b/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/JsonRequest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2002-2021 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 io.spring.sample.graphql.project; + +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; + +import org.springframework.lang.Nullable; +import org.springframework.util.CollectionUtils; + +class JsonRequest { + + private final String query; + + @Nullable + private final String operationName; + + private final Map variables; + + + private JsonRequest(String query, @Nullable String operationName, Map variables) { + this.query = query; + this.operationName = operationName; + this.variables = (!CollectionUtils.isEmpty(variables) ? + new LinkedHashMap<>(variables) : Collections.emptyMap()); + } + + + public String getQuery() { + return query; + } + + public String query() { + return this.query; + } + + @Nullable + public String operationName() { + return this.operationName; + } + + public Map variables() { + return this.variables; + } + + public static JsonRequest create(String query) { + return new JsonRequest(query, null, Collections.emptyMap()); + } + + public static JsonRequest create(String query, String operationName, Map variables) { + return new JsonRequest(query, operationName, variables); + } + +} diff --git a/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/JsonResponse.java b/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/JsonResponse.java new file mode 100644 index 00000000..8db0ecff --- /dev/null +++ b/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/JsonResponse.java @@ -0,0 +1,46 @@ +/* + * Copyright 2002-2021 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 io.spring.sample.graphql.project; + +import java.util.Collections; +import java.util.Map; + +import org.springframework.lang.Nullable; + +class JsonResponse { + + private Map data = Collections.emptyMap(); + + private Map> errors = Collections.emptyMap(); + + + public void setData(@Nullable Map data) { + this.data = data; + } + + public T getDataEntry() { + return this.data.values().iterator().next(); + } + + public void setErrors(@Nullable Map> errors) { + this.errors = errors; + } + + public Map> getErrors() { + return this.errors; + } + +} diff --git a/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/MockWebTestClientTests.java b/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/MockWebTestClientTests.java new file mode 100644 index 00000000..97bbba81 --- /dev/null +++ b/samples/webmvc-http/src/test/java/io/spring/sample/graphql/project/MockWebTestClientTests.java @@ -0,0 +1,114 @@ +/* + * Copyright 2002-2021 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 io.spring.sample.graphql.project; + +import java.util.List; +import java.util.function.Consumer; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.servlet.MockMvc; +import org.springframework.test.web.servlet.client.MockMvcWebTestClient; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Example tests using {@link WebTestClient} to connect to {@link MockMvc} as + * the "mock" server, i.e. without running an HTTP server. + */ +@SpringBootTest +@AutoConfigureMockMvc +public class MockWebTestClientTests { + + private WebTestClient client; + + @BeforeEach + public void setUp(@Autowired MockMvc mockMvc) { + this.client = MockMvcWebTestClient.bindTo(mockMvc) + .baseUrl("/graphql") + .defaultHeaders(headers -> headers.setContentType(MediaType.APPLICATION_JSON)) + .build(); + } + + @Test + void jsonPath() { + String query = "{" + + " project(slug:\"spring-framework\") {" + + " releases {" + + " version" + + " }" + + " }" + + "}"; + + this.client.post().bodyValue(JsonRequest.create(query)) + .exchange() + .expectStatus().isOk() + .expectBody().jsonPath("$.data.project.releases[*].version") + .value((Consumer>) versions -> { + assertThat(versions).hasSizeGreaterThan(1); + }); + } + + @Test + void jsonContent() { + String query = "{" + + " project(slug:\"spring-framework\") {" + + " repositoryUrl" + + " }" + + "}"; + + String expectedJson = "{" + + " \"data\":{" + + " \"project\":{" + + " \"repositoryUrl\":\"http://github.com/spring-projects/spring-framework\"" + + " }" + + " }" + + "}"; + + this.client.post().bodyValue(JsonRequest.create(query)) + .exchange() + .expectStatus().isOk() + .expectBody().json(expectedJson); + } + + @Test + void decodedResponse() { + String query = "{" + + " project(slug:\"spring-framework\") {" + + " releases {" + + " version" + + " }" + + " }" + + "}"; + + this.client.post().bodyValue(JsonRequest.create(query)) + .exchange() + .expectStatus().isOk() + .expectBody(new ParameterizedTypeReference>() {}) + .consumeWith(exchangeResult -> { + Project project = exchangeResult.getResponseBody().getDataEntry(); + assertThat(project.getReleases()).hasSizeGreaterThan(1); + }); + } + +} diff --git a/samples/webmvc-http/src/test/resources/application.properties b/samples/webmvc-http/src/test/resources/application.properties new file mode 100644 index 00000000..7ecf7b5e --- /dev/null +++ b/samples/webmvc-http/src/test/resources/application.properties @@ -0,0 +1 @@ +logging.level.org.springframework.web=DEBUG \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index d4eaa0f0..6cc8b2da 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,5 +1,6 @@ pluginManagement { repositories { + maven { url 'https://repo.spring.io/release' } maven { url 'https://repo.spring.io/milestone' } maven { url 'https://repo.spring.io/snapshot' } gradlePluginPortal()