diff --git a/example-graphql-subscription/build.gradle b/example-graphql-subscription/build.gradle index 3f028f41..527cdade 100644 --- a/example-graphql-subscription/build.gradle +++ b/example-graphql-subscription/build.gradle @@ -3,6 +3,7 @@ apply plugin: "org.springframework.boot" dependencies { implementation(project(":graphql-spring-boot-starter")) implementation(project(":graphiql-spring-boot-starter")) + implementation(project(":playground-spring-boot-starter")) implementation "com.graphql-java-kickstart:graphql-java-tools:$LIB_GRAPHQL_JAVA_TOOLS_VER" implementation "io.reactivex.rxjava2:rxjava" diff --git a/example-webflux/build.gradle b/example-webflux/build.gradle index 64556854..59cbfa99 100644 --- a/example-webflux/build.gradle +++ b/example-webflux/build.gradle @@ -23,6 +23,7 @@ dependencies { implementation(project(":graphql-kickstart-spring-boot-starter-webflux")) implementation(project(":graphql-kickstart-spring-boot-starter-tools")) implementation(project(":voyager-spring-boot-starter")) + implementation(project(":playground-spring-boot-starter")) implementation("org.springframework.boot:spring-boot-starter-webflux:$LIB_SPRING_BOOT_VER") implementation("org.springframework.boot:spring-boot-starter-actuator:$LIB_SPRING_BOOT_VER") diff --git a/playground-spring-boot-autoconfigure/build.gradle b/playground-spring-boot-autoconfigure/build.gradle index 9083b867..4803fb78 100644 --- a/playground-spring-boot-autoconfigure/build.gradle +++ b/playground-spring-boot-autoconfigure/build.gradle @@ -20,13 +20,17 @@ dependencies{ annotationProcessor "org.springframework.boot:spring-boot-configuration-processor" implementation "org.springframework.boot:spring-boot-autoconfigure" - implementation "org.springframework.boot:spring-boot-starter-web" + compileOnly "org.springframework.boot:spring-boot-starter-web" + compileOnly "org.springframework.boot:spring-boot-starter-webflux" + compileOnly "org.springframework.boot:spring-boot-starter-security" implementation "org.springframework.boot:spring-boot-starter-thymeleaf" implementation "org.springframework.boot:spring-boot-starter-validation" testImplementation "org.springframework.boot:spring-boot-starter-web" + testImplementation "org.springframework.boot:spring-boot-starter-webflux" testImplementation "org.springframework.boot:spring-boot-starter-test" testImplementation "org.springframework.boot:spring-boot-starter-security" + testImplementation "org.springframework.security:spring-security-test" testImplementation "org.jsoup:jsoup:$LIB_JSOUP_VER" } diff --git a/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundAutoConfiguration.java b/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundAutoConfiguration.java index 6a724b0a..d560c159 100644 --- a/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundAutoConfiguration.java +++ b/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundAutoConfiguration.java @@ -1,23 +1,20 @@ package graphql.kickstart.playground.boot; import com.fasterxml.jackson.databind.ObjectMapper; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import org.springframework.web.servlet.DispatcherServlet; @Configuration @ConditionalOnWebApplication -@ConditionalOnClass(DispatcherServlet.class) @EnableConfigurationProperties(PlaygroundPropertiesConfiguration.class) public class PlaygroundAutoConfiguration { @Bean @ConditionalOnProperty(value = "graphql.playground.enabled", havingValue = "true", matchIfMissing = true) - PlaygroundController playgroundController(final PlaygroundPropertiesConfiguration playgroundPropertiesConfiguration, + public PlaygroundController playgroundController(final PlaygroundPropertiesConfiguration playgroundPropertiesConfiguration, final ObjectMapper objectMapper) { return new PlaygroundController(playgroundPropertiesConfiguration, objectMapper); } diff --git a/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundController.java b/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundController.java index 4b58a9ff..c6e3c111 100644 --- a/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundController.java +++ b/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundController.java @@ -5,10 +5,12 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestAttribute; -import javax.servlet.http.HttpServletRequest; import java.nio.file.Paths; +import static java.util.Objects.nonNull; + @Controller @RequiredArgsConstructor public class PlaygroundController { @@ -23,13 +25,14 @@ public class PlaygroundController { private static final String FAVICON_URL_ATTRIBUTE_NAME = "faviconUrl"; private static final String SCRIPT_URL_ATTRIBUTE_NAME = "scriptUrl"; private static final String LOGO_URL_ATTRIBUTE_NAME = "logoUrl"; + private static final String _CSRF = "_csrf"; private final PlaygroundPropertiesConfiguration propertiesConfiguration; private final ObjectMapper objectMapper; @GetMapping("${graphql.playground.mapping:/playground}") - public String playground(final Model model, final HttpServletRequest request) { + public String playground(final Model model, final @RequestAttribute(value = _CSRF, required = false) Object csrf) { if (propertiesConfiguration.getPlayground().getCdn().isEnabled()) { setCdnUrls(model); } else { @@ -37,7 +40,9 @@ public String playground(final Model model, final HttpServletRequest request) { } model.addAttribute("pageTitle", propertiesConfiguration.getPlayground().getPageTitle()); model.addAttribute("properties", objectMapper.valueToTree(propertiesConfiguration.getPlayground())); - model.addAttribute("_csrf", request.getAttribute("_csrf")); + if (nonNull(csrf)) { + model.addAttribute(_CSRF, csrf); + } return "playground"; } diff --git a/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundWebFluxAutoConfiguration.java b/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundWebFluxAutoConfiguration.java new file mode 100644 index 00000000..7a55a166 --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundWebFluxAutoConfiguration.java @@ -0,0 +1,58 @@ +package graphql.kickstart.playground.boot; + +import lombok.RequiredArgsConstructor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; +import org.springframework.core.io.ClassPathResource; +import org.springframework.web.reactive.config.ViewResolverRegistry; +import org.springframework.web.reactive.config.WebFluxConfigurer; +import org.springframework.web.reactive.function.server.RouterFunction; +import org.springframework.web.reactive.function.server.RouterFunctions; +import org.springframework.web.reactive.function.server.ServerResponse; +import org.thymeleaf.spring5.SpringWebFluxTemplateEngine; +import org.thymeleaf.spring5.view.reactive.ThymeleafReactiveViewResolver; +import org.thymeleaf.templatemode.TemplateMode; +import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver; + +import java.nio.charset.StandardCharsets; + +@Configuration +@Import(PlaygroundWebFluxControllerAdvice.class) +@ConditionalOnClass(WebFluxConfigurer.class) +@ConditionalOnProperty(value = "graphql.playground.enabled", havingValue = "true", matchIfMissing = true) +@RequiredArgsConstructor +public class PlaygroundWebFluxAutoConfiguration implements WebFluxConfigurer { + + private final ApplicationContext applicationContext; + + @Bean + public RouterFunction playgroundStaticFilesRouter() { + return RouterFunctions.resources("/vendor/playground/**", new ClassPathResource("static/vendor/playground/")); + } + + @Override + public void configureViewResolvers(final ViewResolverRegistry registry) { + final ClassLoaderTemplateResolver templateResolver = new ClassLoaderTemplateResolver(); + templateResolver.setPrefix("templates/"); + templateResolver.setSuffix(".html"); + templateResolver.setTemplateMode(TemplateMode.HTML); + templateResolver.setCharacterEncoding(StandardCharsets.UTF_8.displayName()); + templateResolver.setOrder(1); + templateResolver.setCheckExistence(true); + final SpringWebFluxTemplateEngine springWebFluxTemplateEngine = new SpringWebFluxTemplateEngine(); + springWebFluxTemplateEngine.setTemplateResolver(templateResolver); + final ThymeleafReactiveViewResolver thymeleafReactiveViewResolver = new ThymeleafReactiveViewResolver(); + thymeleafReactiveViewResolver.setDefaultCharset(StandardCharsets.UTF_8); + thymeleafReactiveViewResolver.setApplicationContext(applicationContext); + thymeleafReactiveViewResolver.setTemplateEngine(springWebFluxTemplateEngine); + thymeleafReactiveViewResolver.setViewNames(new String[] {"playground"}); + registry.viewResolver(thymeleafReactiveViewResolver); + } +} diff --git a/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundWebFluxControllerAdvice.java b/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundWebFluxControllerAdvice.java new file mode 100644 index 00000000..6b69844c --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/main/java/graphql/kickstart/playground/boot/PlaygroundWebFluxControllerAdvice.java @@ -0,0 +1,23 @@ +package graphql.kickstart.playground.boot; + +import lombok.NoArgsConstructor; +import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; +import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; +import org.springframework.security.web.reactive.result.view.CsrfRequestDataValueProcessor; +import org.springframework.security.web.server.csrf.CsrfToken; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.server.ServerWebExchange; +import reactor.core.publisher.Mono; + +@NoArgsConstructor +@ControllerAdvice +@ConditionalOnClass({ CsrfToken.class, CsrfRequestDataValueProcessor.class }) +@ConditionalOnBean(CsrfRequestDataValueProcessor.class) +public class PlaygroundWebFluxControllerAdvice { + + @ModelAttribute(CsrfRequestDataValueProcessor.DEFAULT_CSRF_ATTR_NAME) + public Mono getCsrfToken(final ServerWebExchange exchange) { + return exchange.getAttributeOrDefault(CsrfToken.class.getName(), Mono.empty()); + } +} diff --git a/playground-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories b/playground-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories index 830e9efe..0f00e9a5 100644 --- a/playground-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories +++ b/playground-spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories @@ -1 +1 @@ -org.springframework.boot.autoconfigure.EnableAutoConfiguration=graphql.kickstart.playground.boot.PlaygroundAutoConfiguration +org.springframework.boot.autoconfigure.EnableAutoConfiguration=graphql.kickstart.playground.boot.PlaygroundAutoConfiguration,graphql.kickstart.playground.boot.PlaygroundWebFluxAutoConfiguration diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCdnCustomVersionTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCdnCustomVersionTest.java index 42dba75f..55b06b92 100644 --- a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCdnCustomVersionTest.java +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCdnCustomVersionTest.java @@ -11,14 +11,15 @@ @SpringBootTest(classes = PlaygroundTestConfig.class) @AutoConfigureMockMvc @TestPropertySource("classpath:application-playground-cdn-custom-version-test.properties") -class PlaygroundCdnCustomVersionTest extends PlaygroundResourcesTestBase { +public class PlaygroundCdnCustomVersionTest extends PlaygroundResourcesTestBase { - @Test - void shouldLoadSpecifiedVersionFromCdn() throws Exception { - String LOGO_CDN_PATH = "https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.10/build/logo.png"; - String FAVICON_CDN_PATH = "https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.10/build/favicon.png"; - String SCRIPT_CDN_PATH = "https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.10/build/static/js/middleware.js"; - String CSS_CDN_PATH = "https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.10/build/static/css/index.css"; - testPlaygroundResources(CSS_CDN_PATH, SCRIPT_CDN_PATH, FAVICON_CDN_PATH, LOGO_CDN_PATH); - } + @Test + public void shouldLoadSpecifiedVersionFromCdn() throws Exception { + testPlaygroundResources( + PlaygroundTestHelper.CUSTOM_VERSION_CSS_CDN_PATH, + PlaygroundTestHelper.CUSTOM_VERSION_SCRIPT_CDN_PATH, + PlaygroundTestHelper.CUSTOM_VERSION_FAVICON_CDN_PATH, + PlaygroundTestHelper.CUSTOM_VERSION_LOGO_CDN_PATH + ); + } } diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCdnTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCdnTest.java index 1ee91efa..afc78e4e 100644 --- a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCdnTest.java +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCdnTest.java @@ -11,14 +11,15 @@ @SpringBootTest(classes = PlaygroundTestConfig.class) @AutoConfigureMockMvc @TestPropertySource("classpath:application-playground-cdn-test.properties") -class PlaygroundCdnTest extends PlaygroundResourcesTestBase { +public class PlaygroundCdnTest extends PlaygroundResourcesTestBase { - @Test - void shouldLoadLatestVersionFromCdn() throws Exception { - String LOGO_CDN_PATH = "https://cdn.jsdelivr.net/npm/graphql-playground-react@latest/build/logo.png"; - String FAVICON_CDN_PATH = "https://cdn.jsdelivr.net/npm/graphql-playground-react@latest/build/favicon.png"; - String SCRIPT_CDN_PATH = "https://cdn.jsdelivr.net/npm/graphql-playground-react@latest/build/static/js/middleware.js"; - String CSS_CDN_PATH = "https://cdn.jsdelivr.net/npm/graphql-playground-react@latest/build/static/css/index.css"; - testPlaygroundResources(CSS_CDN_PATH, SCRIPT_CDN_PATH, FAVICON_CDN_PATH, LOGO_CDN_PATH); - } + @Test + public void shouldLoadLatestVersionFromCdn() throws Exception { + testPlaygroundResources( + PlaygroundTestHelper.DEFAULT_CSS_CDN_PATH, + PlaygroundTestHelper.DEFAULT_SCRIPT_CDN_PATH, + PlaygroundTestHelper.DEFAULT_FAVICON_CDN_PATH, + PlaygroundTestHelper.DEFAULT_LOGO_CDN_PATH + ); + } } diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomMappingTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomMappingTest.java index 618bddf5..a6da477c 100644 --- a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomMappingTest.java +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomMappingTest.java @@ -21,19 +21,17 @@ @SpringBootTest(classes = PlaygroundTestConfig.class) @AutoConfigureMockMvc @TestPropertySource("classpath:application-playground-mapping-test.properties") -class PlaygroundCustomMappingTest { +public class PlaygroundCustomMappingTest { - private static final String CONFIGURED_MAPPING = "/test-mapping"; + @Autowired + private MockMvc mockMvc; - @Autowired - private MockMvc mockMvc; - - @Test - void shouldUseTheConfiguredRequestMapping() throws Exception { - mockMvc.perform(get(CONFIGURED_MAPPING)) - .andExpect(status().isOk()) - .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_HTML)) - .andExpect(content().encoding(StandardCharsets.UTF_8.name())) - .andExpect(content().string(not(isEmptyString()))); - } + @Test + public void shouldUseTheConfiguredRequestMapping() throws Exception { + mockMvc.perform(get(PlaygroundTestHelper.CUSTOM_MAPPING)) + .andExpect(status().isOk()) + .andExpect(content().contentTypeCompatibleWith(MediaType.TEXT_HTML)) + .andExpect(content().encoding(StandardCharsets.UTF_8.name())) + .andExpect(content().string(not(isEmptyString()))); + } } diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomStaticPathTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomStaticPathTest.java index a4ef063c..354b3997 100644 --- a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomStaticPathTest.java +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomStaticPathTest.java @@ -11,15 +11,15 @@ @SpringBootTest(classes = PlaygroundTestConfig.class) @AutoConfigureMockMvc @TestPropertySource("classpath:application-playground-custom-static-path.properties") -class PlaygroundCustomStaticPathTest extends PlaygroundResourcesTestBase { +public class PlaygroundCustomStaticPathTest extends PlaygroundResourcesTestBase { - private static final String CUSTOM_CSS_URL = "/custom-static-path/static/css/index.css"; - private static final String CUSTOM_SCRIPT_URL = "/custom-static-path/static/js/middleware.js"; - private static final String CUSTOM_FAVICON_URL = "/custom-static-path/favicon.png"; - private static final String CUSTOM_LOGO_URL = "/custom-static-path/logo.png"; - - @Test - void shouldLoadStaticResourcesFromCustomPath() throws Exception { - testPlaygroundResources(CUSTOM_CSS_URL, CUSTOM_SCRIPT_URL, CUSTOM_FAVICON_URL, CUSTOM_LOGO_URL); - } + @Test + public void shouldLoadStaticResourcesFromCustomPath() throws Exception { + testPlaygroundResources( + PlaygroundTestHelper.CUSTOM_LOCAL_CSS_URL, + PlaygroundTestHelper.CUSTOM_LOCAL_SCRIPT_URL, + PlaygroundTestHelper.CUSTOM_LOCAL_FAVICON_URL, + PlaygroundTestHelper.CUSTOM_LOCAL_LOGO_URL + ); + } } diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomTitleTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomTitleTest.java index 54f081e0..bd57f0c6 100644 --- a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomTitleTest.java +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundCustomTitleTest.java @@ -20,22 +20,19 @@ @SpringBootTest(classes = PlaygroundTestConfig.class) @AutoConfigureMockMvc @TestPropertySource("classpath:application-playground-custom-title.properties") -class PlaygroundCustomTitleTest { +public class PlaygroundCustomTitleTest { - private static final String CUSTOM_TITLE = "My CustomTest Title"; + @Autowired + private MockMvc mockMvc; - @Autowired - private MockMvc mockMvc; + @Test + public void shouldUseTheCustomPageTitle() throws Exception { + final MvcResult mvcResult = mockMvc.perform(get(PlaygroundTestHelper.DEFAULT_PLAYGROUND_ENDPOINT)) + .andExpect(status().isOk()) + .andExpect(model().attribute(PlaygroundTestHelper.PAGE_TITLE_FIELD_NAME, PlaygroundTestHelper.CUSTOM_TITLE)) + .andReturn(); - @Test - void shouldUseTheCustomPageTitle() throws Exception { - final MvcResult mvcResult = mockMvc - .perform(get(PlaygroundTestHelper.DEFAULT_PLAYGROUND_ENDPOINT)) - .andExpect(status().isOk()) - .andExpect(model().attribute(PlaygroundTestHelper.PAGE_TITLE_FIELD_NAME, CUSTOM_TITLE)) - .andReturn(); - - final Document document = Jsoup.parse(mvcResult.getResponse().getContentAsString()); - PlaygroundTestHelper.assertTitle(document, CUSTOM_TITLE); - } + final Document document = Jsoup.parse(mvcResult.getResponse().getContentAsString()); + PlaygroundTestHelper.assertTitle(document, PlaygroundTestHelper.CUSTOM_TITLE); + } } diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundTestConfig.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundTestConfig.java index 7913ce6c..5d1c150b 100644 --- a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundTestConfig.java +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundTestConfig.java @@ -3,12 +3,13 @@ import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration; +import org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; import org.springframework.test.context.ContextConfiguration; -@EnableAutoConfiguration +@EnableAutoConfiguration(exclude = WebFluxAutoConfiguration.class) @EnableWebSecurity @ContextConfiguration(classes = {PlaygroundAutoConfiguration.class, ObjectMapper.class, ThymeleafAutoConfiguration.class}) diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundTestHelper.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundTestHelper.java index acc4a203..0599afbf 100644 --- a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundTestHelper.java +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/PlaygroundTestHelper.java @@ -5,15 +5,41 @@ import static org.assertj.core.api.Assertions.assertThat; -final class PlaygroundTestHelper { - static final String DEFAULT_PLAYGROUND_ENDPOINT = "/playground"; - static final String CSS_URL_FIELD_NAME = "cssUrl"; - static final String SCRIPT_URL_FIELD_NAME = "scriptUrl"; - static final String FAVICON_URL_FIELD_NAME = "faviconUrl"; - static final String LOGO_URL_FIELD_NAME = "logoUrl"; - static final String PAGE_TITLE_FIELD_NAME = "pageTitle"; - - static void assertTitle(final Document document, final String title) { +public final class PlaygroundTestHelper { + + public static final String CUSTOM_LOCAL_CSS_URL = "/custom-static-path/static/css/index.css"; + public static final String CUSTOM_LOCAL_SCRIPT_URL = "/custom-static-path/static/js/middleware.js"; + public static final String CUSTOM_LOCAL_FAVICON_URL = "/custom-static-path/favicon.png"; + public static final String CUSTOM_LOCAL_LOGO_URL = "/custom-static-path/logo.png"; + + public static final String DEFAULT_CSS_CDN_PATH + = "https://cdn.jsdelivr.net/npm/graphql-playground-react@latest/build/static/css/index.css"; + public static final String DEFAULT_SCRIPT_CDN_PATH + = "https://cdn.jsdelivr.net/npm/graphql-playground-react@latest/build/static/js/middleware.js"; + public static final String DEFAULT_FAVICON_CDN_PATH + = "https://cdn.jsdelivr.net/npm/graphql-playground-react@latest/build/favicon.png"; + public static final String DEFAULT_LOGO_CDN_PATH + = "https://cdn.jsdelivr.net/npm/graphql-playground-react@latest/build/logo.png"; + + public static final String CUSTOM_VERSION_CSS_CDN_PATH + = "https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.10/build/static/css/index.css"; + public static final String CUSTOM_VERSION_SCRIPT_CDN_PATH + = "https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.10/build/static/js/middleware.js"; + public static final String CUSTOM_VERSION_FAVICON_CDN_PATH + = "https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.10/build/favicon.png"; + public static final String CUSTOM_VERSION_LOGO_CDN_PATH + = "https://cdn.jsdelivr.net/npm/graphql-playground-react@1.7.10/build/logo.png"; + + public static final String CUSTOM_MAPPING = "/test-mapping"; + public static final String CUSTOM_TITLE = "My CustomTest Title"; + public static final String DEFAULT_PLAYGROUND_ENDPOINT = "/playground"; + public static final String CSS_URL_FIELD_NAME = "cssUrl"; + public static final String SCRIPT_URL_FIELD_NAME = "scriptUrl"; + public static final String FAVICON_URL_FIELD_NAME = "faviconUrl"; + public static final String LOGO_URL_FIELD_NAME = "logoUrl"; + public static final String PAGE_TITLE_FIELD_NAME = "pageTitle"; + + public static void assertTitle(final Document document, final String title) { assertThat(document.select("head title")).extracting(Element::text).containsExactly(title); } @@ -29,7 +55,7 @@ private static void assertFavicon(final Document document, final String faviconU private static void assertLoadingLogo(final Document document, final String logoUrl) { assertThat(document.select(String.format("#root img[src=%s]", logoUrl)).size()).isOne(); } - static void assertStaticResources(final Document document, final String cssUrl, final String scriptUrl, + public static void assertStaticResources(final Document document, final String cssUrl, final String scriptUrl, final String faviconUrl, final String logoUrl) { assertStylesheet(document, cssUrl); assertScript(document, scriptUrl); diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCSRFTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCSRFTest.java new file mode 100644 index 00000000..a99e121e --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCSRFTest.java @@ -0,0 +1,34 @@ +package graphql.kickstart.playground.boot.webflux; + +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.reactive.server.WebTestClient; + +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = PlaygroundWebFluxTestConfig.class) +@AutoConfigureWebTestClient +public class PlaygroundWebFluxCSRFTest { + + @Autowired + private WebTestClient webTestClient; + + @Test + void shouldLoadCSRFData() { + // WHEN + final byte[] actual = webTestClient.get().uri(PlaygroundTestHelper.DEFAULT_PLAYGROUND_ENDPOINT) + .exchange() + .expectStatus().isOk() + .expectBody().returnResult().getResponseBody(); + // THEN + assertThat(actual).isNotNull(); + assertThat(new String(actual, StandardCharsets.UTF_8)) + .contains("let csrf = {\"token\":") + .contains("\"parameterName\":\"_csrf\",\"headerName\":\"X-CSRF-TOKEN\"}"); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCdnTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCdnTest.java new file mode 100644 index 00000000..d9412b62 --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCdnTest.java @@ -0,0 +1,23 @@ +package graphql.kickstart.playground.boot.webflux; + +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; + +@SpringBootTest(classes = PlaygroundWebFluxTestConfig.class) +@AutoConfigureWebTestClient +@TestPropertySource("classpath:application-playground-cdn-test.properties") +public class PlaygroundWebFluxCdnTest extends PlaygroundWebFluxResourcesTestBase { + + @Test + public void shouldLoadLatestVersionFromCdn() { + testPlaygroundResources( + PlaygroundTestHelper.DEFAULT_CSS_CDN_PATH, + PlaygroundTestHelper.DEFAULT_SCRIPT_CDN_PATH, + PlaygroundTestHelper.DEFAULT_FAVICON_CDN_PATH, + PlaygroundTestHelper.DEFAULT_LOGO_CDN_PATH + ); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomCdnVersionTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomCdnVersionTest.java new file mode 100644 index 00000000..0ed385ce --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomCdnVersionTest.java @@ -0,0 +1,23 @@ +package graphql.kickstart.playground.boot.webflux; + +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; + +@SpringBootTest(classes = PlaygroundWebFluxTestConfig.class) +@AutoConfigureWebTestClient +@TestPropertySource("classpath:application-playground-cdn-custom-version-test.properties") +public class PlaygroundWebFluxCustomCdnVersionTest extends PlaygroundWebFluxResourcesTestBase { + + @Test + public void shouldLoadSpecifiedVersionFromCdn() { + testPlaygroundResources( + PlaygroundTestHelper.CUSTOM_VERSION_CSS_CDN_PATH, + PlaygroundTestHelper.CUSTOM_VERSION_SCRIPT_CDN_PATH, + PlaygroundTestHelper.CUSTOM_VERSION_FAVICON_CDN_PATH, + PlaygroundTestHelper.CUSTOM_VERSION_LOGO_CDN_PATH + ); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomMappingTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomMappingTest.java new file mode 100644 index 00000000..ad16bced --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomMappingTest.java @@ -0,0 +1,27 @@ +package graphql.kickstart.playground.boot.webflux; + +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.reactive.server.WebTestClient; + +@SpringBootTest(classes = PlaygroundWebFluxTestConfig.class) +@AutoConfigureWebTestClient +@TestPropertySource("classpath:application-playground-mapping-test.properties") +public class PlaygroundWebFluxCustomMappingTest { + + @Autowired + private WebTestClient webTestClient; + + @Test + public void shouldUseTheConfiguredRequestMapping() { + webTestClient.get().uri(PlaygroundTestHelper.CUSTOM_MAPPING) + .exchange() + .expectStatus().isOk() + .expectHeader().contentTypeCompatibleWith(MediaType.TEXT_HTML); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomStaticPathTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomStaticPathTest.java new file mode 100644 index 00000000..048625b6 --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomStaticPathTest.java @@ -0,0 +1,23 @@ +package graphql.kickstart.playground.boot.webflux; + +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; + +@SpringBootTest(classes = PlaygroundWebFluxTestConfig.class) +@AutoConfigureWebTestClient +@TestPropertySource("classpath:application-playground-custom-static-path.properties") +public class PlaygroundWebFluxCustomStaticPathTest extends PlaygroundWebFluxResourcesTestBase { + + @Test + public void shouldLoadStaticResourcesFromCustomPath() { + testPlaygroundResources( + PlaygroundTestHelper.CUSTOM_LOCAL_CSS_URL, + PlaygroundTestHelper.CUSTOM_LOCAL_SCRIPT_URL, + PlaygroundTestHelper.CUSTOM_LOCAL_FAVICON_URL, + PlaygroundTestHelper.CUSTOM_LOCAL_LOGO_URL + ); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomTitleTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomTitleTest.java new file mode 100644 index 00000000..b02b37d5 --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxCustomTitleTest.java @@ -0,0 +1,40 @@ +package graphql.kickstart.playground.boot.webflux; + +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.web.reactive.server.EntityExchangeResult; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.test.web.servlet.MvcResult; + +import java.nio.charset.StandardCharsets; + +import static graphql.kickstart.playground.boot.PlaygroundTestHelper.CUSTOM_TITLE; +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = PlaygroundWebFluxTestConfig.class) +@AutoConfigureWebTestClient +@TestPropertySource("classpath:application-playground-custom-title.properties") +public class PlaygroundWebFluxCustomTitleTest { + + @Autowired + private WebTestClient webTestClient; + + @Test + public void shouldUseTheCustomPageTitle() { + // WHEN + final byte[] actual = webTestClient.get().uri(PlaygroundTestHelper.DEFAULT_PLAYGROUND_ENDPOINT) + .exchange() + .expectStatus().isOk() + .expectBody().returnResult().getResponseBody(); + // THEN + assertThat(actual).isNotNull(); + final Document document = Jsoup.parse(new String(actual, StandardCharsets.UTF_8)); + PlaygroundTestHelper.assertTitle(document, CUSTOM_TITLE); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxDisabledTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxDisabledTest.java new file mode 100644 index 00000000..3bf12060 --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxDisabledTest.java @@ -0,0 +1,37 @@ +package graphql.kickstart.playground.boot.webflux; + +import graphql.kickstart.playground.boot.PlaygroundController; +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.test.web.reactive.server.WebTestClient; + +import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOfType; + +@SpringBootTest(classes = PlaygroundWebFluxTestConfig.class, properties = "graphql.playground.enabled=false") +@AutoConfigureWebTestClient +public class PlaygroundWebFluxDisabledTest { + + @Autowired + private ApplicationContext applicationContext; + + @Autowired + private WebTestClient webTestClient; + + @Test + public void playgroundShouldNotLoadIfDisabled() { + assertThatExceptionOfType(NoSuchBeanDefinitionException.class) + .isThrownBy(() -> applicationContext.getBean(PlaygroundController.class)); + } + + @Test + public void playgroundEndpointShouldNotExist() { + webTestClient.get().uri(PlaygroundTestHelper.DEFAULT_PLAYGROUND_ENDPOINT) + .exchange() + .expectStatus().isNotFound(); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxEnabledTest.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxEnabledTest.java new file mode 100644 index 00000000..5e9a682f --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxEnabledTest.java @@ -0,0 +1,117 @@ +package graphql.kickstart.playground.boot.webflux; + +import com.fasterxml.jackson.databind.ObjectMapper; +import graphql.kickstart.playground.boot.PlaygroundController; +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.ClassPathResource; +import org.springframework.http.MediaType; +import org.springframework.test.web.reactive.server.WebTestClient; +import org.springframework.util.StreamUtils; +import org.springframework.web.reactive.function.client.ExchangeStrategies; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; + +@SpringBootTest(classes = PlaygroundWebFluxTestConfig.class) +@AutoConfigureWebTestClient +public class PlaygroundWebFluxEnabledTest { + + private static final int MAX_IN_MEMORY_SIZE = 3 * 1024 * 1024; + private static final String DEFAULT_CSS_PATH = "/vendor/playground/static/css/index.css"; + private static final String DEFAULT_CSS_RESOURCE = "/static/vendor/playground/static/css/index.css"; + private static final String DEFAULT_SCRIPT_PATH = "/vendor/playground/static/js/middleware.js"; + private static final String DEFAULT_SCRIPT_RESOURCE = "/static/vendor/playground/static/js/middleware.js"; + private static final String DEFAULT_FAVICON_PATH = "/vendor/playground/favicon.png"; + private static final String DEFAULT_FAVICON_RESOURCE = "/static/vendor/playground/favicon.png"; + private static final String DEFAULT_LOGO_PATH = "/vendor/playground/logo.png"; + private static final String DEFAULT_LOGO_RESOURCE = "/static/vendor/playground/logo.png"; + private static final String DEFAULT_TITLE = "Playground"; + + @Autowired + private ApplicationContext applicationContext; + + @Autowired + private WebTestClient webTestClient; + + @Autowired + private ObjectMapper objectMapper; + + @Test + public void playgroundLoads() { + assertThat(applicationContext.getBean(PlaygroundController.class)).isNotNull(); + } + + @Test + public void playgroundShouldBeAvailableAtDefaultEndpoint() { + // WHEN + final byte[] content = webTestClient.get().uri(PlaygroundTestHelper.DEFAULT_PLAYGROUND_ENDPOINT) + .accept(MediaType.TEXT_HTML) + .acceptCharset(StandardCharsets.UTF_8) + .exchange() + .expectStatus().isOk() + .expectHeader().contentTypeCompatibleWith(MediaType.TEXT_HTML) + .expectBody() + .returnResult() + .getResponseBodyContent(); + // THEN + assertThat(content).isNotNull(); + final Document document = Jsoup.parse(new String(content, StandardCharsets.UTF_8)); + PlaygroundTestHelper.assertTitle(document, DEFAULT_TITLE); + PlaygroundTestHelper.assertStaticResources(document, DEFAULT_CSS_PATH, DEFAULT_SCRIPT_PATH, DEFAULT_FAVICON_PATH, DEFAULT_LOGO_PATH); + } + + @Test + public void defaultCssShouldBeAvailable() throws IOException { + testStaticResource(DEFAULT_CSS_RESOURCE, DEFAULT_CSS_PATH, "text/css"); + } + + @Test + public void defaultScriptShouldBeAvailable() throws Exception { + testStaticResource(DEFAULT_SCRIPT_RESOURCE, DEFAULT_SCRIPT_PATH, "application/javascript"); + } + + @Test + public void defaultFaviconShouldBeAvailable() throws Exception { + testStaticResource(DEFAULT_FAVICON_RESOURCE, DEFAULT_FAVICON_PATH, "image/png"); + } + + @Test + public void defaultLogoShouldBeAvailable() throws Exception { + testStaticResource(DEFAULT_LOGO_RESOURCE, DEFAULT_LOGO_PATH, "image/png"); + } + + private void testStaticResource( + final String resourcePath, + final String urlPath, + final String contentType + ) throws IOException { + // GIVEN + final byte[] expected = StreamUtils.copyToByteArray(new ClassPathResource(resourcePath).getInputStream()); + // WHEN + final byte[] actual = webTestClient + .mutateWith((builder, httpHandlerBuilder, connector) + -> builder.exchangeStrategies(ExchangeStrategies.builder().codecs(configurer + -> configurer + .defaultCodecs() + .maxInMemorySize(MAX_IN_MEMORY_SIZE)) + .build() + ) + ) + .get().uri(urlPath) + .exchange() + .expectStatus().isOk() + .expectHeader().contentTypeCompatibleWith(contentType) + .expectBody().returnResult().getResponseBody(); + // THEN + assertThat(actual).isEqualTo(expected); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxResourcesTestBase.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxResourcesTestBase.java new file mode 100644 index 00000000..28f213d1 --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxResourcesTestBase.java @@ -0,0 +1,35 @@ +package graphql.kickstart.playground.boot.webflux; + +import graphql.kickstart.playground.boot.PlaygroundTestHelper; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.web.reactive.server.WebTestClient; + +import java.nio.charset.StandardCharsets; + +import static org.assertj.core.api.Assertions.assertThat; + +public class PlaygroundWebFluxResourcesTestBase { + + @Autowired + private WebTestClient webTestClient; + + void testPlaygroundResources( + final String cssUrl, + final String scriptUrl, + final String faviconUrl, + final String logoUrl + ) { + // WHEN + final byte[] actual = webTestClient.get().uri(PlaygroundTestHelper.DEFAULT_PLAYGROUND_ENDPOINT) + .exchange() + .expectStatus().isOk() + .expectBody().returnResult().getResponseBody(); + + // THEN + assertThat(actual).isNotNull(); + final Document document = Jsoup.parse(new String(actual, StandardCharsets.UTF_8)); + PlaygroundTestHelper.assertStaticResources(document, cssUrl, scriptUrl, faviconUrl, logoUrl); + } +} diff --git a/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxTestConfig.java b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxTestConfig.java new file mode 100644 index 00000000..16017b71 --- /dev/null +++ b/playground-spring-boot-autoconfigure/src/test/java/graphql/kickstart/playground/boot/webflux/PlaygroundWebFluxTestConfig.java @@ -0,0 +1,23 @@ +package graphql.kickstart.playground.boot.webflux; + +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration; +import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity; +import org.springframework.security.config.web.server.ServerHttpSecurity; +import org.springframework.security.web.server.SecurityWebFilterChain; +import org.springframework.web.reactive.config.EnableWebFlux; + +@EnableWebFlux +@EnableWebFluxSecurity +@SpringBootApplication +@EnableAutoConfiguration(exclude = { WebMvcAutoConfiguration.class, SecurityAutoConfiguration.class } ) +class PlaygroundWebFluxTestConfig { + + @Bean + public SecurityWebFilterChain securityWebFilterChain(final ServerHttpSecurity http) { + return http.authorizeExchange().anyExchange().permitAll().and().build(); + } +}