diff --git a/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java b/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java index 66c741eb6b9..356367c55d6 100644 --- a/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/http/server/reactive/MockServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -40,6 +40,7 @@ import org.springframework.http.MediaType; import org.springframework.http.server.reactive.AbstractServerHttpRequest; import org.springframework.http.server.reactive.SslInfo; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MimeType; import org.springframework.util.MultiValueMap; @@ -54,8 +55,12 @@ import org.springframework.web.util.UriComponentsBuilder; */ public final class MockServerHttpRequest extends AbstractServerHttpRequest { + @Nullable private final HttpMethod httpMethod; + @Nullable + private final String customHttpMethod; + private final MultiValueMap cookies; @Nullable @@ -70,13 +75,15 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { private final Flux body; - private MockServerHttpRequest(HttpMethod httpMethod, URI uri, @Nullable String contextPath, - HttpHeaders headers, MultiValueMap cookies, + private MockServerHttpRequest(@Nullable HttpMethod httpMethod, @Nullable String customHttpMethod, + URI uri, @Nullable String contextPath, HttpHeaders headers, MultiValueMap cookies, @Nullable InetSocketAddress remoteAddress, @Nullable InetSocketAddress localAddress, @Nullable SslInfo sslInfo, Publisher body) { super(uri, contextPath, headers); + Assert.isTrue(httpMethod != null || customHttpMethod != null, "HTTP method must not be null"); this.httpMethod = httpMethod; + this.customHttpMethod = customHttpMethod; this.cookies = cookies; this.remoteAddress = remoteAddress; this.localAddress = localAddress; @@ -91,8 +98,9 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { } @Override + @SuppressWarnings("ConstantConditions") public String getMethodValue() { - return this.httpMethod.name(); + return (this.httpMethod != null ? this.httpMethod.name() : this.customHttpMethod); } @Override @@ -131,30 +139,6 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { // Static builder methods - /** - * Create a builder with the given HTTP method and a {@link URI}. - * @param method the HTTP method (GET, POST, etc) - * @param url the URL - * @return the created builder - */ - public static BodyBuilder method(HttpMethod method, URI url) { - return new DefaultBodyBuilder(method, url); - } - - /** - * Alternative to {@link #method(HttpMethod, URI)} that accepts a URI template. - * The given URI may contain query parameters, or those may be added later via - * {@link BaseBuilder#queryParam queryParam} builder methods. - * @param method the HTTP method (GET, POST, etc) - * @param urlTemplate the URL template - * @param vars variables to expand into the template - * @return the created builder - */ - public static BodyBuilder method(HttpMethod method, String urlTemplate, Object... vars) { - URI url = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(vars).encode().toUri(); - return new DefaultBodyBuilder(method, url); - } - /** * Create an HTTP GET builder with the given URI template. The given URI may * contain query parameters, or those may be added later via @@ -228,6 +212,44 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { return method(HttpMethod.OPTIONS, urlTemplate, uriVars); } + /** + * Create a builder with the given HTTP method and a {@link URI}. + * @param method the HTTP method (GET, POST, etc) + * @param url the URL + * @return the created builder + */ + public static BodyBuilder method(HttpMethod method, URI url) { + return new DefaultBodyBuilder(method, url); + } + + /** + * Alternative to {@link #method(HttpMethod, URI)} that accepts a URI template. + * The given URI may contain query parameters, or those may be added later via + * {@link BaseBuilder#queryParam queryParam} builder methods. + * @param method the HTTP method (GET, POST, etc) + * @param urlTemplate the URL template + * @param vars variables to expand into the template + * @return the created builder + */ + public static BodyBuilder method(HttpMethod method, String urlTemplate, Object... vars) { + URI url = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(vars).encode().toUri(); + return new DefaultBodyBuilder(method, url); + } + + /** + * Create a builder with a raw HTTP method value that is outside the range + * of {@link HttpMethod} enum values. + * @param method the HTTP method value + * @param urlTemplate the URL template + * @param vars variables to expand into the template + * @return the created builder + * @since 5.2.7 + */ + public static BodyBuilder method(String method, String urlTemplate, Object... vars) { + URI url = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(vars).encode().toUri(); + return new DefaultBodyBuilder(method, url); + } + /** * Request builder exposing properties not related to the body. @@ -408,8 +430,12 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { private static final DataBufferFactory BUFFER_FACTORY = new DefaultDataBufferFactory(); + @Nullable private final HttpMethod method; + @Nullable + private final String customMethod; + private final URI url; @Nullable @@ -431,8 +457,22 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { private SslInfo sslInfo; - public DefaultBodyBuilder(HttpMethod method, URI url) { + DefaultBodyBuilder(HttpMethod method, URI url) { this.method = method; + this.customMethod = null; + this.url = url; + } + + DefaultBodyBuilder(String method, URI url) { + HttpMethod resolved = HttpMethod.resolve(method); + if (resolved != null) { + this.method = resolved; + this.customMethod = null; + } + else { + this.method = null; + this.customMethod = method; + } this.url = url; } @@ -569,7 +609,7 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { @Override public MockServerHttpRequest body(Publisher body) { applyCookiesIfNecessary(); - return new MockServerHttpRequest(this.method, getUrlToUse(), this.contextPath, + return new MockServerHttpRequest(this.method, this.customMethod, getUrlToUse(), this.contextPath, this.headers, this.cookies, this.remoteAddress, this.localAddress, this.sslInfo, body); } diff --git a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/MockServerHttpRequest.java b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/MockServerHttpRequest.java index 0f41a41d21d..96708ef2fb5 100644 --- a/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/MockServerHttpRequest.java +++ b/spring-web/src/testFixtures/java/org/springframework/web/testfixture/http/server/reactive/MockServerHttpRequest.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2019 the original author or authors. + * Copyright 2002-2020 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. @@ -40,6 +40,7 @@ import org.springframework.http.MediaType; import org.springframework.http.server.reactive.AbstractServerHttpRequest; import org.springframework.http.server.reactive.SslInfo; import org.springframework.lang.Nullable; +import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MimeType; import org.springframework.util.MultiValueMap; @@ -54,8 +55,12 @@ import org.springframework.web.util.UriComponentsBuilder; */ public final class MockServerHttpRequest extends AbstractServerHttpRequest { + @Nullable private final HttpMethod httpMethod; + @Nullable + private final String customHttpMethod; + private final MultiValueMap cookies; @Nullable @@ -70,13 +75,15 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { private final Flux body; - private MockServerHttpRequest(HttpMethod httpMethod, URI uri, @Nullable String contextPath, - HttpHeaders headers, MultiValueMap cookies, + private MockServerHttpRequest(@Nullable HttpMethod httpMethod, @Nullable String customHttpMethod, + URI uri, @Nullable String contextPath, HttpHeaders headers, MultiValueMap cookies, @Nullable InetSocketAddress remoteAddress, @Nullable InetSocketAddress localAddress, @Nullable SslInfo sslInfo, Publisher body) { super(uri, contextPath, headers); + Assert.isTrue(httpMethod != null || customHttpMethod != null, "HTTP method must not be null"); this.httpMethod = httpMethod; + this.customHttpMethod = customHttpMethod; this.cookies = cookies; this.remoteAddress = remoteAddress; this.localAddress = localAddress; @@ -91,8 +98,9 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { } @Override + @SuppressWarnings("ConstantConditions") public String getMethodValue() { - return this.httpMethod.name(); + return (this.httpMethod != null ? this.httpMethod.name() : this.customHttpMethod); } @Override @@ -131,30 +139,6 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { // Static builder methods - /** - * Create a builder with the given HTTP method and a {@link URI}. - * @param method the HTTP method (GET, POST, etc) - * @param url the URL - * @return the created builder - */ - public static BodyBuilder method(HttpMethod method, URI url) { - return new DefaultBodyBuilder(method, url); - } - - /** - * Alternative to {@link #method(HttpMethod, URI)} that accepts a URI template. - * The given URI may contain query parameters, or those may be added later via - * {@link BaseBuilder#queryParam queryParam} builder methods. - * @param method the HTTP method (GET, POST, etc) - * @param urlTemplate the URL template - * @param vars variables to expand into the template - * @return the created builder - */ - public static BodyBuilder method(HttpMethod method, String urlTemplate, Object... vars) { - URI url = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(vars).encode().toUri(); - return new DefaultBodyBuilder(method, url); - } - /** * Create an HTTP GET builder with the given URI template. The given URI may * contain query parameters, or those may be added later via @@ -228,6 +212,44 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { return method(HttpMethod.OPTIONS, urlTemplate, uriVars); } + /** + * Create a builder with the given HTTP method and a {@link URI}. + * @param method the HTTP method (GET, POST, etc) + * @param url the URL + * @return the created builder + */ + public static BodyBuilder method(HttpMethod method, URI url) { + return new DefaultBodyBuilder(method, url); + } + + /** + * Alternative to {@link #method(HttpMethod, URI)} that accepts a URI template. + * The given URI may contain query parameters, or those may be added later via + * {@link BaseBuilder#queryParam queryParam} builder methods. + * @param method the HTTP method (GET, POST, etc) + * @param urlTemplate the URL template + * @param vars variables to expand into the template + * @return the created builder + */ + public static BodyBuilder method(HttpMethod method, String urlTemplate, Object... vars) { + URI url = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(vars).encode().toUri(); + return new DefaultBodyBuilder(method, url); + } + + /** + * Create a builder with a raw HTTP method value that is outside the range + * of {@link HttpMethod} enum values. + * @param method the HTTP method value + * @param urlTemplate the URL template + * @param vars variables to expand into the template + * @return the created builder + * @since 5.2.7 + */ + public static BodyBuilder method(String method, String urlTemplate, Object... vars) { + URI url = UriComponentsBuilder.fromUriString(urlTemplate).buildAndExpand(vars).encode().toUri(); + return new DefaultBodyBuilder(method, url); + } + /** * Request builder exposing properties not related to the body. @@ -408,8 +430,12 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { private static final DataBufferFactory BUFFER_FACTORY = new DefaultDataBufferFactory(); + @Nullable private final HttpMethod method; + @Nullable + private final String customMethod; + private final URI url; @Nullable @@ -431,8 +457,22 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { private SslInfo sslInfo; - public DefaultBodyBuilder(HttpMethod method, URI url) { + DefaultBodyBuilder(HttpMethod method, URI url) { this.method = method; + this.customMethod = null; + this.url = url; + } + + DefaultBodyBuilder(String method, URI url) { + HttpMethod resolved = HttpMethod.resolve(method); + if (resolved != null) { + this.method = resolved; + this.customMethod = null; + } + else { + this.method = null; + this.customMethod = method; + } this.url = url; } @@ -569,7 +609,7 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest { @Override public MockServerHttpRequest body(Publisher body) { applyCookiesIfNecessary(); - return new MockServerHttpRequest(this.method, getUrlToUse(), this.contextPath, + return new MockServerHttpRequest(this.method, this.customMethod, getUrlToUse(), this.contextPath, this.headers, this.cookies, this.remoteAddress, this.localAddress, this.sslInfo, body); }