From c592ee09626cbd781c82204fcad3d99c87c5b1de Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Fri, 9 Sep 2022 17:32:19 +0100 Subject: [PATCH] GraphiQlHandler supports path variables Closes gh-478 --- .../server/webflux/GraphiQlHandler.java | 4 +- .../server/webmvc/GraphiQlHandler.java | 4 +- .../server/webflux/GraphiQlHandlerTests.java | 29 ++++++++++++++- .../server/webmvc/GraphiQlHandlerTests.java | 37 +++++++++++++++++-- 4 files changed, 64 insertions(+), 10 deletions(-) diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphiQlHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphiQlHandler.java index ceec57ea..913fe5f2 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphiQlHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webflux/GraphiQlHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -86,7 +86,7 @@ public class GraphiQlHandler { String wsPathQueryParam = applyContextPath(request, this.graphQlWsPath); builder.queryParam("wsPath", wsPathQueryParam); } - return builder.build(); + return builder.build(request.pathVariables()); } private String applyContextPath(ServerRequest request, String path) { diff --git a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java index c07cea0e..fd03317c 100644 --- a/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java +++ b/spring-graphql/src/main/java/org/springframework/graphql/server/webmvc/GraphiQlHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2020-2021 the original author or authors. + * Copyright 2020-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,7 +85,7 @@ public class GraphiQlHandler { String wsPathQueryParam = applyPathPrefix(request, this.graphQlWsPath); builder.queryParam("wsPath", wsPathQueryParam); } - return builder.build(); + return builder.build(request.pathVariables()); } private String applyPathPrefix(ServerRequest request, String path) { diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphiQlHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphiQlHandlerTests.java index 6e34b6ff..63b533dd 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphiQlHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webflux/GraphiQlHandlerTests.java @@ -19,6 +19,7 @@ package org.springframework.graphql.server.webflux; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; +import java.util.Map; import org.junit.jupiter.api.Test; @@ -31,9 +32,11 @@ import org.springframework.http.codec.HttpMessageReader; import org.springframework.http.codec.HttpMessageWriter; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; import org.springframework.mock.web.server.MockServerWebExchange; +import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.reactive.result.view.ViewResolver; +import org.springframework.web.util.UriComponentsBuilder; import static org.assertj.core.api.Assertions.assertThat; @@ -45,10 +48,13 @@ class GraphiQlHandlerTests { private static final List> MESSAGE_READERS = Collections.emptyList(); - private final GraphiQlHandler handler = new GraphiQlHandler("/graphql", null, - new ByteArrayResource("GRAPHIQL".getBytes(StandardCharsets.UTF_8))); + private final GraphiQlHandler handler = initHandler("/graphql"); + private static GraphiQlHandler initHandler(String path) { + return new GraphiQlHandler(path, null, new ByteArrayResource("GRAPHIQL".getBytes(StandardCharsets.UTF_8))); + } + @Test void shouldRedirectWithPathQueryParameter() { MockServerHttpRequest httpRequest = MockServerHttpRequest.get("/graphiql").build(); @@ -73,6 +79,25 @@ class GraphiQlHandlerTests { assertThat(response.headers().getLocation().toASCIIString()).isEqualTo("/graphiql?path=/graphql&wsPath=/graphql"); } + @Test // gh-478 + void shouldRedirectWithPathVariables() { + Map pathVariables = Collections.singletonMap("envId", "123"); + UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("/env/{envId}/graphiql"); + String path = uriBuilder.build(pathVariables).toString(); + + MockServerHttpRequest httpRequest = MockServerHttpRequest.get(path).build(); + MockServerWebExchange exchange = MockServerWebExchange.from(httpRequest); + exchange.getAttributes().put(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE, pathVariables); + ServerRequest request = ServerRequest.create(exchange, MESSAGE_READERS); + + GraphiQlHandler graphiQlHandler = initHandler(uriBuilder.build().toString()); + ServerResponse response = graphiQlHandler.handleRequest(request).block(); + + assertThat(response.statusCode()).isEqualTo(HttpStatus.TEMPORARY_REDIRECT); + assertThat(response.headers().getLocation()).isNotNull(); + assertThat(response.headers().getLocation().toASCIIString()).isEqualTo(path + "?path=" + path); + } + @Test void shouldServeGraphiQlHtmlResource() { MockServerHttpRequest httpRequest = MockServerHttpRequest.get("/graphiql").queryParam("path", "/graphql").build(); diff --git a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java index d1673a9b..63d810ac 100644 --- a/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java +++ b/spring-graphql/src/test/java/org/springframework/graphql/server/webmvc/GraphiQlHandlerTests.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.List; +import java.util.Map; import javax.servlet.ServletException; @@ -33,8 +34,10 @@ import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.ResourceHttpMessageConverter; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; +import org.springframework.web.servlet.function.RouterFunctions; import org.springframework.web.servlet.function.ServerRequest; import org.springframework.web.servlet.function.ServerResponse; +import org.springframework.web.util.UriComponentsBuilder; import static org.assertj.core.api.Assertions.assertThat; @@ -47,8 +50,13 @@ class GraphiQlHandlerTests { private static final List> MESSAGE_READERS = Collections.emptyList(); - private GraphiQlHandler handler = new GraphiQlHandler("/graphql", null, - new ByteArrayResource("GRAPHIQL".getBytes(StandardCharsets.UTF_8))); + private final GraphiQlHandler handler = initHandler("/graphql"); + + + private static GraphiQlHandler initHandler(String path) { + return new GraphiQlHandler(path, null, new ByteArrayResource("GRAPHIQL".getBytes(StandardCharsets.UTF_8))); + } + @Test void shouldRedirectWithPathQueryParameter() { @@ -57,7 +65,8 @@ class GraphiQlHandlerTests { ServerResponse response = this.handler.handleRequest(request); assertThat(response.statusCode()).isEqualTo(HttpStatus.TEMPORARY_REDIRECT); assertThat(response.headers().getLocation()).isNotNull(); - assertThat(response.headers().getLocation().toASCIIString()).isEqualTo("http://localhost/graphiql?path=/graphql"); + assertThat(response.headers().getLocation().toASCIIString()) + .isEqualTo("http://localhost/graphiql?path=/graphql"); } @Test @@ -69,7 +78,27 @@ class GraphiQlHandlerTests { ServerResponse response = wsHandler.handleRequest(request); assertThat(response.statusCode()).isEqualTo(HttpStatus.TEMPORARY_REDIRECT); assertThat(response.headers().getLocation()).isNotNull(); - assertThat(response.headers().getLocation().toASCIIString()).isEqualTo("http://localhost/graphiql?path=/graphql&wsPath=/graphql"); + assertThat(response.headers().getLocation().toASCIIString()) + .isEqualTo("http://localhost/graphiql?path=/graphql&wsPath=/graphql"); + } + + @Test // gh-478 + void shouldRedirectWithPathVariables() { + Map pathVariables = Collections.singletonMap("envId", "123"); + UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString("/env/{envId}/graphiql"); + String path = uriBuilder.build(pathVariables).toString(); + + MockHttpServletRequest servletRequest = new MockHttpServletRequest("GET", path); + ServerRequest request = ServerRequest.create(servletRequest, MESSAGE_READERS); + servletRequest.setAttribute(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE, pathVariables); + + GraphiQlHandler graphiQlHandler = initHandler(uriBuilder.build().toString()); + ServerResponse response = graphiQlHandler.handleRequest(request); + + assertThat(response.statusCode()).isEqualTo(HttpStatus.TEMPORARY_REDIRECT); + assertThat(response.headers().getLocation()).isNotNull(); + assertThat(response.headers().getLocation().toASCIIString()) + .isEqualTo("http://localhost" + path + "?path=" + path); } @Test