diff --git a/spring-boot-project/spring-boot-autoconfigure/build.gradle b/spring-boot-project/spring-boot-autoconfigure/build.gradle index 114b137b11..456481a5ac 100644 --- a/spring-boot-project/spring-boot-autoconfigure/build.gradle +++ b/spring-boot-project/spring-boot-autoconfigure/build.gradle @@ -225,6 +225,7 @@ dependencies { testImplementation("com.github.h-thurow:simple-jndi") testImplementation("com.ibm.db2:jcc") testImplementation("com.jayway.jsonpath:json-path") + testImplementation("com.querydsl:querydsl-core") testImplementation("com.squareup.okhttp3:mockwebserver") testImplementation("com.sun.xml.messaging.saaj:saaj-impl") testImplementation("io.projectreactor:reactor-test") @@ -243,6 +244,7 @@ dependencies { testImplementation("org.mockito:mockito-core") testImplementation("org.mockito:mockito-junit-jupiter") testImplementation("org.springframework:spring-test") + testImplementation("org.springframework.graphql:spring-graphql-test") testImplementation("org.springframework.kafka:spring-kafka-test") testImplementation("org.springframework.security:spring-security-test") testImplementation("org.testcontainers:cassandra") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfiguration.java new file mode 100644 index 0000000000..504d4bf024 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfiguration.java @@ -0,0 +1,71 @@ +/* + * 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 org.springframework.boot.autoconfigure.graphql.data; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import graphql.GraphQL; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.repository.query.QueryByExampleExecutor; +import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor; +import org.springframework.graphql.data.query.QueryByExampleDataFetcher; +import org.springframework.graphql.execution.GraphQlSource; + +/** + * {@link EnableAutoConfiguration Auto-configuration} that creates a + * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories with Query + * By Example support and register them as {@code DataFetcher}s for any queries with a + * matching return type. + * + * @author Rossen Stoyanchev + * @since 2.7.0 + * @see QueryByExampleDataFetcher#autoRegistrationTypeVisitor(List, List) + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass({ GraphQL.class, QueryByExampleDataFetcher.class, QueryByExampleExecutor.class }) +@ConditionalOnBean(GraphQlSource.class) +@AutoConfigureAfter(GraphQlAutoConfiguration.class) +public class GraphQlQueryByExampleAutoConfiguration { + + @Bean + public GraphQlSourceBuilderCustomizer queryByExampleRegistrar( + ObjectProvider> executorsProvider, + ObjectProvider> reactiveExecutorsProvider) { + + return (builder) -> { + List> executors = executorsProvider.stream().collect(Collectors.toList()); + List> reactiveExecutors = reactiveExecutorsProvider.stream() + .collect(Collectors.toList()); + if (!executors.isEmpty()) { + builder.typeVisitors(Collections.singletonList( + QueryByExampleDataFetcher.autoRegistrationTypeVisitor(executors, reactiveExecutors))); + } + }; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfiguration.java new file mode 100644 index 0000000000..d10c0dcab0 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfiguration.java @@ -0,0 +1,71 @@ +/* + * 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 org.springframework.boot.autoconfigure.graphql.data; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import graphql.GraphQL; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor; +import org.springframework.graphql.data.query.QuerydslDataFetcher; +import org.springframework.graphql.execution.GraphQlSource; + +/** + * {@link EnableAutoConfiguration Auto-configuration} that creates a + * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories with + * Querydsl support and register them as {@code DataFetcher}s for any queries with a + * matching return type. + * + * @author Rossen Stoyanchev + * @since 2.7.0 + * @see QuerydslDataFetcher#autoRegistrationTypeVisitor(List, List) + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass({ GraphQL.class, QuerydslDataFetcher.class, QuerydslPredicateExecutor.class }) +@ConditionalOnBean(GraphQlSource.class) +@AutoConfigureAfter(GraphQlAutoConfiguration.class) +public class GraphQlQuerydslAutoConfiguration { + + @Bean + public GraphQlSourceBuilderCustomizer querydslRegistrar( + ObjectProvider> executorsProvider, + ObjectProvider> reactiveExecutorsProvider) { + + return (builder) -> { + List> executors = executorsProvider.stream().collect(Collectors.toList()); + List> reactiveExecutors = reactiveExecutorsProvider.stream() + .collect(Collectors.toList()); + if (!executors.isEmpty()) { + builder.typeVisitors(Collections + .singletonList(QuerydslDataFetcher.autoRegistrationTypeVisitor(executors, reactiveExecutors))); + } + }; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfiguration.java new file mode 100644 index 0000000000..e36ec5ba03 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfiguration.java @@ -0,0 +1,67 @@ +/* + * 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 org.springframework.boot.autoconfigure.graphql.data; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import graphql.GraphQL; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor; +import org.springframework.graphql.data.query.QueryByExampleDataFetcher; +import org.springframework.graphql.execution.GraphQlSource; + +/** + * {@link EnableAutoConfiguration Auto-configuration} that creates a + * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories with Query + * By Example support and register them as {@code DataFetcher}s for any queries with a + * matching return type. + * + * @author Rossen Stoyanchev + * @since 2.7.0 + * @see QueryByExampleDataFetcher#autoRegistrationTypeVisitor(List, List) + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass({ GraphQL.class, QueryByExampleDataFetcher.class, ReactiveQueryByExampleExecutor.class }) +@ConditionalOnBean(GraphQlSource.class) +@AutoConfigureAfter(GraphQlAutoConfiguration.class) +public class GraphQlReactiveQueryByExampleAutoConfiguration { + + @Bean + public GraphQlSourceBuilderCustomizer reactiveQueryByExampleRegistrar( + ObjectProvider> executorsProvider) { + + return (builder) -> { + List> executors = executorsProvider.stream().collect(Collectors.toList()); + if (!executors.isEmpty()) { + builder.typeVisitors(Collections.singletonList( + QueryByExampleDataFetcher.autoRegistrationTypeVisitor(Collections.emptyList(), executors))); + } + }; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfiguration.java new file mode 100644 index 0000000000..91b5689855 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfiguration.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 org.springframework.boot.autoconfigure.graphql.data; + +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import graphql.GraphQL; + +import org.springframework.beans.factory.ObjectProvider; +import org.springframework.boot.autoconfigure.AutoConfigureAfter; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor; +import org.springframework.graphql.data.query.QuerydslDataFetcher; +import org.springframework.graphql.execution.GraphQlSource; + +/** + * {@link EnableAutoConfiguration Auto-configuration} that creates a + * {@link GraphQlSourceBuilderCustomizer}s to detect Spring Data repositories with + * Querydsl support and register them as {@code DataFetcher}s for any queries with a + * matching return type. + * + * @author Rossen Stoyanchev + * @since 2.7.0 + * @see QuerydslDataFetcher#autoRegistrationTypeVisitor(List, List) + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnClass({ GraphQL.class, QuerydslDataFetcher.class, ReactiveQuerydslPredicateExecutor.class }) +@ConditionalOnBean(GraphQlSource.class) +@AutoConfigureAfter(GraphQlAutoConfiguration.class) +public class GraphQlReactiveQuerydslAutoConfiguration { + + @Bean + public GraphQlSourceBuilderCustomizer reactiveQuerydslRegistrar( + ObjectProvider> executorsProvider) { + + return (builder) -> { + List> executors = executorsProvider.stream() + .collect(Collectors.toList()); + if (!executors.isEmpty()) { + builder.typeVisitors(Collections.singletonList( + QuerydslDataFetcher.autoRegistrationTypeVisitor(Collections.emptyList(), executors))); + } + }; + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java new file mode 100644 index 0000000000..0f1a57d4f4 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/graphql/data/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2020-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. + */ + +/** + * Auto-configuration classes for data integrations with GraphQL. + */ +package org.springframework.boot.autoconfigure.graphql.data; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index bad6ab475c..e4b771a4cb 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -69,6 +69,10 @@ org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAuto org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\ org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\ org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration,\ +org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQueryByExampleAutoConfiguration,\ +org.springframework.boot.autoconfigure.graphql.data.GraphQlReactiveQuerydslAutoConfiguration,\ +org.springframework.boot.autoconfigure.graphql.data.GraphQlQueryByExampleAutoConfiguration,\ +org.springframework.boot.autoconfigure.graphql.data.GraphQlQuerydslAutoConfiguration,\ org.springframework.boot.autoconfigure.graphql.reactive.GraphQlWebFluxAutoConfiguration,\ org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java index ecd0468216..0dbea1be83 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/Book.java @@ -16,6 +16,8 @@ package org.springframework.boot.autoconfigure.graphql; +import org.springframework.data.annotation.Id; + /** * Sample class for * @@ -23,6 +25,7 @@ package org.springframework.boot.autoconfigure.graphql; */ public class Book { + @Id String id; String name; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java new file mode 100644 index 0000000000..c7e95ac4e7 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/QBook.java @@ -0,0 +1,56 @@ +/* + * Copyright 2012-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 org.springframework.boot.autoconfigure.graphql; + +import com.querydsl.core.types.Path; +import com.querydsl.core.types.PathMetadata; +import com.querydsl.core.types.PathMetadataFactory; +import com.querydsl.core.types.dsl.EntityPathBase; +import com.querydsl.core.types.dsl.NumberPath; +import com.querydsl.core.types.dsl.StringPath; + +/** + * QBook is a Querydsl query type for Book. This class is usually generated by the + * Querydsl annotation processor. + */ +public class QBook extends EntityPathBase { + + private static final long serialVersionUID = -1932588188L; + + public static final QBook book = new QBook("book"); + + public final StringPath author = createString("author"); + + public final StringPath id = createString("id"); + + public final StringPath name = createString("name"); + + public final NumberPath pageCount = createNumber("pageCount", Integer.class); + + public QBook(String variable) { + super(Book.class, PathMetadataFactory.forVariable(variable)); + } + + public QBook(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QBook(PathMetadata metadata) { + super(Book.class, metadata); + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java new file mode 100644 index 0000000000..be28b3e908 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQueryByExampleAutoConfigurationTests.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-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 org.springframework.boot.autoconfigure.graphql.data; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.graphql.Book; +import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.query.QueryByExampleExecutor; +import org.springframework.graphql.GraphQlService; +import org.springframework.graphql.data.GraphQlRepository; +import org.springframework.graphql.test.tester.GraphQlTester; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link GraphQlQueryByExampleAutoConfiguration} + * + * @author Brian Clozel + */ +class GraphQlQueryByExampleAutoConfigurationTests { + + private static final Book book = new Book("42", "Test title", 42, "Test Author"); + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(GraphQlAutoConfiguration.class, GraphQlQueryByExampleAutoConfiguration.class)) + .withUserConfiguration(MockRepositoryConfig.class) + .withPropertyValues("spring.main.web-application-type=reactive"); + + @Test + void shouldRegisterDataFetcherForQueryByExampleRepositories() { + this.contextRunner.run((context) -> { + GraphQlService graphQlService = context.getBean(GraphQlService.class); + GraphQlTester graphQlTester = GraphQlTester.create(graphQlService); + graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class) + .isEqualTo("Test title"); + }); + } + + @Configuration(proxyBeanMethods = false) + static class MockRepositoryConfig { + + @Bean + MockRepository mockRepository() { + MockRepository mockRepository = mock(MockRepository.class); + given(mockRepository.findBy(any(), any())).willReturn(Optional.of(book)); + return mockRepository; + } + + } + + @GraphQlRepository + interface MockRepository extends CrudRepository, QueryByExampleExecutor { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java new file mode 100644 index 0000000000..c687d0834e --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlQuerydslAutoConfigurationTests.java @@ -0,0 +1,81 @@ +/* + * Copyright 2012-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 org.springframework.boot.autoconfigure.graphql.data; + +import java.util.Optional; + +import org.junit.jupiter.api.Test; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.graphql.Book; +import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.test.context.runner.WebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.querydsl.QuerydslPredicateExecutor; +import org.springframework.data.repository.CrudRepository; +import org.springframework.graphql.GraphQlService; +import org.springframework.graphql.data.GraphQlRepository; +import org.springframework.graphql.test.tester.GraphQlTester; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link GraphQlQuerydslAutoConfiguration}. + * + * @author Brian Clozel + */ +class GraphQlQuerydslAutoConfigurationTests { + + private static final Book book = new Book("42", "Test title", 42, "Test Author"); + + private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner() + .withConfiguration( + AutoConfigurations.of(GraphQlAutoConfiguration.class, GraphQlQuerydslAutoConfiguration.class)) + .withUserConfiguration(MockRepositoryConfig.class) + .withPropertyValues("spring.main.web-application-type=reactive"); + + @Test + void shouldRegisterDataFetcherForQueryDslRepositories() { + this.contextRunner.run((context) -> { + GraphQlService graphQlService = context.getBean(GraphQlService.class); + GraphQlTester graphQlTester = GraphQlTester.create(graphQlService); + graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class) + .isEqualTo("Test title"); + }); + } + + @Configuration(proxyBeanMethods = false) + static class MockRepositoryConfig { + + @Bean + MockRepository mockRepository() { + MockRepository mockRepository = mock(MockRepository.class); + given(mockRepository.findBy(any(), any())).willReturn(Optional.of(book)); + return mockRepository; + } + + } + + @GraphQlRepository + interface MockRepository extends CrudRepository, QuerydslPredicateExecutor { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java new file mode 100644 index 0000000000..20eb88e797 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQueryByExampleAutoConfigurationTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-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 org.springframework.boot.autoconfigure.graphql.data; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.graphql.Book; +import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.repository.query.ReactiveQueryByExampleExecutor; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.graphql.GraphQlService; +import org.springframework.graphql.data.GraphQlRepository; +import org.springframework.graphql.test.tester.GraphQlTester; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link GraphQlReactiveQueryByExampleAutoConfiguration} + * + * @author Brian Clozel + */ +class GraphQlReactiveQueryByExampleAutoConfigurationTests { + + private static final Mono bookPublisher = Mono.just(new Book("42", "Test title", 42, "Test Author")); + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(GraphQlAutoConfiguration.class, + GraphQlReactiveQueryByExampleAutoConfiguration.class)) + .withUserConfiguration(MockRepositoryConfig.class) + .withPropertyValues("spring.main.web-application-type=reactive"); + + @Test + void shouldRegisterDataFetcherForQueryByExampleRepositories() { + this.contextRunner.run((context) -> { + GraphQlService graphQlService = context.getBean(GraphQlService.class); + GraphQlTester graphQlTester = GraphQlTester.create(graphQlService); + graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class) + .isEqualTo("Test title"); + }); + } + + @Configuration(proxyBeanMethods = false) + static class MockRepositoryConfig { + + @Bean + MockRepository mockRepository() { + MockRepository mockRepository = mock(MockRepository.class); + given(mockRepository.findBy(any(), any())).willReturn(bookPublisher); + return mockRepository; + } + + } + + @GraphQlRepository + interface MockRepository extends ReactiveCrudRepository, ReactiveQueryByExampleExecutor { + + } + +} diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java new file mode 100644 index 0000000000..4d5d461462 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/graphql/data/GraphQlReactiveQuerydslAutoConfigurationTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2012-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 org.springframework.boot.autoconfigure.graphql.data; + +import org.junit.jupiter.api.Test; +import reactor.core.publisher.Mono; + +import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.graphql.Book; +import org.springframework.boot.autoconfigure.graphql.GraphQlAutoConfiguration; +import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.querydsl.ReactiveQuerydslPredicateExecutor; +import org.springframework.data.repository.reactive.ReactiveCrudRepository; +import org.springframework.graphql.GraphQlService; +import org.springframework.graphql.data.GraphQlRepository; +import org.springframework.graphql.test.tester.GraphQlTester; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; + +/** + * Tests for {@link GraphQlReactiveQuerydslAutoConfiguration} + * + * @author Brian Clozel + */ +class GraphQlReactiveQuerydslAutoConfigurationTests { + + private static final Mono bookPublisher = Mono.just(new Book("42", "Test title", 42, "Test Author")); + + private final ReactiveWebApplicationContextRunner contextRunner = new ReactiveWebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(GraphQlAutoConfiguration.class, + GraphQlReactiveQuerydslAutoConfiguration.class)) + .withUserConfiguration(MockRepositoryConfig.class) + .withPropertyValues("spring.main.web-application-type=reactive"); + + @Test + void shouldRegisterDataFetcherForQueryDslRepositories() { + this.contextRunner.run((context) -> { + GraphQlService graphQlService = context.getBean(GraphQlService.class); + GraphQlTester graphQlTester = GraphQlTester.create(graphQlService); + graphQlTester.query("{ bookById(id: 1) {name}}").execute().path("bookById.name").entity(String.class) + .isEqualTo("Test title"); + }); + } + + @Configuration(proxyBeanMethods = false) + static class MockRepositoryConfig { + + @Bean + MockRepository mockRepository() { + MockRepository mockRepository = mock(MockRepository.class); + given(mockRepository.findBy(any(), any())).willReturn(bookPublisher); + return mockRepository; + } + + } + + @GraphQlRepository + interface MockRepository extends ReactiveCrudRepository, ReactiveQuerydslPredicateExecutor { + + } + +}