diff --git a/spring-graphql/src/test/java/org/springframework/graphql/GraphQlServiceSetup.java b/spring-graphql/src/test/java/org/springframework/graphql/GraphQlServiceSetup.java new file mode 100644 index 00000000..42e843cf --- /dev/null +++ b/spring-graphql/src/test/java/org/springframework/graphql/GraphQlServiceSetup.java @@ -0,0 +1,32 @@ +/* + * 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.graphql; + +import org.springframework.graphql.execution.DataLoaderRegistrar; + +/** + * Workflow that results in the creation of a {@link GraphQlService} or a + * {@link org.springframework.graphql.web.WebGraphQlHandler}. + * + * @author Rossen Stoyanchev + */ +public interface GraphQlServiceSetup extends WebGraphQlSetup { + + GraphQlServiceSetup dataLoaders(DataLoaderRegistrar... registrars); + + GraphQlService toGraphQlService(); + +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/GraphQlSetup.java b/spring-graphql/src/test/java/org/springframework/graphql/GraphQlSetup.java new file mode 100644 index 00000000..b99504c7 --- /dev/null +++ b/spring-graphql/src/test/java/org/springframework/graphql/GraphQlSetup.java @@ -0,0 +1,167 @@ +/* + * 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.graphql; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import graphql.GraphQL; +import graphql.schema.DataFetcher; +import graphql.schema.GraphQLTypeVisitor; +import graphql.schema.TypeResolver; + +import org.springframework.core.io.ByteArrayResource; +import org.springframework.core.io.Resource; +import org.springframework.graphql.execution.DataFetcherExceptionResolver; +import org.springframework.graphql.execution.DataLoaderRegistrar; +import org.springframework.graphql.execution.ExecutionGraphQlService; +import org.springframework.graphql.execution.GraphQlSource; +import org.springframework.graphql.execution.RuntimeWiringConfigurer; +import org.springframework.graphql.execution.ThreadLocalAccessor; +import org.springframework.graphql.web.WebGraphQlHandler; +import org.springframework.graphql.web.WebInterceptor; + +/** + * Workflow for GraphQL tests setup that starts with {@link GraphQlSource.Builder} + * related input, and then optionally moving on to the creation of a + * {@link GraphQlService} or a {@link WebGraphQlHandler}. + * + * @author Rossen Stoyanchev + */ +@SuppressWarnings("unused") +public class GraphQlSetup implements GraphQlServiceSetup { + + private final GraphQlSource.Builder graphQlSourceBuilder; + + private final List dataLoaderRegistrars = new ArrayList<>(); + + private final List webInterceptors = new ArrayList<>(); + + private final List accessors = new ArrayList<>(); + + + private GraphQlSetup(Resource... schemaResources) { + this.graphQlSourceBuilder = GraphQlSource.builder().schemaResources(schemaResources); + } + + + public GraphQlSetup queryFetcher(String field, DataFetcher dataFetcher) { + return dataFetcher("Query", field, dataFetcher); + } + + public GraphQlSetup mutationFetcher(String field, DataFetcher dataFetcher) { + return dataFetcher("Mutation", field, dataFetcher); + } + + public GraphQlSetup subscriptionFetcher(String field, DataFetcher dataFetcher) { + return dataFetcher("Subscription", field, dataFetcher); + } + + public GraphQlSetup dataFetcher(String type, String field, DataFetcher dataFetcher) { + return runtimeWiring(wiringBuilder -> + wiringBuilder.type(type, typeBuilder -> typeBuilder.dataFetcher(field, dataFetcher))); + } + + public GraphQlSetup runtimeWiring(RuntimeWiringConfigurer configurer) { + this.graphQlSourceBuilder.configureRuntimeWiring(configurer); + return this; + } + + public GraphQlSetup exceptionResolver(DataFetcherExceptionResolver... resolvers) { + this.graphQlSourceBuilder.exceptionResolvers(Arrays.asList(resolvers)); + return this; + } + + public GraphQlSetup typeResolver(TypeResolver typeResolver) { + this.graphQlSourceBuilder.defaultTypeResolver(typeResolver); + return this; + } + + public GraphQlSetup typeVisitor(GraphQLTypeVisitor... visitors) { + this.graphQlSourceBuilder.typeVisitors(Arrays.asList(visitors)); + return this; + } + + public GraphQL toGraphQl() { + return this.graphQlSourceBuilder.build().graphQl(); + } + + public GraphQlSource toGraphQlSource() { + return this.graphQlSourceBuilder.build(); + } + + + // GraphQlServiceSetup... + + @Override + public GraphQlServiceSetup dataLoaders(DataLoaderRegistrar... registrars) { + this.dataLoaderRegistrars.addAll(Arrays.asList(registrars)); + return this; + } + + public ExecutionGraphQlService toGraphQlService() { + GraphQlSource source = graphQlSourceBuilder.build(); + ExecutionGraphQlService service = new ExecutionGraphQlService(source); + this.dataLoaderRegistrars.forEach(service::addDataLoaderRegistrar); + return service; + } + + + // WebGraphQlSetup... + + public WebGraphQlSetup webInterceptor(WebInterceptor... interceptors) { + this.webInterceptors.addAll(Arrays.asList(interceptors)); + return this; + } + + @Override + public WebGraphQlSetup threadLocalAccessor(ThreadLocalAccessor... accessors) { + this.accessors.addAll(Arrays.asList(accessors)); + return this; + } + + public WebGraphQlHandler toWebGraphQlHandler() { + ExecutionGraphQlService service = toGraphQlService(); + return WebGraphQlHandler.builder(service) + .interceptors(webInterceptors) + .threadLocalAccessors(this.accessors) + .build(); + } + + @Override + public org.springframework.graphql.web.webmvc.GraphQlHttpHandler toHttpHandler() { + return new org.springframework.graphql.web.webmvc.GraphQlHttpHandler(toWebGraphQlHandler()); + } + + @Override + public org.springframework.graphql.web.webflux.GraphQlHttpHandler toHttpHandlerWebFlux() { + return new org.springframework.graphql.web.webflux.GraphQlHttpHandler(toWebGraphQlHandler()); + } + + + // Factory methods + + public static GraphQlSetup schemaContent(String schema) { + return new GraphQlSetup(new ByteArrayResource(schema.getBytes(StandardCharsets.UTF_8))); + } + + public static GraphQlSetup schemaResource(Resource... resources) { + return new GraphQlSetup(resources); + } + +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/GraphQlTestUtils.java b/spring-graphql/src/test/java/org/springframework/graphql/GraphQlTestUtils.java deleted file mode 100644 index 20fb2375..00000000 --- a/spring-graphql/src/test/java/org/springframework/graphql/GraphQlTestUtils.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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.graphql; - -import java.nio.charset.StandardCharsets; - -import graphql.schema.DataFetcher; - -import org.springframework.core.io.ByteArrayResource; -import org.springframework.core.io.Resource; -import org.springframework.graphql.execution.GraphQlSource; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; - -/** - * Utility methods for GraphQL tests. - */ -public abstract class GraphQlTestUtils { - - /** - * Initialize a {@link GraphQlSource.Builder} with a single {@link DataFetcher}. - * - * @param schema either String content or a {@link Resource}. - * @param typeName the parent type name (Query, Mutation, or Subscription). - * @param fieldName the name of the operation - * @param fetcher the fetcher to use - * - * @return the created builder - */ - public static GraphQlSource.Builder graphQlSource( - Object schema, String typeName, String fieldName, DataFetcher fetcher) { - - return graphQlSource(schema, - wiring -> wiring.type(typeName, builder -> builder.dataFetcher(fieldName, fetcher))); - } - - /** - * Initialize a {@link GraphQlSource.Builder} with a {@link RuntimeWiringConfigurer}, - * which may be useful for multiple {@link DataFetcher} registrations, or for a - * built-in implementation (e.g. for annotated handler methods). - * - * @param schema either String content or a {@link Resource}. - * @param configurer the configurer to apply to the RuntimeWiring - * - * @return the created builder - */ - public static GraphQlSource.Builder graphQlSource(Object schema, RuntimeWiringConfigurer configurer) { - Resource schemaResource = (schema instanceof String ? - new ByteArrayResource(((String) schema).getBytes(StandardCharsets.UTF_8)) : - (Resource) schema); - - return GraphQlSource.builder() - .schemaResources(schemaResource) - .configureRuntimeWiring(configurer); - } - -} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/TestThreadLocalAccessor.java b/spring-graphql/src/test/java/org/springframework/graphql/TestThreadLocalAccessor.java index 326617ca..80bebbd6 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/TestThreadLocalAccessor.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/TestThreadLocalAccessor.java @@ -34,7 +34,7 @@ public class TestThreadLocalAccessor implements ThreadLocalAccessor { @Nullable private Long threadId; - private boolean suppressThreadIdCheck; + private final boolean suppressThreadIdCheck; public TestThreadLocalAccessor(ThreadLocal threadLocal) { this(threadLocal, false); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/WebGraphQlSetup.java b/spring-graphql/src/test/java/org/springframework/graphql/WebGraphQlSetup.java new file mode 100644 index 00000000..95c27f97 --- /dev/null +++ b/spring-graphql/src/test/java/org/springframework/graphql/WebGraphQlSetup.java @@ -0,0 +1,40 @@ +/* + * 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.graphql; + +import org.springframework.graphql.execution.ThreadLocalAccessor; +import org.springframework.graphql.web.WebGraphQlHandler; +import org.springframework.graphql.web.WebInterceptor; + +/** + * Workflow that results in the creation of a {@link WebGraphQlHandler} or + * an HTTP handler for WebMvc or WebFlux. + * + * @author Rossen Stoyanchev + */ +public interface WebGraphQlSetup { + + WebGraphQlSetup webInterceptor(WebInterceptor... interceptors); + + WebGraphQlSetup threadLocalAccessor(ThreadLocalAccessor... accessors); + + WebGraphQlHandler toWebGraphQlHandler(); + + org.springframework.graphql.web.webmvc.GraphQlHttpHandler toHttpHandler(); + + org.springframework.graphql.web.webflux.GraphQlHttpHandler toHttpHandlerWebFlux(); + +} diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java index 5c7fc52d..d57f7845 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/BatchMappingInvocationTests.java @@ -40,14 +40,13 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext import org.springframework.context.annotation.Bean; import org.springframework.graphql.GraphQlResponse; import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.GraphQlTestUtils; +import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.RequestInput; import org.springframework.graphql.data.method.annotation.BatchMapping; import org.springframework.graphql.data.method.annotation.QueryMapping; import org.springframework.graphql.execution.BatchLoaderRegistry; import org.springframework.graphql.execution.DefaultBatchLoaderRegistry; import org.springframework.graphql.execution.ExecutionGraphQlService; -import org.springframework.graphql.execution.GraphQlSource; import org.springframework.lang.Nullable; import org.springframework.stereotype.Controller; @@ -258,10 +257,10 @@ public class BatchMappingInvocationTests { @Bean public GraphQlService graphQlService(AnnotatedControllerConfigurer configurer, BatchLoaderRegistry registry) { - GraphQlSource source = GraphQlTestUtils.graphQlSource(schema, configurer).build(); - ExecutionGraphQlService service = new ExecutionGraphQlService(source); - service.addDataLoaderRegistrar(registry); - return service; + return GraphQlSetup.schemaContent(schema) + .runtimeWiring(configurer) + .dataLoaders(registry) + .toGraphQlService(); } @Bean diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java index 476105fb..128e879c 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/method/annotation/support/SchemaMappingInvocationTests.java @@ -37,7 +37,7 @@ import org.springframework.graphql.BookCriteria; import org.springframework.graphql.BookSource; import org.springframework.graphql.GraphQlResponse; import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.GraphQlTestUtils; +import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.RequestInput; import org.springframework.graphql.data.method.annotation.Argument; import org.springframework.graphql.data.method.annotation.MutationMapping; @@ -47,7 +47,6 @@ import org.springframework.graphql.data.method.annotation.SubscriptionMapping; import org.springframework.graphql.execution.BatchLoaderRegistry; import org.springframework.graphql.execution.DefaultBatchLoaderRegistry; import org.springframework.graphql.execution.ExecutionGraphQlService; -import org.springframework.graphql.execution.GraphQlSource; import org.springframework.stereotype.Controller; import static org.assertj.core.api.Assertions.assertThat; @@ -192,11 +191,11 @@ public class SchemaMappingInvocationTests { } @Bean - public GraphQlService graphQlService(AnnotatedControllerConfigurer configurer) { - GraphQlSource source = GraphQlTestUtils.graphQlSource(BookSource.schema, configurer).build(); - ExecutionGraphQlService service = new ExecutionGraphQlService(source); - service.addDataLoaderRegistrar(batchLoaderRegistry()); - return service; + public GraphQlService graphQlService(AnnotatedControllerConfigurer configurer, BatchLoaderRegistry registry) { + return GraphQlSetup.schemaResource(BookSource.schema) + .runtimeWiring(configurer) + .dataLoaders(registry) + .toGraphQlService(); } @Bean diff --git a/spring-graphql/src/test/java/org/springframework/graphql/data/querydsl/QuerydslDataFetcherTests.java b/spring-graphql/src/test/java/org/springframework/graphql/data/querydsl/QuerydslDataFetcherTests.java index dbb4a1d7..ef74029d 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/data/querydsl/QuerydslDataFetcherTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/data/querydsl/QuerydslDataFetcherTests.java @@ -44,11 +44,8 @@ import org.springframework.data.repository.Repository; import org.springframework.graphql.Author; import org.springframework.graphql.BookSource; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.GraphQlTestUtils; +import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.data.GraphQlRepository; -import org.springframework.graphql.execution.ExecutionGraphQlService; -import org.springframework.graphql.execution.GraphQlSource; -import org.springframework.graphql.execution.RuntimeWiringConfigurer; import org.springframework.graphql.web.WebGraphQlHandler; import org.springframework.graphql.web.WebInput; import org.springframework.graphql.web.WebOutput; @@ -77,18 +74,18 @@ class QuerydslDataFetcherTests { Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); mockRepository.save(book); - Consumer tester = (handler) -> { - Mono outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}")); + Consumer tester = setup -> { + Mono output = setup.toWebGraphQlHandler().handleRequest(input("{ bookById(id: 42) {name}}")); + Book actualBook = GraphQlResponse.from(output).toEntity("bookById", Book.class); - Book actualBook = GraphQlResponse.from(outputMono).toEntity("bookById", Book.class); assertThat(actualBook.getName()).isEqualTo(book.getName()); }; // explicit wiring - tester.accept(initHandler("bookById", QuerydslDataFetcher.builder(mockRepository).single())); + tester.accept(graphQlSetup("bookById", QuerydslDataFetcher.builder(mockRepository).single())); // auto registration - tester.accept(initHandler(builder -> {}, mockRepository, null)); + tester.accept(graphQlSetup(mockRepository)); } @Test @@ -97,20 +94,20 @@ class QuerydslDataFetcherTests { Book book2 = new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")); mockRepository.saveAll(Arrays.asList(book1, book2)); - Consumer tester = (handler) -> { - Mono outputMono = handler.handleRequest(input("{ books {name}}")); + Consumer tester = graphQlSetup -> { + Mono output = graphQlSetup.toWebGraphQlHandler().handleRequest(input("{ books {name}}")); - List names = GraphQlResponse.from(outputMono).toList("books", Book.class) + List names = GraphQlResponse.from(output).toList("books", Book.class) .stream().map(Book::getName).collect(Collectors.toList()); assertThat(names).containsExactlyInAnyOrder(book1.getName(), book2.getName()); }; // explicit wiring - tester.accept(initHandler("books", QuerydslDataFetcher.builder(mockRepository).many())); + tester.accept(graphQlSetup("books", QuerydslDataFetcher.builder(mockRepository).many())); // auto registration - tester.accept(initHandler(builder -> {}, mockRepository, null)); + tester.accept(graphQlSetup(mockRepository)); } @Test @@ -120,16 +117,16 @@ class QuerydslDataFetcherTests { when(mockRepository.findBy(any(), any())).thenReturn(Optional.of(book)); // 1) Automatic registration only - WebGraphQlHandler handler = initHandler(builder -> {}, mockRepository, null); + WebGraphQlHandler handler = graphQlSetup(mockRepository).toWebGraphQlHandler(); Mono outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}")); Book actualBook = GraphQlResponse.from(outputMono).toEntity("bookById", Book.class); assertThat(actualBook.getName()).isEqualTo("Hitchhiker's Guide to the Galaxy"); // 2) Automatic registration and explicit wiring - handler = initHandler( - "bookById", env -> new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")), - mockRepository); + handler = graphQlSetup(mockRepository) + .queryFetcher("bookById", env -> new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg"))) + .toWebGraphQlHandler(); outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}")); @@ -142,8 +139,8 @@ class QuerydslDataFetcherTests { Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); mockRepository.save(book); - WebGraphQlHandler handler = initHandler("bookById", - QuerydslDataFetcher.builder(mockRepository).projectAs(BookProjection.class).single()); + DataFetcher fetcher = QuerydslDataFetcher.builder(mockRepository).projectAs(BookProjection.class).single(); + WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler(); Mono outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}")); @@ -156,8 +153,8 @@ class QuerydslDataFetcherTests { Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); mockRepository.save(book); - WebGraphQlHandler handler = initHandler("bookById", - QuerydslDataFetcher.builder(mockRepository).projectAs(BookDto.class).single()); + DataFetcher fetcher = QuerydslDataFetcher.builder(mockRepository).projectAs(BookDto.class).single(); + WebGraphQlHandler handler = graphQlSetup("bookById", fetcher).toWebGraphQlHandler(); Mono outputMono = handler.handleRequest(input("{ bookById(id: 42) {name}}")); @@ -169,11 +166,12 @@ class QuerydslDataFetcherTests { void shouldConstructPredicateProperly() { MockRepository mockRepository = mock(MockRepository.class); - WebGraphQlHandler handler = initHandler("books", - QuerydslDataFetcher.builder(mockRepository) - .customizer((QuerydslBinderCustomizer) (bindings, book) -> - bindings.bind(book.name).firstOptional((path, value) -> value.map(path::startsWith))) - .many()); + DataFetcher> fetcher = QuerydslDataFetcher.builder(mockRepository) + .customizer((QuerydslBinderCustomizer) (bindings, book) -> + bindings.bind(book.name).firstOptional((path, value) -> value.map(path::startsWith))) + .many(); + + WebGraphQlHandler handler = graphQlSetup("books", fetcher).toWebGraphQlHandler(); handler.handleRequest(input("{ books(name: \"H\", author: \"Doug\") {name}}")).block(); @@ -190,18 +188,18 @@ class QuerydslDataFetcherTests { Book book = new Book(42L, "Hitchhiker's Guide to the Galaxy", new Author(0L, "Douglas", "Adams")); when(mockRepository.findBy(any(), any())).thenReturn(Mono.just(book)); - Consumer tester = (handler) -> { - Mono outputMono = handler.handleRequest(input("{ bookById(id: 1) {name}}")); - + Consumer tester = setup -> { + Mono outputMono = setup.toWebGraphQlHandler().handleRequest(input("{ bookById(id: 1) {name}}")); Book actualBook = GraphQlResponse.from(outputMono).toEntity("bookById", Book.class); + assertThat(actualBook.getName()).isEqualTo(book.getName()); }; // explicit wiring - tester.accept(initHandler("bookById", QuerydslDataFetcher.builder(mockRepository).single())); + tester.accept(graphQlSetup("bookById", QuerydslDataFetcher.builder(mockRepository).single())); // auto registration - tester.accept(initHandler(builder -> {}, null, mockRepository)); + tester.accept(graphQlSetup(mockRepository)); } @Test @@ -211,8 +209,8 @@ class QuerydslDataFetcherTests { Book book2 = new Book(53L, "Breaking Bad", new Author(0L, "", "Heisenberg")); when(mockRepository.findBy(any(), any())).thenReturn(Flux.just(book1, book2)); - Consumer tester = (handler) -> { - Mono outputMono = handler.handleRequest(input("{ books {name}}")); + Consumer tester = setup -> { + Mono outputMono = setup.toWebGraphQlHandler().handleRequest(input("{ books {name}}")); List names = GraphQlResponse.from(outputMono).toList("books", Book.class) .stream().map(Book::getName).collect(Collectors.toList()); @@ -221,10 +219,37 @@ class QuerydslDataFetcherTests { }; // explicit wiring - tester.accept(initHandler("books", QuerydslDataFetcher.builder(mockRepository).many())); + tester.accept(graphQlSetup("books", QuerydslDataFetcher.builder(mockRepository).many())); // auto registration - tester.accept(initHandler(builder -> {}, null, mockRepository)); + tester.accept(graphQlSetup(mockRepository)); + } + + static GraphQlSetup graphQlSetup(String fieldName, DataFetcher fetcher) { + return initGraphQlSetup(null, null).queryFetcher(fieldName, fetcher); + } + + static GraphQlSetup graphQlSetup(@Nullable QuerydslPredicateExecutor executor) { + return initGraphQlSetup(executor, null); + } + + static GraphQlSetup graphQlSetup(@Nullable ReactiveQuerydslPredicateExecutor executor) { + return initGraphQlSetup(null, executor); + } + + private static GraphQlSetup initGraphQlSetup( + @Nullable QuerydslPredicateExecutor executor, + @Nullable ReactiveQuerydslPredicateExecutor reactiveExecutor) { + + GraphQLTypeVisitor visitor = QuerydslDataFetcher.registrationTypeVisitor( + (executor != null ? Collections.singletonList(executor) : Collections.emptyList()), + (reactiveExecutor != null ? Collections.singletonList(reactiveExecutor) : Collections.emptyList())); + + return GraphQlSetup.schemaResource(BookSource.schema).typeVisitor(visitor); + } + + private WebInput input(String query) { + return new WebInput(URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), null, "1"); } @@ -233,52 +258,12 @@ class QuerydslDataFetcherTests { } + @GraphQlRepository interface ReactiveMockRepository extends Repository, ReactiveQuerydslPredicateExecutor { } - static WebGraphQlHandler initHandler(String fieldName, DataFetcher fetcher) { - return initHandler(fieldName, fetcher, null); - } - - static WebGraphQlHandler initHandler( - String fieldName, DataFetcher fetcher, @Nullable QuerydslPredicateExecutor executor) { - - return initHandler( - GraphQlTestUtils.graphQlSource(BookSource.schema, "Query", fieldName, fetcher), - executor, null); - } - - static WebGraphQlHandler initHandler( - RuntimeWiringConfigurer configurer, - @Nullable QuerydslPredicateExecutor executor, - @Nullable ReactiveQuerydslPredicateExecutor reactiveExecutor) { - - return initHandler( - GraphQlTestUtils.graphQlSource(BookSource.schema, configurer), - executor, - reactiveExecutor); - } - - private static WebGraphQlHandler initHandler( - GraphQlSource.Builder sourceBuilder, - @Nullable QuerydslPredicateExecutor executor, - @Nullable ReactiveQuerydslPredicateExecutor reactiveExecutor) { - - GraphQLTypeVisitor visitor = QuerydslDataFetcher.registrationTypeVisitor( - (executor != null ? Collections.singletonList(executor) : Collections.emptyList()), - (reactiveExecutor != null ? Collections.singletonList(reactiveExecutor) : Collections.emptyList())); - - GraphQlSource source = sourceBuilder.typeVisitors(Collections.singletonList(visitor)).build(); - ExecutionGraphQlService service = new ExecutionGraphQlService(source); - return WebGraphQlHandler.builder(service).build(); - } - - private WebInput input(String query) { - return new WebInput(URI.create("/"), new HttpHeaders(), Collections.singletonMap("query", query), null, "1"); - } - interface BookProjection { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java index 4fe3041b..7425bb44 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/BatchLoadingTests.java @@ -29,7 +29,8 @@ import org.springframework.graphql.Author; import org.springframework.graphql.Book; import org.springframework.graphql.BookSource; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.GraphQlTestUtils; +import org.springframework.graphql.GraphQlService; +import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.RequestInput; import static org.assertj.core.api.Assertions.assertThat; @@ -59,20 +60,21 @@ public class BatchLoadingTests { this.registry.forTypePair(Long.class, Author.class) .registerBatchLoader((ids, env) -> Flux.fromIterable(ids).map(BookSource::getAuthor)); - ExecutionGraphQlService service = initExecutionGraphQlService(wiring -> { - wiring.type("Query", builder -> builder.dataFetcher("booksByCriteria", env -> { - Map criteria = env.getArgument("criteria"); - String authorName = (String) criteria.get("author"); - return BookSource.findBooksByAuthor(authorName).stream() - .map(book -> new Book(book.getId(), book.getName(), book.getAuthorId())) - .collect(Collectors.toList()); - })); - wiring.type("Book", builder -> builder.dataFetcher("author", env -> { - Book book = env.getSource(); - DataLoader dataLoader = env.getDataLoader(Author.class.getName()); - return dataLoader.load(book.getAuthorId()); - })); - }); + GraphQlService service = GraphQlSetup.schemaResource(BookSource.schema) + .queryFetcher("booksByCriteria", env -> { + Map criteria = env.getArgument("criteria"); + String authorName = (String) criteria.get("author"); + return BookSource.findBooksByAuthor(authorName).stream() + .map(book -> new Book(book.getId(), book.getName(), book.getAuthorId())) + .collect(Collectors.toList()); + }) + .dataFetcher("Book", "author", env -> { + Book book = env.getSource(); + DataLoader dataLoader = env.getDataLoader(Author.class.getName()); + return dataLoader.load(book.getAuthorId()); + }) + .dataLoaders(this.registry) + .toGraphQlService(); Mono resultMono = service.execute(new RequestInput(query, null, null, null)); @@ -85,11 +87,4 @@ public class BatchLoadingTests { assertThat(author.getLastName()).isEqualTo("Orwell"); } - private ExecutionGraphQlService initExecutionGraphQlService(RuntimeWiringConfigurer configurer) { - GraphQlSource source = GraphQlTestUtils.graphQlSource(BookSource.schema, configurer).build(); - ExecutionGraphQlService service = new ExecutionGraphQlService(source); - service.addDataLoaderRegistrar(this.registry); - return service; - } - } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java index fddbb435..aae4d1d8 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ClassNameTypeResolverTests.java @@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.GraphQlTestUtils; +import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.RequestInput; import static org.assertj.core.api.Assertions.assertThat; @@ -64,13 +64,11 @@ public class ClassNameTypeResolverTests { "}" + "union Sighting = Bird | Mammal | Plant | Vegetable "; + private final GraphQlSetup graphQlSetup = GraphQlSetup.schemaContent(schema); + @Test void typeResolutionViaSuperHierarchy() { - - GraphQlSource graphQlSource = - GraphQlTestUtils.graphQlSource(schema, "Query", "animals", env -> animalList).build(); - String query = "" + "query Animals {" + " animals {" + @@ -85,7 +83,8 @@ public class ClassNameTypeResolverTests { " }" + "}"; - Mono resultMono = new ExecutionGraphQlService(graphQlSource) + Mono resultMono = graphQlSetup.queryFetcher("animals", env -> animalList) + .toGraphQlService() .execute(new RequestInput(query, null, null, null)); GraphQlResponse response = GraphQlResponse.from(resultMono); @@ -107,15 +106,6 @@ public class ClassNameTypeResolverTests { @Test void typeResolutionViaMapping() { - - ClassNameTypeResolver typeResolver = new ClassNameTypeResolver(); - typeResolver.addMapping(Tree.class, "Plant"); - - GraphQlSource graphQlSource = - GraphQlTestUtils.graphQlSource(schema, "Query", "sightings", env -> animalAndPlantList) - .defaultTypeResolver(typeResolver) - .build(); - String query = "" + "query Sightings {" + " sightings {" + @@ -132,10 +122,15 @@ public class ClassNameTypeResolverTests { " }" + "}"; - Mono resultMono = new ExecutionGraphQlService(graphQlSource) + ClassNameTypeResolver typeResolver = new ClassNameTypeResolver(); + typeResolver.addMapping(Tree.class, "Plant"); + + Mono result = graphQlSetup.queryFetcher("sightings", env -> animalAndPlantList) + .typeResolver(typeResolver) + .toGraphQlService() .execute(new RequestInput(query, null, null, null)); - GraphQlResponse response = GraphQlResponse.from(resultMono); + GraphQlResponse response = GraphQlResponse.from(result); for (int i = 0; i < animalAndPlantList.size(); i++) { Object sighting = animalAndPlantList.get(i); if (sighting instanceof Animal) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java index 241a88f3..71c5e4e9 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ContextDataFetcherDecoratorTests.java @@ -22,7 +22,6 @@ import java.util.List; import graphql.ExecutionInput; import graphql.ExecutionResult; import graphql.GraphQL; -import graphql.schema.DataFetcher; import org.junit.jupiter.api.Test; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @@ -31,7 +30,7 @@ import reactor.util.context.Context; import reactor.util.context.ContextView; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.GraphQlTestUtils; +import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.TestThreadLocalAccessor; import static org.assertj.core.api.Assertions.assertThat; @@ -44,12 +43,13 @@ public class ContextDataFetcherDecoratorTests { @Test void monoDataFetcher() throws Exception { - GraphQL graphQl = initGraphQl( - "type Query { greeting: String }", - "Query", "greeting", (env) -> Mono.deferContextual((context) -> { - Object name = context.get("name"); - return Mono.delay(Duration.ofMillis(50)).map((aLong) -> "Hello " + name); - })); + GraphQL graphQl = GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", (env) -> + Mono.deferContextual((context) -> { + Object name = context.get("name"); + return Mono.delay(Duration.ofMillis(50)).map((aLong) -> "Hello " + name); + })) + .toGraphQl(); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }").build(); ReactorContextManager.setReactorContext(Context.of("name", "007"), input); @@ -62,33 +62,34 @@ public class ContextDataFetcherDecoratorTests { @Test void fluxDataFetcher() throws Exception { - GraphQL graphQl = initGraphQl( - "type Query { greetings: [String] }", - "Query", "greetings", - (env) -> Mono.delay(Duration.ofMillis(50)) - .flatMapMany((aLong) -> Flux.deferContextual((context) -> { - String name = context.get("name"); - return Flux.just("Hi", "Bonjour", "Hola").map((s) -> s + " " + name); - }))); + GraphQL graphQl = GraphQlSetup.schemaContent("type Query { greetings: [String] }") + .queryFetcher("greetings", (env) -> + Mono.delay(Duration.ofMillis(50)) + .flatMapMany((aLong) -> Flux.deferContextual((context) -> { + String name = context.get("name"); + return Flux.just("Hi", "Bonjour", "Hola").map((s) -> s + " " + name); + }))) + .toGraphQl(); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greetings }").build(); ReactorContextManager.setReactorContext(Context.of("name", "007"), input); ExecutionResult result = graphQl.executeAsync(input).get(); - List data = GraphQlResponse.from(result).toList("greetings", String.class);; + List data = GraphQlResponse.from(result).toList("greetings", String.class); assertThat(data).containsExactly("Hi 007", "Bonjour 007", "Hola 007"); } @Test void fluxDataFetcherSubscription() throws Exception { - GraphQL graphQl = initGraphQl( - "type Query { greeting: String } type Subscription { greetings: String }", - "Subscription", "greetings", (env) -> Mono.delay(Duration.ofMillis(50)) - .flatMapMany((aLong) -> Flux.deferContextual((context) -> { - String name = context.get("name"); - return Flux.just("Hi", "Bonjour", "Hola").map((s) -> s + " " + name); - }))); + GraphQL graphQl = GraphQlSetup.schemaContent("type Query { greeting: String } type Subscription { greetings: String }") + .subscriptionFetcher("greetings", (env) -> + Mono.delay(Duration.ofMillis(50)) + .flatMapMany((aLong) -> Flux.deferContextual((context) -> { + String name = context.get("name"); + return Flux.just("Hi", "Bonjour", "Hola").map((s) -> s + " " + name); + }))) + .toGraphQl(); ExecutionInput input = ExecutionInput.newExecutionInput().query("subscription { greetings }").build(); ReactorContextManager.setReactorContext(Context.of("name", "007"), input); @@ -109,9 +110,9 @@ public class ContextDataFetcherDecoratorTests { nameThreadLocal.set("007"); TestThreadLocalAccessor accessor = new TestThreadLocalAccessor<>(nameThreadLocal); try { - GraphQL graphQl = initGraphQl( - "type Query { greeting: String }", - "Query", "greeting", (env) -> "Hello " + nameThreadLocal.get()); + GraphQL graphQl = GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", (env) -> "Hello " + nameThreadLocal.get()) + .toGraphQl(); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }").build(); ContextView view = ReactorContextManager.extractThreadLocalValues(accessor, Context.empty()); @@ -128,11 +129,4 @@ public class ContextDataFetcherDecoratorTests { } } - private static GraphQL initGraphQl( - String schemaContent, String typeName, String fieldName, DataFetcher fetcher) { - - return GraphQlTestUtils.graphQlSource(schemaContent, typeName, fieldName, fetcher) - .build().graphQl(); - } - } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java index e1e34632..a09b1585 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/execution/ExceptionResolversExceptionHandlerTests.java @@ -32,7 +32,7 @@ import reactor.util.context.Context; import reactor.util.context.ContextView; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.GraphQlTestUtils; +import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.TestThreadLocalAccessor; import static org.assertj.core.api.Assertions.assertThat; @@ -45,7 +45,7 @@ public class ExceptionResolversExceptionHandlerTests { @Test void resolveException() throws Exception { - GraphQL graphQl = initGraphQl((ex, env) -> + GraphQL graphQl = graphQl((ex, env) -> Mono.just(Collections.singletonList( GraphqlErrorBuilder.newError(env) .message("Resolved error: " + ex.getMessage()) @@ -65,7 +65,7 @@ public class ExceptionResolversExceptionHandlerTests { @Test void resolveExceptionWithReactorContext() throws Exception { - GraphQL graphQl = initGraphQl((ex, env) -> + GraphQL graphQl = graphQl((ex, env) -> Mono.deferContextual((view) -> Mono.just(Collections.singletonList( GraphqlErrorBuilder.newError(env) .message("Resolved error: " + ex.getMessage() + ", name=" + view.get("name")) @@ -87,7 +87,7 @@ public class ExceptionResolversExceptionHandlerTests { nameThreadLocal.set("007"); TestThreadLocalAccessor accessor = new TestThreadLocalAccessor<>(nameThreadLocal); try { - GraphQL graphQl = initGraphQl(threadLocalContextAwareExceptionResolver((ex, env) -> + GraphQL graphQl = graphQl(threadLocalContextAwareResolver((ex, env) -> GraphqlErrorBuilder.newError(env) .message("Resolved error: " + ex.getMessage() + ", name=" + nameThreadLocal.get()) .errorType(ErrorType.BAD_REQUEST) @@ -111,7 +111,7 @@ public class ExceptionResolversExceptionHandlerTests { @Test void unresolvedException() throws Exception { - GraphQL graphQl = initGraphQl((exception, environment) -> Mono.empty()); + GraphQL graphQl = graphQl((exception, environment) -> Mono.empty()); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }").build(); ExecutionResult result = graphQl.executeAsync(input).get(); @@ -127,7 +127,7 @@ public class ExceptionResolversExceptionHandlerTests { @Test void suppressedException() throws Exception { - GraphQL graphQl = initGraphQl((ex, env) -> Mono.just(Collections.emptyList())); + GraphQL graphQl = graphQl((ex, env) -> Mono.just(Collections.emptyList())); ExecutionInput input = ExecutionInput.newExecutionInput().query("{ greeting }").build(); ExecutionResult result = graphQl.executeAsync(input).get(); @@ -136,18 +136,16 @@ public class ExceptionResolversExceptionHandlerTests { assertThat(greeting).isNull(); } - private static GraphQL initGraphQl(DataFetcherExceptionResolver exceptionResolver) { - return GraphQlTestUtils.graphQlSource( - "type Query { greeting: String }", - "Query", "greeting", (env) -> { - throw new IllegalArgumentException("Invalid greeting"); - }) - .exceptionResolvers(Collections.singletonList(exceptionResolver)) - .build() - .graphQl(); + private static GraphQL graphQl(DataFetcherExceptionResolver exceptionResolver) { + return GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", (env) -> { + throw new IllegalArgumentException("Invalid greeting"); + }) + .exceptionResolver(exceptionResolver) + .toGraphQl(); } - private static DataFetcherExceptionResolver threadLocalContextAwareExceptionResolver( + private static DataFetcherExceptionResolver threadLocalContextAwareResolver( BiFunction resolver) { DataFetcherExceptionResolverAdapter adapter = new DataFetcherExceptionResolverAdapter() { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/WebGraphQlHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/web/WebGraphQlHandlerTests.java index bff34dc2..cc9c848b 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/WebGraphQlHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/WebGraphQlHandlerTests.java @@ -28,14 +28,11 @@ import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; import org.springframework.graphql.GraphQlResponse; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.GraphQlTestUtils; +import org.springframework.graphql.GraphQlSetup; import org.springframework.graphql.TestThreadLocalAccessor; import org.springframework.graphql.execution.DataFetcherExceptionResolver; import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter; import org.springframework.graphql.execution.ErrorType; -import org.springframework.graphql.execution.ExecutionGraphQlService; -import org.springframework.graphql.execution.GraphQlSource; import org.springframework.http.HttpHeaders; import static org.assertj.core.api.Assertions.assertThat; @@ -50,15 +47,13 @@ public class WebGraphQlHandlerTests { @Test void reactorContextPropagation() { - GraphQlSource graphQlSource = GraphQlTestUtils.graphQlSource( - "type Query { greeting: String }", - "Query", "greeting", (env) -> Mono.deferContextual((context) -> { - Object name = context.get("name"); - return Mono.delay(Duration.ofMillis(50)).map((aLong) -> "Hello " + name); - })).build(); - - GraphQlService service = new ExecutionGraphQlService(graphQlSource); - WebGraphQlHandler handler = WebGraphQlHandler.builder(service).build(); + WebGraphQlHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", (env) -> + Mono.deferContextual((context) -> { + Object name = context.get("name"); + return Mono.delay(Duration.ofMillis(50)).map((aLong) -> "Hello " + name); + })) + .toWebGraphQlHandler(); Mono outputMono = handler.handleRequest(webInput) .contextWrite((context) -> context.put("name", "007")); @@ -69,25 +64,19 @@ public class WebGraphQlHandlerTests { @Test void reactorContextPropagationToExceptionResolver() { - - GraphQlSource graphQlSource = GraphQlTestUtils.graphQlSource( - "type Query { greeting: String }", - "Query", "greeting", (env) -> { - throw new IllegalArgumentException("Invalid greeting"); - }) - .exceptionResolvers(Collections.singletonList( - (ex, env) -> Mono.deferContextual((view) -> Mono.just(Collections.singletonList( + WebGraphQlHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", (env) -> { + throw new IllegalArgumentException("Invalid greeting"); + }) + .exceptionResolver((ex, env) -> Mono.deferContextual((view) -> + Mono.just(Collections.singletonList( GraphqlErrorBuilder.newError(env) .message("Resolved error: " + ex.getMessage() + ", name=" + view.get("name")) .errorType(ErrorType.BAD_REQUEST) - .build()))))) - .build(); + .build())))) + .toWebGraphQlHandler(); - GraphQlService service = new ExecutionGraphQlService(graphQlSource); - WebGraphQlHandler handler = WebGraphQlHandler.builder(service).build(); - - Mono outputMono = handler.handleRequest(webInput) - .contextWrite((context) -> context.put("name", "007")); + Mono outputMono = handler.handleRequest(webInput).contextWrite((cxt) -> cxt.put("name", "007")); GraphQlResponse response = GraphQlResponse.from(outputMono); assertThat(response.errorCount()).isEqualTo(1); @@ -103,17 +92,11 @@ public class WebGraphQlHandlerTests { nameThreadLocal.set("007"); TestThreadLocalAccessor threadLocalAccessor = new TestThreadLocalAccessor<>(nameThreadLocal); try { - GraphQlSource graphQlSource = GraphQlTestUtils.graphQlSource( - "type Query { greeting: String }", - "Query", "greeting", env -> "Hello " + nameThreadLocal.get()) - .build(); - - GraphQlService service = new ExecutionGraphQlService(graphQlSource); - - WebGraphQlHandler handler = WebGraphQlHandler.builder(service) - .interceptor((input, next) -> Mono.delay(Duration.ofMillis(10)).flatMap((aLong) -> next.next(input))) + WebGraphQlHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", env -> "Hello " + nameThreadLocal.get()) + .webInterceptor((input, next) -> Mono.delay(Duration.ofMillis(10)).flatMap((aLong) -> next.next(input))) .threadLocalAccessor(threadLocalAccessor) - .build(); + .toWebGraphQlHandler(); Mono outputMono = handler.handleRequest(webInput); @@ -131,25 +114,18 @@ public class WebGraphQlHandlerTests { nameThreadLocal.set("007"); TestThreadLocalAccessor threadLocalAccessor = new TestThreadLocalAccessor<>(nameThreadLocal); try { - GraphQlSource graphQlSource = GraphQlTestUtils.graphQlSource( - "type Query { greeting: String }", - "Query", "greeting", env -> { + WebGraphQlHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", env -> { throw new IllegalArgumentException("Invalid greeting"); }) - .exceptionResolvers(Collections.singletonList( - threadLocalContextAwareExceptionResolver((ex, env) -> - GraphqlErrorBuilder.newError(env) - .message("Resolved error: " + ex.getMessage() + ", name=" + nameThreadLocal.get()) - .errorType(ErrorType.BAD_REQUEST).build()) - )) - .build(); - - GraphQlService service = new ExecutionGraphQlService(graphQlSource); - - WebGraphQlHandler handler = WebGraphQlHandler.builder(service) - .interceptor((input, next) -> Mono.delay(Duration.ofMillis(10)).flatMap((aLong) -> next.next(input))) + .exceptionResolver(threadLocalContextAwareExceptionResolver((ex, env) -> + GraphqlErrorBuilder.newError(env) + .message("Resolved error: " + ex.getMessage() + ", name=" + nameThreadLocal.get()) + .errorType(ErrorType.BAD_REQUEST).build()) + ) + .webInterceptor((input, next) -> Mono.delay(Duration.ofMillis(10)).flatMap((aLong) -> next.next(input))) .threadLocalAccessor(threadLocalAccessor) - .build(); + .toWebGraphQlHandler(); Mono outputMono = handler.handleRequest(webInput); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/BookTestUtils.java b/spring-graphql/src/test/java/org/springframework/graphql/web/WebSocketHandlerTestSupport.java similarity index 52% rename from spring-graphql/src/test/java/org/springframework/graphql/web/BookTestUtils.java rename to spring-graphql/src/test/java/org/springframework/graphql/web/WebSocketHandlerTestSupport.java index 34c2660e..51e89472 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/BookTestUtils.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/WebSocketHandlerTestSupport.java @@ -16,21 +16,17 @@ package org.springframework.graphql.web; -import java.util.Arrays; - import reactor.core.publisher.Flux; import org.springframework.graphql.BookSource; -import org.springframework.graphql.GraphQlTestUtils; -import org.springframework.graphql.execution.ExecutionGraphQlService; -import org.springframework.graphql.execution.GraphQlSource; +import org.springframework.graphql.GraphQlSetup; -public abstract class BookTestUtils { +public abstract class WebSocketHandlerTestSupport { - public static final String SUBSCRIPTION_ID = "1"; + protected static final String SUBSCRIPTION_ID = "1"; - public static final String BOOK_QUERY = "{" + - "\"id\":\"" + BookTestUtils.SUBSCRIPTION_ID + "\"," + + protected static final String BOOK_QUERY = "{" + + "\"id\":\"" + WebSocketHandlerTestSupport.SUBSCRIPTION_ID + "\"," + "\"type\":\"subscribe\"," + "\"payload\":{\"query\": \"" + " query TestQuery {" + @@ -44,7 +40,7 @@ public abstract class BookTestUtils { " }}\"}" + "}"; - public static final String BOOK_SUBSCRIPTION = "{" + + protected static final String BOOK_SUBSCRIPTION = "{" + "\"id\":\"" + SUBSCRIPTION_ID + "\"," + "\"type\":\"subscribe\"," + "\"payload\":{\"query\": \"" + @@ -59,24 +55,20 @@ public abstract class BookTestUtils { " }}\"}" + "}"; - public static WebGraphQlHandler initWebGraphQlHandler(WebInterceptor... interceptors) { - GraphQlSource source = GraphQlTestUtils.graphQlSource(BookSource.schema, - wiringBuilder -> { - wiringBuilder.type("Query", builder -> builder.dataFetcher("bookById", (env) -> { - Long id = Long.parseLong(env.getArgument("id")); - return BookSource.getBook(id); - })); - wiringBuilder.type("Subscription", builder -> builder.dataFetcher("bookSearch", (env) -> { - String author = env.getArgument("author"); - return Flux.fromIterable(BookSource.books()) - .filter((book) -> book.getAuthor().getFullName().contains(author)); - })); - }).build(); - - return WebGraphQlHandler.builder(new ExecutionGraphQlService(source)) - .interceptors(Arrays.asList(interceptors)) - .build(); + protected WebGraphQlHandler initHandler(WebInterceptor... interceptors) { + return GraphQlSetup.schemaResource(BookSource.schema) + .queryFetcher("bookById", environment -> { + Long id = Long.parseLong(environment.getArgument("id")); + return BookSource.getBook(id); + }) + .subscriptionFetcher("bookSearch", environment -> { + String author = environment.getArgument("author"); + return Flux.fromIterable(BookSource.books()) + .filter((book) -> book.getAuthor().getFullName().contains(author)); + }) + .webInterceptor(interceptors) + .toWebGraphQlHandler(); } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlHttpHandlerTests.java index 8bc21ecb..1ae1cedb 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlHttpHandlerTests.java @@ -20,15 +20,10 @@ import java.util.List; import java.util.Locale; import java.util.Map; -import graphql.schema.DataFetcher; import org.junit.jupiter.api.Test; import reactor.core.publisher.Mono; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.GraphQlTestUtils; -import org.springframework.graphql.execution.ExecutionGraphQlService; -import org.springframework.graphql.execution.GraphQlSource; -import org.springframework.graphql.web.WebGraphQlHandler; +import org.springframework.graphql.GraphQlSetup; import org.springframework.http.codec.EncoderHttpMessageWriter; import org.springframework.http.codec.HttpMessageWriter; import org.springframework.http.codec.json.Jackson2JsonEncoder; @@ -50,9 +45,9 @@ public class GraphQlHttpHandlerTests { @Test void locale() { - GraphQlHttpHandler handler = createHttpHandler( - "type Query { greeting: String }", "Query", "greeting", - (env) -> "Hello in " + env.getLocale()); + GraphQlHttpHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", (env) -> "Hello in " + env.getLocale()) + .toHttpHandlerWebFlux(); MockServerHttpRequest httpRequest = MockServerHttpRequest.post("/").acceptLanguageAsLocales(Locale.FRENCH).build(); @@ -64,14 +59,6 @@ public class GraphQlHttpHandlerTests { .isEqualTo("{\"data\":{\"greeting\":\"Hello in fr\"}}"); } - private GraphQlHttpHandler createHttpHandler( - String schemaContent, String type, String field, DataFetcher dataFetcher) { - - GraphQlSource source = GraphQlTestUtils.graphQlSource(schemaContent, type, field, dataFetcher).build(); - GraphQlService service = new ExecutionGraphQlService(source); - return new GraphQlHttpHandler(WebGraphQlHandler.builder(service).build()); - } - private MockServerHttpResponse handleRequest( MockServerHttpRequest httpRequest, GraphQlHttpHandler handler, Map body) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlWebSocketHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlWebSocketHandlerTests.java index 1d0fbf70..c6a6340b 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlWebSocketHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/webflux/GraphQlWebSocketHandlerTests.java @@ -34,7 +34,7 @@ import reactor.test.StepVerifier; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.core.io.buffer.DefaultDataBufferFactory; -import org.springframework.graphql.web.BookTestUtils; +import org.springframework.graphql.web.WebSocketHandlerTestSupport; import org.springframework.graphql.web.ConsumeOneAndNeverCompleteInterceptor; import org.springframework.graphql.web.WebInterceptor; import org.springframework.graphql.web.WebSocketInterceptor; @@ -49,7 +49,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Unit tests for {@link GraphQlWebSocketHandler}. */ -public class GraphQlWebSocketHandlerTests { +public class GraphQlWebSocketHandlerTests extends WebSocketHandlerTestSupport { private static final Jackson2JsonDecoder decoder = new Jackson2JsonDecoder(); @@ -57,12 +57,12 @@ public class GraphQlWebSocketHandlerTests { void query() { TestWebSocketSession session = handle(Flux.just( toWebSocketMessage("{\"type\":\"connection_init\"}"), - toWebSocketMessage(BookTestUtils.BOOK_QUERY))); + toWebSocketMessage(BOOK_QUERY))); StepVerifier.create(session.getOutput()) .consumeNextWith((message) -> assertMessageType(message, "connection_ack")) .consumeNextWith((message) -> assertThat(decode(message)).hasSize(3) - .containsEntry("id", BookTestUtils.SUBSCRIPTION_ID).containsEntry("type", "next") + .containsEntry("id", SUBSCRIPTION_ID).containsEntry("type", "next") .extractingByKey("payload", as(InstanceOfAssertFactories.map(String.class, Object.class))) .extractingByKey("data", as(InstanceOfAssertFactories.map(String.class, Object.class))) .extractingByKey("bookById", as(InstanceOfAssertFactories.map(String.class, Object.class))) @@ -75,11 +75,11 @@ public class GraphQlWebSocketHandlerTests { void subscription() { TestWebSocketSession session = handle(Flux.just( toWebSocketMessage("{\"type\":\"connection_init\"}"), - toWebSocketMessage(BookTestUtils.BOOK_SUBSCRIPTION))); + toWebSocketMessage(BOOK_SUBSCRIPTION))); BiConsumer bookPayloadAssertion = (message, bookId) -> assertThat(decode(message)) - .hasSize(3).containsEntry("id", BookTestUtils.SUBSCRIPTION_ID).containsEntry("type", "next") + .hasSize(3).containsEntry("id", SUBSCRIPTION_ID).containsEntry("type", "next") .extractingByKey("payload", as(InstanceOfAssertFactories.map(String.class, Object.class))) .extractingByKey("data", as(InstanceOfAssertFactories.map(String.class, Object.class))) .extractingByKey("bookSearch", as(InstanceOfAssertFactories.map(String.class, Object.class))) @@ -97,7 +97,7 @@ public class GraphQlWebSocketHandlerTests { void unauthorizedWithoutMessageType() { TestWebSocketSession session = handle(Flux.just( toWebSocketMessage("{\"type\":\"connection_init\"}"), - toWebSocketMessage("{\"id\":\"" + BookTestUtils.SUBSCRIPTION_ID + "\"}"))); + toWebSocketMessage("{\"id\":\"" + SUBSCRIPTION_ID + "\"}"))); StepVerifier.create(session.getOutput()) .consumeNextWith((message) -> assertMessageType(message, "connection_ack")) @@ -168,7 +168,7 @@ public class GraphQlWebSocketHandlerTests { @Test void unauthorizedWithoutConnectionInit() { - TestWebSocketSession session = handle(Flux.just(toWebSocketMessage(BookTestUtils.BOOK_SUBSCRIPTION))); + TestWebSocketSession session = handle(Flux.just(toWebSocketMessage(BOOK_SUBSCRIPTION))); StepVerifier.create(session.getOutput()).verifyComplete(); StepVerifier.create(session.closeStatus()).expectNext(new CloseStatus(4401, "Unauthorized")).verifyComplete(); @@ -192,7 +192,7 @@ public class GraphQlWebSocketHandlerTests { @Test void connectionInitTimeout() { GraphQlWebSocketHandler handler = new GraphQlWebSocketHandler( - BookTestUtils.initWebGraphQlHandler(), ServerCodecConfigurer.create(), Duration.ofMillis(50)); + initHandler(), ServerCodecConfigurer.create(), Duration.ofMillis(50)); TestWebSocketSession session = new TestWebSocketSession(Flux.empty()); handler.handle(session).block(); @@ -206,8 +206,8 @@ public class GraphQlWebSocketHandlerTests { void subscriptionExists() { Flux messageFlux = Flux.just( toWebSocketMessage("{\"type\":\"connection_init\"}"), - toWebSocketMessage(BookTestUtils.BOOK_SUBSCRIPTION), - toWebSocketMessage(BookTestUtils.BOOK_SUBSCRIPTION)); + toWebSocketMessage(BOOK_SUBSCRIPTION), + toWebSocketMessage(BOOK_SUBSCRIPTION)); TestWebSocketSession session = handle(messageFlux, new ConsumeOneAndNeverCompleteInterceptor()); @@ -216,7 +216,7 @@ public class GraphQlWebSocketHandlerTests { session.getOutput().subscribe((message) -> messages.add(decode(message))); StepVerifier.create(session.closeStatus()) - .expectNext(new CloseStatus(4409, "Subscriber for " + BookTestUtils.SUBSCRIPTION_ID + " already exists")) + .expectNext(new CloseStatus(4409, "Subscriber for " + SUBSCRIPTION_ID + " already exists")) .verifyComplete(); assertThat(messages.size()).isEqualTo(2); @@ -228,18 +228,18 @@ public class GraphQlWebSocketHandlerTests { void clientCompletion() { Sinks.Many input = Sinks.many().unicast().onBackpressureBuffer(); input.tryEmitNext(toWebSocketMessage("{\"type\":\"connection_init\"}")); - input.tryEmitNext(toWebSocketMessage(BookTestUtils.BOOK_SUBSCRIPTION)); + input.tryEmitNext(toWebSocketMessage(BOOK_SUBSCRIPTION)); TestWebSocketSession session = handle(input.asFlux(), new ConsumeOneAndNeverCompleteInterceptor()); - String completeMessage = "{\"id\":\"" + BookTestUtils.SUBSCRIPTION_ID + "\",\"type\":\"complete\"}"; + String completeMessage = "{\"id\":\"" + SUBSCRIPTION_ID + "\",\"type\":\"complete\"}"; StepVerifier.create(session.getOutput()) .consumeNextWith((message) -> assertMessageType(message, "connection_ack")) .consumeNextWith((message) -> assertMessageType(message, "next")) .then(() -> input.tryEmitNext(toWebSocketMessage(completeMessage))) .as("Second subscription with same id is possible only if the first was properly removed") - .then(() -> input.tryEmitNext(toWebSocketMessage(BookTestUtils.BOOK_SUBSCRIPTION))) + .then(() -> input.tryEmitNext(toWebSocketMessage(BOOK_SUBSCRIPTION))) .consumeNextWith((message) -> assertMessageType(message, "next")) .then(() -> input.tryEmitNext(toWebSocketMessage(completeMessage))) .verifyTimeout(Duration.ofMillis(500)); @@ -247,7 +247,7 @@ public class GraphQlWebSocketHandlerTests { private TestWebSocketSession handle(Flux input, WebInterceptor... interceptors) { GraphQlWebSocketHandler handler = new GraphQlWebSocketHandler( - BookTestUtils.initWebGraphQlHandler(interceptors), + initHandler(interceptors), ServerCodecConfigurer.create(), Duration.ofSeconds(60)); @@ -271,7 +271,7 @@ public class GraphQlWebSocketHandlerTests { Map map = decode(message); assertThat(map).containsEntry("type", messageType); if (!messageType.equals("connection_ack")) { - assertThat(map).containsEntry("id", BookTestUtils.SUBSCRIPTION_ID); + assertThat(map).containsEntry("id", SUBSCRIPTION_ID); } } diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlHttpHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlHttpHandlerTests.java index ac3e4a3c..fe3118b0 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlHttpHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlHttpHandlerTests.java @@ -23,15 +23,10 @@ import java.util.Locale; import javax.servlet.ServletException; -import graphql.schema.DataFetcher; import org.junit.jupiter.api.Test; import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.graphql.GraphQlService; -import org.springframework.graphql.GraphQlTestUtils; -import org.springframework.graphql.execution.ExecutionGraphQlService; -import org.springframework.graphql.execution.GraphQlSource; -import org.springframework.graphql.web.WebGraphQlHandler; +import org.springframework.graphql.GraphQlSetup; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.mock.web.MockHttpServletRequest; @@ -54,8 +49,9 @@ public class GraphQlHttpHandlerTests { @Test void locale() throws Exception { - GraphQlHttpHandler handler = createHttpHandler( - "type Query { greeting: String }", "Query", "greeting", (env) -> "Hello in " + env.getLocale()); + GraphQlHttpHandler handler = GraphQlSetup.schemaContent("type Query { greeting: String }") + .queryFetcher("greeting", (env) -> "Hello in " + env.getLocale()) + .toHttpHandler(); MockHttpServletRequest servletRequest = new MockHttpServletRequest("POST", "/"); servletRequest.setContentType("application/json"); @@ -74,14 +70,6 @@ public class GraphQlHttpHandlerTests { } } - private GraphQlHttpHandler createHttpHandler( - String schemaContent, String type, String field, DataFetcher dataFetcher) { - - GraphQlSource source = GraphQlTestUtils.graphQlSource(schemaContent, type, field, dataFetcher).build(); - GraphQlService service = new ExecutionGraphQlService(source); - return new GraphQlHttpHandler(WebGraphQlHandler.builder(service).build()); - } - private MockHttpServletResponse handleRequest( MockHttpServletRequest servletRequest, GraphQlHttpHandler handler) throws ServletException, IOException { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlWebSocketHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlWebSocketHandlerTests.java index a07292de..52d1701e 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlWebSocketHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/web/webmvc/GraphQlWebSocketHandlerTests.java @@ -29,11 +29,10 @@ import java.util.function.Consumer; import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; -import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; -import org.springframework.graphql.web.BookTestUtils; +import org.springframework.graphql.web.WebSocketHandlerTestSupport; import org.springframework.graphql.web.ConsumeOneAndNeverCompleteInterceptor; import org.springframework.graphql.web.WebInterceptor; import org.springframework.graphql.web.WebSocketInterceptor; @@ -51,7 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat; /** * Unit tests for {@link GraphQlWebSocketHandler}. */ -public class GraphQlWebSocketHandlerTests { +public class GraphQlWebSocketHandlerTests extends WebSocketHandlerTestSupport { private static final HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); @@ -63,12 +62,12 @@ public class GraphQlWebSocketHandlerTests { void query() throws Exception { handle(this.handler, new TextMessage("{\"type\":\"connection_init\"}"), - new TextMessage(BookTestUtils.BOOK_QUERY)); + new TextMessage(BOOK_QUERY)); StepVerifier.create(this.session.getOutput()) .consumeNextWith((message) -> assertMessageType(message, "connection_ack")) .consumeNextWith((message) -> assertThat(decode(message)).hasSize(3) - .containsEntry("id", BookTestUtils.SUBSCRIPTION_ID).containsEntry("type", "next") + .containsEntry("id", SUBSCRIPTION_ID).containsEntry("type", "next") .extractingByKey("payload", as(InstanceOfAssertFactories.map(String.class, Object.class))) .extractingByKey("data", as(InstanceOfAssertFactories.map(String.class, Object.class))) .extractingByKey("bookById", as(InstanceOfAssertFactories.map(String.class, Object.class))) @@ -80,12 +79,11 @@ public class GraphQlWebSocketHandlerTests { @Test void subscription() throws Exception { - handle(this.handler, new TextMessage("{\"type\":\"connection_init\"}"), - new TextMessage(BookTestUtils.BOOK_SUBSCRIPTION)); + handle(this.handler, new TextMessage("{\"type\":\"connection_init\"}"), new TextMessage(BOOK_SUBSCRIPTION)); BiConsumer, String> bookPayloadAssertion = (message, bookId) -> assertThat(decode(message)) - .hasSize(3).containsEntry("id", BookTestUtils.SUBSCRIPTION_ID).containsEntry("type", "next") + .hasSize(3).containsEntry("id", SUBSCRIPTION_ID).containsEntry("type", "next") .extractingByKey("payload", as(InstanceOfAssertFactories.map(String.class, Object.class))) .extractingByKey("data", as(InstanceOfAssertFactories.map(String.class, Object.class))) .extractingByKey("bookSearch", as(InstanceOfAssertFactories.map(String.class, Object.class))) @@ -104,7 +102,7 @@ public class GraphQlWebSocketHandlerTests { void unauthorizedWithoutMessageType() throws Exception { handle(this.handler, new TextMessage("{\"type\":\"connection_init\"}"), - new TextMessage("{\"id\":\"" + BookTestUtils.SUBSCRIPTION_ID + "\"}")); + new TextMessage("{\"id\":\"" + SUBSCRIPTION_ID + "\"}")); // No message type StepVerifier.create(this.session.getOutput()) @@ -173,7 +171,7 @@ public class GraphQlWebSocketHandlerTests { @Test void unauthorizedWithoutConnectionInit() throws Exception { - handle(this.handler, new TextMessage(BookTestUtils.BOOK_SUBSCRIPTION)); + handle(this.handler, new TextMessage(BOOK_SUBSCRIPTION)); StepVerifier.create(this.session.getOutput()).verifyComplete(); assertThat(this.session.getCloseStatus()).isEqualTo(new CloseStatus(4401, "Unauthorized")); @@ -194,9 +192,7 @@ public class GraphQlWebSocketHandlerTests { @Test void connectionInitTimeout() { - GraphQlWebSocketHandler handler = new GraphQlWebSocketHandler( - BookTestUtils.initWebGraphQlHandler(), converter, Duration.ofMillis(50)); - + GraphQlWebSocketHandler handler = new GraphQlWebSocketHandler(initHandler(), converter, Duration.ofMillis(50)); handler.afterConnectionEstablished(this.session); StepVerifier.create(this.session.closeStatus()) @@ -208,15 +204,15 @@ public class GraphQlWebSocketHandlerTests { void subscriptionExists() throws Exception { handle(initWebSocketHandler(new ConsumeOneAndNeverCompleteInterceptor()), new TextMessage("{\"type\":\"connection_init\"}"), - new TextMessage(BookTestUtils.BOOK_SUBSCRIPTION), - new TextMessage(BookTestUtils.BOOK_SUBSCRIPTION)); + new TextMessage(BOOK_SUBSCRIPTION), + new TextMessage(BOOK_SUBSCRIPTION)); // Collect messages until session closed List> messages = new ArrayList<>(); this.session.getOutput().subscribe((message) -> messages.add(decode(message))); StepVerifier.create(this.session.closeStatus()) - .expectNext(new CloseStatus(4409, "Subscriber for " + BookTestUtils.SUBSCRIPTION_ID + " already exists")) + .expectNext(new CloseStatus(4409, "Subscriber for " + SUBSCRIPTION_ID + " already exists")) .verifyComplete(); assertThat(messages.size()).isEqualTo(2); @@ -230,9 +226,9 @@ public class GraphQlWebSocketHandlerTests { handle(handler, new TextMessage("{\"type\":\"connection_init\"}"), - new TextMessage(BookTestUtils.BOOK_SUBSCRIPTION)); + new TextMessage(BOOK_SUBSCRIPTION)); - String completeMessage = "{\"id\":\"" + BookTestUtils.SUBSCRIPTION_ID + "\",\"type\":\"complete\"}"; + String completeMessage = "{\"id\":\"" + SUBSCRIPTION_ID + "\",\"type\":\"complete\"}"; Consumer messageSender = (body) -> { try { handler.handleTextMessage(this.session, new TextMessage(body)); @@ -247,7 +243,7 @@ public class GraphQlWebSocketHandlerTests { .consumeNextWith((message) -> assertMessageType(message, "next")) .then(() -> messageSender.accept(completeMessage)) .as("Second subscription with same id is possible only if the first was properly removed") - .then(() -> messageSender.accept(BookTestUtils.BOOK_SUBSCRIPTION)) + .then(() -> messageSender.accept(BOOK_SUBSCRIPTION)) .consumeNextWith((message) -> assertMessageType(message, "next")) .then(() -> messageSender.accept(completeMessage)) .verifyTimeout(Duration.ofMillis(500)); @@ -262,8 +258,7 @@ public class GraphQlWebSocketHandlerTests { private GraphQlWebSocketHandler initWebSocketHandler(WebInterceptor... interceptors) { try { - return new GraphQlWebSocketHandler( - BookTestUtils.initWebGraphQlHandler(interceptors), converter, Duration.ofSeconds(60)); + return new GraphQlWebSocketHandler(initHandler(interceptors), converter, Duration.ofSeconds(60)); } catch (Exception ex) { throw new IllegalStateException(ex); @@ -274,7 +269,7 @@ public class GraphQlWebSocketHandlerTests { Map map = decode(message, Map.class); assertThat(map).containsEntry("type", messageType); if (!messageType.equals("connection_ack")) { - assertThat(map).containsEntry("id", BookTestUtils.SUBSCRIPTION_ID); + assertThat(map).containsEntry("id", SUBSCRIPTION_ID); } }