Polish contribution and related code

This commit is contained in:
Sam Brannen
2023-01-11 13:50:46 +01:00
parent afb8a0d1b1
commit 0415975dd1
13 changed files with 240 additions and 330 deletions

View File

@@ -65,14 +65,16 @@ import org.springframework.web.testfixture.http.server.reactive.MockServerHttpRe
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.InstanceOfAssertFactories.type;
import static org.springframework.http.codec.json.Jackson2CodecSupport.JSON_VIEW_HINT;
/**
* @author Arjen Poutsma
* @author Sebastien Deleuze
* @author Brian Clozel
* @author Sam Brannen
*/
public class BodyExtractorsTests {
class BodyExtractorsTests {
private BodyExtractor.Context context;
@@ -82,7 +84,7 @@ public class BodyExtractorsTests {
@BeforeEach
public void createContext() {
void createContext() {
final List<HttpMessageReader<?>> messageReaders = new ArrayList<>();
messageReaders.add(new DecoderHttpMessageReader<>(new ByteBufferDecoder()));
messageReaders.add(new DecoderHttpMessageReader<>(StringDecoder.allMimeTypes()));
@@ -116,7 +118,7 @@ public class BodyExtractorsTests {
@Test
public void toMono() {
void toMono() {
BodyExtractor<Mono<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(String.class);
DefaultDataBufferFactory factory = DefaultDataBufferFactory.sharedInstance;
@@ -134,7 +136,7 @@ public class BodyExtractorsTests {
}
@Test
public void toMonoParameterizedTypeReference() {
void toMonoParameterizedTypeReference() {
BodyExtractor<Mono<Map<String, String>>, ReactiveHttpInputMessage> extractor =
BodyExtractors.toMono(new ParameterizedTypeReference<Map<String, String>>() {});
@@ -155,7 +157,7 @@ public class BodyExtractorsTests {
}
@Test
public void toMonoWithHints() {
void toMonoWithHints() {
BodyExtractor<Mono<User>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(User.class);
this.hints.put(JSON_VIEW_HINT, SafeToDeserialize.class);
@@ -179,7 +181,7 @@ public class BodyExtractorsTests {
}
@Test // SPR-15758
public void toMonoWithEmptyBodyAndNoContentType() {
void toMonoWithEmptyBodyAndNoContentType() {
BodyExtractor<Mono<Map<String, String>>, ReactiveHttpInputMessage> extractor =
BodyExtractors.toMono(new ParameterizedTypeReference<Map<String, String>>() {});
@@ -190,7 +192,7 @@ public class BodyExtractorsTests {
}
@Test
public void toMonoVoidAsClientShouldConsumeAndCancel() {
void toMonoVoidAsClientShouldConsumeAndCancel() {
byte[] bytes = "foo".getBytes(StandardCharsets.UTF_8);
DefaultDataBuffer dataBuffer = DefaultDataBufferFactory.sharedInstance.wrap(ByteBuffer.wrap(bytes));
TestPublisher<DataBuffer> body = TestPublisher.create();
@@ -210,7 +212,7 @@ public class BodyExtractorsTests {
}
@Test
public void toMonoVoidAsClientWithEmptyBody() {
void toMonoVoidAsClientWithEmptyBody() {
TestPublisher<DataBuffer> body = TestPublisher.create();
BodyExtractor<Mono<Void>, ReactiveHttpInputMessage> extractor = BodyExtractors.toMono(Void.class);
@@ -226,7 +228,7 @@ public class BodyExtractorsTests {
}
@Test
public void toFlux() {
void toFlux() {
BodyExtractor<Flux<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(String.class);
byte[] bytes = "foo".getBytes(StandardCharsets.UTF_8);
@@ -243,7 +245,7 @@ public class BodyExtractorsTests {
}
@Test
public void toFluxWithHints() {
void toFluxWithHints() {
BodyExtractor<Flux<User>, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(User.class);
this.hints.put(JSON_VIEW_HINT, SafeToDeserialize.class);
@@ -272,7 +274,7 @@ public class BodyExtractorsTests {
}
@Test
public void toFluxUnacceptable() {
void toFluxUnacceptable() {
BodyExtractor<Flux<String>, ReactiveHttpInputMessage> extractor = BodyExtractors.toFlux(String.class);
byte[] bytes = "foo".getBytes(StandardCharsets.UTF_8);
@@ -307,7 +309,7 @@ public class BodyExtractorsTests {
}
@Test
public void toFormData() {
void toFormData() {
byte[] bytes = "name+1=value+1&name+2=value+2%2B1&name+2=value+2%2B2&name+3".getBytes(StandardCharsets.UTF_8);
DefaultDataBuffer dataBuffer = DefaultDataBufferFactory.sharedInstance.wrap(ByteBuffer.wrap(bytes));
Flux<DataBuffer> body = Flux.just(dataBuffer);
@@ -320,10 +322,10 @@ public class BodyExtractorsTests {
StepVerifier.create(result)
.consumeNextWith(form -> {
assertThat(form.size()).as("Invalid result").isEqualTo(3);
assertThat(form).as("Invalid result").hasSize(3);
assertThat(form.getFirst("name 1")).as("Invalid result").isEqualTo("value 1");
List<String> values = form.get("name 2");
assertThat(values.size()).as("Invalid result").isEqualTo(2);
assertThat(values).as("Invalid result").hasSize(2);
assertThat(values.get(0)).as("Invalid result").isEqualTo("value 2+1");
assertThat(values.get(1)).as("Invalid result").isEqualTo("value 2+2");
assertThat(form.getFirst("name 3")).as("Invalid result").isNull();
@@ -333,28 +335,28 @@ public class BodyExtractorsTests {
}
@Test
public void toParts() {
void toParts() {
BodyExtractor<Flux<Part>, ServerHttpRequest> extractor = BodyExtractors.toParts();
String bodyContents = """
-----------------------------9051914041544843365972754266\r
Content-Disposition: form-data; name="text"\r
\r
text default\r
-----------------------------9051914041544843365972754266\r
Content-Disposition: form-data; name="file1"; filename="a.txt"\r
Content-Type: text/plain\r
\r
Content of a.txt.\r
\r
-----------------------------9051914041544843365972754266\r
Content-Disposition: form-data; name="file2"; filename="a.html"\r
Content-Type: text/html\r
\r
<!DOCTYPE html><title>Content of a.html.</title>\r
\r
-----------------------------9051914041544843365972754266--\r
""";
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="text"
text default
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain
Content of a.txt.
-----------------------------9051914041544843365972754266
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html
<!DOCTYPE html><title>Content of a.html.</title>
-----------------------------9051914041544843365972754266--
""".replace("\n", "\r\n");
byte[] bytes = bodyContents.getBytes(StandardCharsets.UTF_8);
DefaultDataBuffer dataBuffer = DefaultDataBufferFactory.sharedInstance.wrap(ByteBuffer.wrap(bytes));
@@ -369,33 +371,27 @@ public class BodyExtractorsTests {
StepVerifier.create(result)
.consumeNextWith(part -> {
assertThat(part.name()).isEqualTo("text");
boolean condition = part instanceof FormFieldPart;
assertThat(condition).isTrue();
FormFieldPart formFieldPart = (FormFieldPart) part;
assertThat(formFieldPart.value()).isEqualTo("text default");
assertThat(part).asInstanceOf(type(FormFieldPart.class)).satisfies(
formFieldPart -> assertThat(formFieldPart.value()).isEqualTo("text default"));
})
.consumeNextWith(part -> {
assertThat(part.name()).isEqualTo("file1");
boolean condition = part instanceof FilePart;
assertThat(condition).isTrue();
FilePart filePart = (FilePart) part;
assertThat(filePart.filename()).isEqualTo("a.txt");
assertThat(filePart.headers().getContentType()).isEqualTo(MediaType.TEXT_PLAIN);
assertThat(part).asInstanceOf(type(FilePart.class)).satisfies(
filePart -> assertThat(filePart.filename()).isEqualTo("a.txt"),
filePart -> assertThat(filePart.headers().getContentType()).isEqualTo(MediaType.TEXT_PLAIN));
})
.consumeNextWith(part -> {
assertThat(part.name()).isEqualTo("file2");
boolean condition = part instanceof FilePart;
assertThat(condition).isTrue();
FilePart filePart = (FilePart) part;
assertThat(filePart.filename()).isEqualTo("a.html");
assertThat(filePart.headers().getContentType()).isEqualTo(MediaType.TEXT_HTML);
assertThat(part).asInstanceOf(type(FilePart.class)).satisfies(
filePart -> assertThat(filePart.filename()).isEqualTo("a.html"),
filePart -> assertThat(filePart.headers().getContentType()).isEqualTo(MediaType.TEXT_HTML));
})
.expectComplete()
.verify();
}
@Test
public void toDataBuffers() {
void toDataBuffers() {
BodyExtractor<Flux<DataBuffer>, ReactiveHttpInputMessage> extractor = BodyExtractors.toDataBuffers();
byte[] bytes = "foo".getBytes(StandardCharsets.UTF_8);
@@ -412,7 +408,7 @@ public class BodyExtractorsTests {
}
@Test // SPR-17054
public void unsupportedMediaTypeShouldConsumeAndCancel() {
void unsupportedMediaTypeShouldConsumeAndCancel() {
NettyDataBufferFactory factory = new NettyDataBufferFactory(new PooledByteBufAllocator(true));
NettyDataBuffer buffer = factory.wrap(ByteBuffer.wrap("spring".getBytes(StandardCharsets.UTF_8)));
TestPublisher<DataBuffer> body = TestPublisher.create();
@@ -428,10 +424,8 @@ public class BodyExtractorsTests {
body.emit(buffer);
})
.expectErrorSatisfies(throwable -> {
boolean condition = throwable instanceof UnsupportedMediaTypeException;
assertThat(condition).isTrue();
assertThatExceptionOfType(IllegalReferenceCountException.class).isThrownBy(
buffer::release);
assertThat(throwable).isInstanceOf(UnsupportedMediaTypeException.class);
assertThatExceptionOfType(IllegalReferenceCountException.class).isThrownBy(buffer::release);
body.assertCancelled();
}).verify();
}

View File

@@ -70,6 +70,7 @@ import org.springframework.web.testfixture.server.MockServerWebExchange;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.InstanceOfAssertFactories.type;
import static org.springframework.web.reactive.function.BodyExtractors.toMono;
/**
@@ -413,16 +414,16 @@ public class DefaultServerRequestTests {
@Test
public void multipartData() {
String data = """
--12345\r
Content-Disposition: form-data; name="foo"\r
\r
bar\r
--12345\r
Content-Disposition: form-data; name="baz"\r
\r
qux\r
--12345--\r
""";
--12345
Content-Disposition: form-data; name="foo"
bar
--12345
Content-Disposition: form-data; name="baz"
qux
--12345--
""".replace("\n", "\r\n");
byte[] bytes = data.getBytes(StandardCharsets.UTF_8);
DefaultDataBuffer dataBuffer = DefaultDataBufferFactory.sharedInstance.wrap(ByteBuffer.wrap(bytes));
Flux<DataBuffer> body = Flux.just(dataBuffer);
@@ -439,18 +440,10 @@ public class DefaultServerRequestTests {
StepVerifier.create(resultData)
.consumeNextWith(formData -> {
assertThat(formData).hasSize(2);
Part part = formData.getFirst("foo");
boolean condition1 = part instanceof FormFieldPart;
assertThat(condition1).isTrue();
FormFieldPart formFieldPart = (FormFieldPart) part;
assertThat(formFieldPart.value()).isEqualTo("bar");
part = formData.getFirst("baz");
boolean condition = part instanceof FormFieldPart;
assertThat(condition).isTrue();
formFieldPart = (FormFieldPart) part;
assertThat(formFieldPart.value()).isEqualTo("qux");
assertThat(formData.getFirst("foo")).asInstanceOf(type(FormFieldPart.class))
.extracting(FormFieldPart::value).isEqualTo("bar");
assertThat(formData.getFirst("baz")).asInstanceOf(type(FormFieldPart.class))
.extracting(FormFieldPart::value).isEqualTo("qux");
})
.verifyComplete();
}
@@ -740,7 +733,6 @@ public class DefaultServerRequestTests {
@ParameterizedTest(name = "[{index}] {0}")
@ValueSource(strings = {"GET", "HEAD"})
@interface SafeHttpMethodsTest {
}
}

View File

@@ -36,10 +36,10 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r
/**
* @author Arjen Poutsma
*/
public class ToStringVisitorTests {
class ToStringVisitorTests {
@Test
public void nested() {
void nested() {
HandlerFunction<ServerResponse> handler = new SimpleHandlerFunction();
RouterFunction<ServerResponse> routerFunction = route()
.path("/foo", builder ->
@@ -53,16 +53,17 @@ public class ToStringVisitorTests {
routerFunction.accept(visitor);
String result = visitor.toString();
String expected = "/foo => {\n" +
" /bar => {\n" +
" (GET && /baz) -> \n" +
" }\n" +
"}";
String expected = """
/foo => {
/bar => {
(GET && /baz) ->\s
}
}""".replace('\t', ' ');
assertThat(result).isEqualTo(expected);
}
@Test
public void predicates() {
void predicates() {
testPredicate(methods(HttpMethod.GET), "GET");
testPredicate(methods(HttpMethod.GET, HttpMethod.POST), "[GET, POST]");
@@ -95,9 +96,7 @@ public class ToStringVisitorTests {
private void testPredicate(RequestPredicate predicate, String expected) {
ToStringVisitor visitor = new ToStringVisitor();
predicate.accept(visitor);
String result = visitor.toString();
assertThat(result).isEqualTo(expected);
assertThat(visitor).asString().isEqualTo(expected);
}

View File

@@ -16,10 +16,9 @@
package org.springframework.web.reactive.resource;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -29,11 +28,11 @@ import reactor.test.StepVerifier;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.util.StringUtils;
import org.springframework.web.reactive.resource.EncodedResourceResolver.EncodedResource;
import org.springframework.web.reactive.resource.GzipSupport.GzippedFiles;
import org.springframework.web.testfixture.server.MockServerWebExchange;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.web.testfixture.http.server.reactive.MockServerHttpRequest.get;
@@ -44,18 +43,16 @@ import static org.springframework.web.testfixture.http.server.reactive.MockServe
* @author Sam Brannen
*/
@ExtendWith(GzipSupport.class)
public class CssLinkResourceTransformerTests {
class CssLinkResourceTransformerTests {
private ResourceTransformerChain transformerChain;
@BeforeEach
public void setup() {
void setup() {
VersionResourceResolver versionResolver = new VersionResourceResolver();
versionResolver.setStrategyMap(Collections.singletonMap("/**", new ContentVersionStrategy()));
List<ResourceResolver> resolvers = new ArrayList<>();
resolvers.add(versionResolver);
resolvers.add(new PathResourceResolver());
List<ResourceResolver> resolvers = List.of(versionResolver, new PathResourceResolver());
CssLinkResourceTransformer cssLinkTransformer = new CssLinkResourceTransformer();
cssLinkTransformer.setResourceUrlProvider(createUrlProvider(resolvers));
@@ -66,18 +63,17 @@ public class CssLinkResourceTransformerTests {
private ResourceUrlProvider createUrlProvider(List<ResourceResolver> resolvers) {
ResourceWebHandler handler = new ResourceWebHandler();
handler.setLocations(Collections.singletonList(new ClassPathResource("test/", getClass())));
handler.setLocations(List.of(new ClassPathResource("test/", getClass())));
handler.setResourceResolvers(resolvers);
ResourceUrlProvider urlProvider = new ResourceUrlProvider();
urlProvider.registerHandlers(Collections.singletonMap("/static/**", handler));
urlProvider.registerHandlers(Map.of("/static/**", handler));
return urlProvider;
}
@Test
public void transform() {
void transform() {
MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/main.css"));
Resource css = getResource("main.css");
String expected = """
@@ -95,16 +91,15 @@ public class CssLinkResourceTransformerTests {
StepVerifier.create(this.transformerChain.transform(exchange, css)
.cast(TransformedResource.class))
.consumeNextWith(transformedResource -> {
String result = new String(transformedResource.getByteArray(), StandardCharsets.UTF_8);
result = StringUtils.deleteAny(result, "\r");
assertThat(result).isEqualTo(expected);
String result = new String(transformedResource.getByteArray(), UTF_8);
assertThat(result).isEqualToNormalizingNewlines(expected);
})
.expectComplete()
.verify();
}
@Test
public void transformNoLinks() {
void transformNoLinks() {
MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/foo.css"));
Resource expected = getResource("foo.css");
@@ -114,7 +109,7 @@ public class CssLinkResourceTransformerTests {
}
@Test
public void transformExtLinksNotAllowed() {
void transformExtLinksNotAllowed() {
MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/external.css"));
List<ResourceTransformer> transformers = Collections.singletonList(new CssLinkResourceTransformer());
@@ -130,9 +125,8 @@ public class CssLinkResourceTransformerTests {
StepVerifier.create(chain.transform(exchange, resource)
.cast(TransformedResource.class))
.consumeNextWith(transformedResource -> {
String result = new String(transformedResource.getByteArray(), StandardCharsets.UTF_8);
result = StringUtils.deleteAny(result, "\r");
assertThat(result).isEqualTo(expected);
String result = new String(transformedResource.getByteArray(), UTF_8);
assertThat(result).isEqualToNormalizingNewlines(expected);
})
.expectComplete()
.verify();
@@ -144,7 +138,7 @@ public class CssLinkResourceTransformerTests {
}
@Test
public void transformSkippedForNonCssResource() {
void transformSkippedForNonCssResource() {
MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/images/image.png"));
Resource expected = getResource("images/image.png");
@@ -155,7 +149,7 @@ public class CssLinkResourceTransformerTests {
}
@Test
public void transformSkippedForGzippedResource(GzippedFiles gzippedFiles) throws Exception {
void transformSkippedForGzippedResource(GzippedFiles gzippedFiles) throws Exception {
gzippedFiles.create("main.css");
MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/main.css"));
@@ -169,20 +163,19 @@ public class CssLinkResourceTransformerTests {
}
@Test // https://github.com/spring-projects/spring-framework/issues/22602
public void transformEmptyUrlFunction() throws Exception {
void transformEmptyUrlFunction() throws Exception {
MockServerWebExchange exchange = MockServerWebExchange.from(get("/static/empty_url_function.css"));
Resource css = getResource("empty_url_function.css");
String expected = """
.fooStyle {
\tbackground: transparent url() no-repeat left top;
background: transparent url() no-repeat left top;
}""";
StepVerifier.create(this.transformerChain.transform(exchange, css)
.cast(TransformedResource.class))
.consumeNextWith(transformedResource -> {
String result = new String(transformedResource.getByteArray(), StandardCharsets.UTF_8);
result = StringUtils.deleteAny(result, "\r");
assertThat(result).isEqualTo(expected);
String result = new String(transformedResource.getByteArray(), UTF_8);
assertThat(result).isEqualToNormalizingNewlines(expected);
})
.expectComplete()
.verify();