Add smoke test for spring-boot-starter-graphql

Fixes gh-47
This commit is contained in:
Scott Frederick
2022-09-29 15:17:28 -05:00
parent ed3105f124
commit 038247d7f0
36 changed files with 1038 additions and 1 deletions

View File

@@ -598,6 +598,31 @@ h|nativeTest
|
5+^h|Graphql
h|Smoke Test
h|appTest
h|nativeAppTest
h|test
h|nativeTest
|graphql-webflux
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-native-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-native-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-native-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-native-test]
|graphql-webflux-rsocket
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-rsocket-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-rsocket-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-rsocket-native-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-rsocket-native-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-rsocket-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-rsocket-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-rsocket-native-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webflux-rsocket-native-test]
|graphql-webmvc
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webmvc-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webmvc-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webmvc-native-app-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webmvc-native-app-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webmvc-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webmvc-test]
|image:https://ci.spring.io/api/v1/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webmvc-native-test/badge[link=https://ci.spring.io/teams/spring-aot-smoke-tests/pipelines/spring-aot-smoke-tests-1.0.x/jobs/graphql-webmvc-native-test]
5+^h|Integration
h|Smoke Test
h|appTest

View File

@@ -291,6 +291,17 @@ groups:
- name: websocket-undertow
app_test: true
test: false
- name: graphql
smoke_tests:
- name: graphql-webflux
app_test: true
test: true
- name: graphql-webflux-rsocket
app_test: true
test: true
- name: graphql-webmvc
app_test: true
test: true
- name: integration
smoke_tests:
- name: integration

View File

@@ -0,0 +1 @@
Tests if Spring for GraphQL with WebFlux over RSockets is working

View File

@@ -0,0 +1,27 @@
plugins {
id 'java'
id 'org.springframework.boot'
id 'org.springframework.aot.smoke-test'
id 'org.graalvm.buildtools.native'
}
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-rsocket")
implementation("org.springframework.boot:spring-boot-starter-graphql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.graphql:spring-graphql-test")
testImplementation("io.projectreactor:reactor-test")
appTestImplementation(project(":aot-smoke-test-support"))
appTestImplementation("org.springframework.boot:spring-boot-starter-rsocket")
appTestImplementation("org.springframework.graphql:spring-graphql-test")
appTestImplementation("org.springframework.boot:spring-boot-starter-json")
appTestImplementation("io.projectreactor:reactor-test")
}
aotSmokeTest {
webApplication = true
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright 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 com.example.graphql.webflux;
import io.rsocket.transport.netty.client.TcpClientTransport;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.aot.smoketest.support.junit.ApplicationTest;
import org.springframework.graphql.client.RSocketGraphQlClient;
@ApplicationTest
class GraphQlApplicationAotTests {
@Test
void getProject() {
TcpClientTransport transport = TcpClientTransport.create(9090);
RSocketGraphQlClient graphQlClient = RSocketGraphQlClient.builder().clientTransport(transport).build();
Mono<String> projectName = graphQlClient.documentName("project").retrieve("project.name")
.toEntity(String.class);
StepVerifier.create(projectName).expectNext("Spring Framework").expectComplete().verify();
}
}

View File

@@ -0,0 +1,5 @@
{
project(slug:"spring-framework") {
name
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 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 com.example.graphql.webflux;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GraphQlApplication {
public static void main(String[] args) {
SpringApplication.run(GraphQlApplication.class, args);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 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 com.example.graphql.webflux;
import java.util.Objects;
public class Project {
private String slug;
private String name;
public Project(String slug, String name) {
this.slug = slug;
this.name = name;
}
public String getSlug() {
return this.slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Project project = (Project) o;
return this.slug.equals(project.slug);
}
@Override
public int hashCode() {
return Objects.hash(this.slug);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 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 com.example.graphql.webflux;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
@Controller
public class ProjectController {
private final List<Project> projects;
public ProjectController() {
this.projects = Arrays.asList(new Project("spring-boot", "Spring Boot"),
new Project("spring-graphql", "Spring GraphQL"), new Project("spring-framework", "Spring Framework"));
}
@QueryMapping
public Optional<Project> project(@Argument String slug) {
return this.projects.stream().filter((project) -> project.getSlug().equals(slug)).findFirst();
}
}

View File

@@ -0,0 +1,7 @@
spring:
graphql:
rsocket:
mapping: graphql
rsocket:
server:
port: 9090

View File

@@ -0,0 +1,8 @@
type Query {
project(slug: ID!): Project
}
type Project {
slug: ID!
name: String!
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 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 com.example.graphql.webflux;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.GraphQlTester;
@SpringBootTest
@AutoConfigureGraphQlTester
class GraphQlTesterTests {
private static final String DOCUMENT = """
{
project(slug:"spring-boot") {
name
}
}
""";
@Autowired
private GraphQlTester graphQlTester;
@Test
void getProject() {
graphQlTester.document(DOCUMENT).execute().path("project.name").entity(String.class).isEqualTo("Spring Boot");
}
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright 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 com.example.graphql.webflux;
import io.rsocket.transport.netty.client.TcpClientTransport;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.RSocketGraphQlTester;
@SpringBootTest
@AutoConfigureGraphQlTester
class TcpTests {
private static final String DOCUMENT = """
{
project(slug:"spring-boot") {
name
}
}
""";
@Test
void getProject() {
TcpClientTransport transport = TcpClientTransport.create(9090);
RSocketGraphQlTester graphQlTester = RSocketGraphQlTester.builder().clientTransport(transport).build();
graphQlTester.document(DOCUMENT).execute().path("project.name").entity(String.class).isEqualTo("Spring Boot");
}
}

View File

@@ -0,0 +1 @@
Tests if Spring for GraphQL with WebFlux over HTTP and WebSocket is working

View File

@@ -0,0 +1,26 @@
plugins {
id 'java'
id 'org.springframework.boot'
id 'org.springframework.aot.smoke-test'
id 'org.graalvm.buildtools.native'
}
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-webflux")
implementation("org.springframework.boot:spring-boot-starter-websocket")
implementation("org.springframework.boot:spring-boot-starter-graphql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.graphql:spring-graphql-test")
testImplementation("io.projectreactor:reactor-test")
appTestImplementation(project(":aot-smoke-test-support"))
appTestImplementation("org.springframework.graphql:spring-graphql-test")
appTestImplementation("org.springframework.boot:spring-boot-starter-json")
appTestImplementation("io.projectreactor:reactor-test")
}
aotSmokeTest {
webApplication = true
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 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 com.example.graphql.webflux;
import java.net.URI;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.aot.smoketest.support.junit.ApplicationTest;
import org.springframework.aot.smoketest.support.junit.ApplicationUrl;
import org.springframework.graphql.client.HttpGraphQlClient;
import org.springframework.graphql.client.WebSocketGraphQlClient;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
import org.springframework.web.reactive.socket.client.WebSocketClient;
@ApplicationTest
class GraphQlApplicationAotTests {
@Test
void getProjectUsingHttp(@ApplicationUrl(scheme = ApplicationUrl.Scheme.HTTP) URI applicationUrl) {
WebClient webClient = WebClient.create(applicationUrl.toString() + "/graphql");
HttpGraphQlClient graphQlClient = HttpGraphQlClient.create(webClient);
Mono<String> projectName = graphQlClient.documentName("project").retrieve("project.name")
.toEntity(String.class);
StepVerifier.create(projectName).expectNext("Spring Framework").expectComplete().verify();
}
@Test
void getProjectUsingWebSocket(@ApplicationUrl(scheme = ApplicationUrl.Scheme.WEBSOCKET) URI applicationUrl) {
WebSocketClient webClient = new ReactorNettyWebSocketClient();
WebSocketGraphQlClient graphQlClient = WebSocketGraphQlClient
.builder(applicationUrl.toString() + "/graphql", webClient).build();
Mono<String> projectName = graphQlClient.documentName("project").retrieve("project.name")
.toEntity(String.class);
StepVerifier.create(projectName).expectNext("Spring Framework").expectComplete().verify();
}
}

View File

@@ -0,0 +1,5 @@
{
project(slug:"spring-framework") {
name
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 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 com.example.graphql.webflux;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GraphQlApplication {
public static void main(String[] args) {
SpringApplication.run(GraphQlApplication.class, args);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 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 com.example.graphql.webflux;
import java.util.Objects;
public class Project {
private String slug;
private String name;
public Project(String slug, String name) {
this.slug = slug;
this.name = name;
}
public String getSlug() {
return this.slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Project project = (Project) o;
return this.slug.equals(project.slug);
}
@Override
public int hashCode() {
return Objects.hash(this.slug);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 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 com.example.graphql.webflux;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
@Controller
public class ProjectController {
private final List<Project> projects;
public ProjectController() {
this.projects = Arrays.asList(new Project("spring-boot", "Spring Boot"),
new Project("spring-graphql", "Spring GraphQL"), new Project("spring-framework", "Spring Framework"));
}
@QueryMapping
public Optional<Project> project(@Argument String slug) {
return this.projects.stream().filter((project) -> project.getSlug().equals(slug)).findFirst();
}
}

View File

@@ -0,0 +1,4 @@
spring:
graphql:
websocket:
path: /graphql

View File

@@ -0,0 +1,8 @@
type Query {
project(slug: ID!): Project
}
type Project {
slug: ID!
name: String!
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 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 com.example.graphql.webflux;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.GraphQlTester;
@SpringBootTest
@AutoConfigureGraphQlTester
class GraphQlTesterTests {
private static final String DOCUMENT = """
{
project(slug:"spring-boot") {
name
}
}
""";
@Autowired
private GraphQlTester graphQlTester;
@Test
void getProject() {
graphQlTester.document(DOCUMENT).execute().path("project.name").entity(String.class).isEqualTo("Spring Boot");
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 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 com.example.graphql.webflux;
import java.net.URI;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.graphql.test.tester.WebSocketGraphQlTester;
import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
import org.springframework.web.reactive.socket.client.WebSocketClient;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@SpringBootTest(webEnvironment = RANDOM_PORT)
@AutoConfigureHttpGraphQlTester
class RandomPortTests {
private static final String DOCUMENT = """
{
project(slug:"spring-boot") {
name
}
}
""";
@LocalServerPort
private int localPort;
@Test
void getProjectUsingHttp(@Autowired HttpGraphQlTester graphQlTester) {
graphQlTester.document(DOCUMENT).execute().path("project.name").entity(String.class).isEqualTo("Spring Boot");
}
@Test
void getProjectUsingWebSocket() {
WebSocketClient webClient = new ReactorNettyWebSocketClient();
URI uri = URI.create("http://localhost:" + localPort + "/graphql");
WebSocketGraphQlTester graphQlTester = WebSocketGraphQlTester.create(uri, webClient);
graphQlTester.document(DOCUMENT).execute().path("project.name").entity(String.class).isEqualTo("Spring Boot");
}
}

View File

@@ -0,0 +1 @@
Tests if Spring for GraphQL with WebMVC is working

View File

@@ -0,0 +1,27 @@
plugins {
id 'java'
id 'org.springframework.boot'
id 'org.springframework.aot.smoke-test'
id 'org.graalvm.buildtools.native'
}
dependencies {
implementation(platform(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES))
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.springframework.boot:spring-boot-starter-websocket")
implementation("org.springframework.boot:spring-boot-starter-graphql")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.boot:spring-boot-starter-webflux")
testImplementation("org.springframework.graphql:spring-graphql-test")
testImplementation("io.projectreactor:reactor-test")
appTestImplementation(project(":aot-smoke-test-support"))
appTestImplementation("org.springframework.graphql:spring-graphql-test")
appTestImplementation("org.springframework.boot:spring-boot-starter-json")
appTestImplementation("io.projectreactor:reactor-test")
}
aotSmokeTest {
webApplication = true
}

View File

@@ -0,0 +1,55 @@
/*
* Copyright 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 com.example.graphql.webmvc;
import java.net.URI;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import reactor.test.StepVerifier;
import org.springframework.aot.smoketest.support.junit.ApplicationTest;
import org.springframework.aot.smoketest.support.junit.ApplicationUrl;
import org.springframework.graphql.client.HttpGraphQlClient;
import org.springframework.graphql.client.WebSocketGraphQlClient;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
import org.springframework.web.reactive.socket.client.WebSocketClient;
@ApplicationTest
class GraphQlApplicationAotTests {
@Test
void getProjectUsingHttp(@ApplicationUrl(scheme = ApplicationUrl.Scheme.HTTP) URI applicationUrl) {
WebClient webClient = WebClient.create(applicationUrl.toString() + "/graphql");
HttpGraphQlClient graphQlClient = HttpGraphQlClient.create(webClient);
Mono<String> projectName = graphQlClient.documentName("project").retrieve("project.name")
.toEntity(String.class);
StepVerifier.create(projectName).expectNext("Spring Framework").expectComplete().verify();
}
@Test
void getProjectUsingWebSocket(@ApplicationUrl(scheme = ApplicationUrl.Scheme.WEBSOCKET) URI applicationUrl) {
WebSocketClient webClient = new ReactorNettyWebSocketClient();
WebSocketGraphQlClient graphQlClient = WebSocketGraphQlClient
.builder(applicationUrl.toString() + "/graphql", webClient).build();
Mono<String> projectName = graphQlClient.documentName("project").retrieve("project.name")
.toEntity(String.class);
StepVerifier.create(projectName).expectNext("Spring Framework").expectComplete().verify();
}
}

View File

@@ -0,0 +1,5 @@
{
project(slug:"spring-framework") {
name
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright 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 com.example.graphql.webmvc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GraphQlApplication {
public static void main(String[] args) {
SpringApplication.run(GraphQlApplication.class, args);
}
}

View File

@@ -0,0 +1,65 @@
/*
* Copyright 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 com.example.graphql.webmvc;
import java.util.Objects;
public class Project {
private String slug;
private String name;
public Project(String slug, String name) {
this.slug = slug;
this.name = name;
}
public String getSlug() {
return this.slug;
}
public void setSlug(String slug) {
this.slug = slug;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Project project = (Project) o;
return this.slug.equals(project.slug);
}
@Override
public int hashCode() {
return Objects.hash(this.slug);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright 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 com.example.graphql.webmvc;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
@Controller
public class ProjectController {
private final List<Project> projects;
public ProjectController() {
this.projects = Arrays.asList(new Project("spring-boot", "Spring Boot"),
new Project("spring-graphql", "Spring GraphQL"), new Project("spring-framework", "Spring Framework"));
}
@QueryMapping
public Optional<Project> project(@Argument String slug) {
return this.projects.stream().filter((project) -> project.getSlug().equals(slug)).findFirst();
}
}

View File

@@ -0,0 +1,4 @@
spring:
graphql:
websocket:
path: /graphql

View File

@@ -0,0 +1,8 @@
type Query {
project(slug: ID!): Project
}
type Project {
slug: ID!
name: String!
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright 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 com.example.graphql.webmvc;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.graphql.test.tester.GraphQlTester;
@SpringBootTest
@AutoConfigureGraphQlTester
class GraphQlTesterTests {
private static final String DOCUMENT = """
{
project(slug:"spring-boot") {
name
}
}
""";
@Autowired
private GraphQlTester graphQlTester;
@Test
void getProject() {
graphQlTester.document(DOCUMENT).execute().path("project.name").entity(String.class).isEqualTo("Spring Boot");
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright 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 com.example.graphql.webmvc;
import java.net.URI;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.graphql.tester.AutoConfigureHttpGraphQlTester;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.graphql.test.tester.HttpGraphQlTester;
import org.springframework.graphql.test.tester.WebSocketGraphQlTester;
import org.springframework.web.reactive.socket.client.ReactorNettyWebSocketClient;
import org.springframework.web.reactive.socket.client.WebSocketClient;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@SpringBootTest(webEnvironment = RANDOM_PORT)
@AutoConfigureHttpGraphQlTester
class RandomPortTests {
private static final String DOCUMENT = """
{
project(slug:"spring-boot") {
name
}
}
""";
@LocalServerPort
private int localPort;
@Test
void getProjectUsingHttp(@Autowired HttpGraphQlTester graphQlTester) {
graphQlTester.document(DOCUMENT).execute().path("project.name").entity(String.class).isEqualTo("Spring Boot");
}
@Test
void getProjectUsingWebSocket() {
WebSocketClient webClient = new ReactorNettyWebSocketClient();
URI uri = URI.create("http://localhost:" + localPort + "/graphql");
WebSocketGraphQlTester graphQlTester = WebSocketGraphQlTester.create(uri, webClient);
graphQlTester.document(DOCUMENT).execute().path("project.name").entity(String.class).isEqualTo("Spring Boot");
}
}

View File

@@ -27,7 +27,7 @@ rootProject.name="spring-aot-smoke-tests"
include "aot-smoke-test-support"
include "aot-smoke-test-third-party-hints"
["batch", "boot", "cloud", "data", "framework", "integration", "security", "session"].each { group ->
["batch", "boot", "cloud", "data", "framework", "graphql", "integration", "security", "session"].each { group ->
file(group).eachDirMatch(~/[a-z].*/) { smokeTest ->
include "$group:${smokeTest.name}"
}