Browse Source

Add nullability annotations to tests in module/spring-boot-webflux

See gh-47263
pull/47637/head
Moritz Halbritter 5 months ago
parent
commit
8236fa2f42
  1. 4
      module/spring-boot-webflux/build.gradle
  2. 9
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java
  3. 5
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java
  4. 35
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WebFluxAutoConfigurationTests.java
  5. 18
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WelcomePageRouterFunctionFactoryTests.java
  6. 7
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/ControllerEndpointWebFluxIntegrationTests.java
  7. 8
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointAccessIntegrationTests.java
  8. 4
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationIntegrationTests.java
  9. 21
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandlerIntegrationTests.java
  10. 1
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DummyBody.java
  11. 85
      module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/error/DefaultErrorAttributesTests.java

4
module/spring-boot-webflux/build.gradle

@ -58,3 +58,7 @@ dependencies {
testRuntimeOnly("ch.qos.logback:logback-classic") testRuntimeOnly("ch.qos.logback:logback-classic")
testRuntimeOnly("jakarta.servlet:jakarta.servlet-api") testRuntimeOnly("jakarta.servlet:jakarta.servlet-api")
} }
tasks.named("compileTestJava") {
options.nullability.checking = "tests"
}

9
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/actuate/endpoint/web/ControllerEndpointHandlerMappingTests.java

@ -16,9 +16,11 @@
package org.springframework.boot.webflux.actuate.endpoint.web; package org.springframework.boot.webflux.actuate.endpoint.web;
import java.lang.reflect.Method;
import java.time.Duration; import java.time.Duration;
import java.util.Arrays; import java.util.Arrays;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.endpoint.Access; import org.springframework.boot.actuate.endpoint.Access;
@ -96,7 +98,8 @@ class ControllerEndpointHandlerMappingTests {
.isThrownBy(() -> getHandler(mapping, HttpMethod.POST, "/actuator/first")); .isThrownBy(() -> getHandler(mapping, HttpMethod.POST, "/actuator/first"));
} }
private Object getHandler(ControllerEndpointHandlerMapping mapping, HttpMethod method, String requestURI) { private @Nullable Object getHandler(ControllerEndpointHandlerMapping mapping, HttpMethod method,
String requestURI) {
return mapping.getHandler(exchange(method, requestURI)).block(Duration.ofSeconds(30)); return mapping.getHandler(exchange(method, requestURI)).block(Duration.ofSeconds(30));
} }
@ -109,7 +112,9 @@ class ControllerEndpointHandlerMappingTests {
} }
private HandlerMethod handlerOf(Object source, String methodName) { private HandlerMethod handlerOf(Object source, String methodName) {
return new HandlerMethod(source, ReflectionUtils.findMethod(source.getClass(), methodName)); Method method = ReflectionUtils.findMethod(source.getClass(), methodName);
assertThat(method).isNotNull();
return new HandlerMethod(source, method);
} }
private MockServerWebExchange exchange(HttpMethod method, String requestURI) { private MockServerWebExchange exchange(HttpMethod method, String requestURI) {

5
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java

@ -18,6 +18,7 @@ package org.springframework.boot.webflux.autoconfigure;
import org.assertj.core.api.InstanceOfAssertFactories; import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
@ -104,12 +105,12 @@ class HttpHandlerAutoConfigurationTests {
@Bean @Bean
HttpHandler customHttpHandler() { HttpHandler customHttpHandler() {
return (serverHttpRequest, serverHttpResponse) -> null; return (serverHttpRequest, serverHttpResponse) -> Mono.empty();
} }
@Bean @Bean
RouterFunction<ServerResponse> routerFunction() { RouterFunction<ServerResponse> routerFunction() {
return route(GET("/test"), (serverRequest) -> null); return route(GET("/test"), (serverRequest) -> Mono.empty());
} }
} }

35
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WebFluxAutoConfigurationTests.java

@ -38,11 +38,13 @@ import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
import org.assertj.core.api.Assertions; import org.assertj.core.api.Assertions;
import org.assertj.core.api.InstanceOfAssertFactories; import org.assertj.core.api.InstanceOfAssertFactories;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledForJreRange; import org.junit.jupiter.api.condition.EnabledForJreRange;
import org.junit.jupiter.api.condition.JRE; import org.junit.jupiter.api.condition.JRE;
import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource; import org.junit.jupiter.params.provider.ValueSource;
import reactor.core.publisher.Mono;
import org.springframework.aop.support.AopUtils; import org.springframework.aop.support.AopUtils;
import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.AutoConfigurations;
@ -109,6 +111,7 @@ import org.springframework.web.reactive.resource.CachingResourceTransformer;
import org.springframework.web.reactive.resource.PathResourceResolver; import org.springframework.web.reactive.resource.PathResourceResolver;
import org.springframework.web.reactive.resource.ResourceWebHandler; import org.springframework.web.reactive.resource.ResourceWebHandler;
import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver; import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;
import org.springframework.web.reactive.result.method.annotation.ArgumentResolverConfigurer;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.reactive.result.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.reactive.result.method.annotation.ResponseEntityExceptionHandler; import org.springframework.web.reactive.result.method.annotation.ResponseEntityExceptionHandler;
@ -178,8 +181,10 @@ class WebFluxAutoConfigurationTests {
void shouldRegisterCustomHandlerMethodArgumentResolver() { void shouldRegisterCustomHandlerMethodArgumentResolver() {
this.contextRunner.withUserConfiguration(CustomArgumentResolvers.class).run((context) -> { this.contextRunner.withUserConfiguration(CustomArgumentResolvers.class).run((context) -> {
RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class); RequestMappingHandlerAdapter adapter = context.getBean(RequestMappingHandlerAdapter.class);
ArgumentResolverConfigurer configurer = adapter.getArgumentResolverConfigurer();
assertThat(configurer).isNotNull();
List<HandlerMethodArgumentResolver> customResolvers = (List<HandlerMethodArgumentResolver>) ReflectionTestUtils List<HandlerMethodArgumentResolver> customResolvers = (List<HandlerMethodArgumentResolver>) ReflectionTestUtils
.getField(adapter.getArgumentResolverConfigurer(), "customResolvers"); .getField(configurer, "customResolvers");
assertThat(customResolvers).contains(context.getBean("firstResolver", HandlerMethodArgumentResolver.class), assertThat(customResolvers).contains(context.getBean("firstResolver", HandlerMethodArgumentResolver.class),
context.getBean("secondResolver", HandlerMethodArgumentResolver.class)); context.getBean("secondResolver", HandlerMethodArgumentResolver.class));
}); });
@ -564,9 +569,9 @@ class WebFluxAutoConfigurationTests {
void whenFixedLocalContextResolverIsUsedThenAcceptLanguagesHeaderIsIgnored() { void whenFixedLocalContextResolverIsUsedThenAcceptLanguagesHeaderIsIgnored() {
this.contextRunner.withPropertyValues("spring.web.locale:en_UK", "spring.web.locale-resolver=fixed") this.contextRunner.withPropertyValues("spring.web.locale:en_UK", "spring.web.locale-resolver=fixed")
.run((context) -> { .run((context) -> {
MockServerHttpRequest request = MockServerHttpRequest.get("/") Locale locale = StringUtils.parseLocaleString("nl_NL");
.acceptLanguageAsLocales(StringUtils.parseLocaleString("nl_NL")) assertThat(locale).isNotNull();
.build(); MockServerHttpRequest request = MockServerHttpRequest.get("/").acceptLanguageAsLocales(locale).build();
MockServerWebExchange exchange = MockServerWebExchange.from(request); MockServerWebExchange exchange = MockServerWebExchange.from(request);
LocaleContextResolver localeContextResolver = context.getBean(LocaleContextResolver.class); LocaleContextResolver localeContextResolver = context.getBean(LocaleContextResolver.class);
assertThat(localeContextResolver).isInstanceOf(FixedLocaleContextResolver.class); assertThat(localeContextResolver).isInstanceOf(FixedLocaleContextResolver.class);
@ -578,14 +583,14 @@ class WebFluxAutoConfigurationTests {
@Test @Test
void whenAcceptHeaderLocaleContextResolverIsUsedThenAcceptLanguagesHeaderIsHonoured() { void whenAcceptHeaderLocaleContextResolverIsUsedThenAcceptLanguagesHeaderIsHonoured() {
this.contextRunner.withPropertyValues("spring.web.locale:en_UK").run((context) -> { this.contextRunner.withPropertyValues("spring.web.locale:en_UK").run((context) -> {
MockServerHttpRequest request = MockServerHttpRequest.get("/") Locale locale = StringUtils.parseLocaleString("nl_NL");
.acceptLanguageAsLocales(StringUtils.parseLocaleString("nl_NL")) assertThat(locale).isNotNull();
.build(); MockServerHttpRequest request = MockServerHttpRequest.get("/").acceptLanguageAsLocales(locale).build();
MockServerWebExchange exchange = MockServerWebExchange.from(request); MockServerWebExchange exchange = MockServerWebExchange.from(request);
LocaleContextResolver localeContextResolver = context.getBean(LocaleContextResolver.class); LocaleContextResolver localeContextResolver = context.getBean(LocaleContextResolver.class);
assertThat(localeContextResolver).isInstanceOf(AcceptHeaderLocaleContextResolver.class); assertThat(localeContextResolver).isInstanceOf(AcceptHeaderLocaleContextResolver.class);
LocaleContext localeContext = localeContextResolver.resolveLocaleContext(exchange); LocaleContext localeContext = localeContextResolver.resolveLocaleContext(exchange);
assertThat(localeContext.getLocale()).isEqualTo(StringUtils.parseLocaleString("nl_NL")); assertThat(localeContext.getLocale()).isEqualTo(locale);
}); });
} }
@ -674,12 +679,15 @@ class WebFluxAutoConfigurationTests {
.run(assertExchangeWithSession((exchange) -> { .run(assertExchangeWithSession((exchange) -> {
List<ResponseCookie> cookies = exchange.getResponse().getCookies().get("JSESSIONID"); List<ResponseCookie> cookies = exchange.getResponse().getCookies().get("JSESSIONID");
assertThat(cookies).isNotEmpty(); assertThat(cookies).isNotEmpty();
assertThat(cookies).allMatch((cookie) -> cookie.getDomain().equals(".example.com")); assertThat(cookies)
assertThat(cookies).allMatch((cookie) -> cookie.getPath().equals("/example")); .allMatch((cookie) -> cookie.getDomain() != null && cookie.getDomain().equals(".example.com"));
assertThat(cookies)
.allMatch((cookie) -> cookie.getPath() != null && cookie.getPath().equals("/example"));
assertThat(cookies).allMatch((cookie) -> cookie.getMaxAge().equals(Duration.ofSeconds(60))); assertThat(cookies).allMatch((cookie) -> cookie.getMaxAge().equals(Duration.ofSeconds(60)));
assertThat(cookies).allMatch((cookie) -> !cookie.isHttpOnly()); assertThat(cookies).allMatch((cookie) -> !cookie.isHttpOnly());
assertThat(cookies).allMatch((cookie) -> !cookie.isSecure()); assertThat(cookies).allMatch((cookie) -> !cookie.isSecure());
assertThat(cookies).allMatch((cookie) -> cookie.getSameSite().equals("Strict")); assertThat(cookies)
.allMatch((cookie) -> cookie.getSameSite() != null && cookie.getSameSite().equals("Strict"));
assertThat(cookies).allMatch(ResponseCookie::isPartitioned); assertThat(cookies).allMatch(ResponseCookie::isPartitioned);
})); }));
} }
@ -906,6 +914,7 @@ class WebFluxAutoConfigurationTests {
MockServerWebExchange webExchange = MockServerWebExchange.from(request); MockServerWebExchange webExchange = MockServerWebExchange.from(request);
WebSessionManager webSessionManager = context.getBean(WebSessionManager.class); WebSessionManager webSessionManager = context.getBean(WebSessionManager.class);
WebSession webSession = webSessionManager.getSession(webExchange).block(); WebSession webSession = webSessionManager.getSession(webExchange).block();
assertThat(webSession).isNotNull();
webSession.start(); webSession.start();
webExchange.getResponse().setComplete().block(); webExchange.getResponse().setComplete().block();
exchange.accept(webExchange); exchange.accept(webExchange);
@ -1024,7 +1033,7 @@ class WebFluxAutoConfigurationTests {
@Bean @Bean
HttpHandler httpHandler() { HttpHandler httpHandler() {
return (serverHttpRequest, serverHttpResponse) -> null; return (serverHttpRequest, serverHttpResponse) -> Mono.empty();
} }
} }
@ -1198,7 +1207,7 @@ class WebFluxAutoConfigurationTests {
} }
@Override @Override
public void setLocaleContext(ServerWebExchange exchange, LocaleContext localeContext) { public void setLocaleContext(ServerWebExchange exchange, @Nullable LocaleContext localeContext) {
} }
} }

18
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/WelcomePageRouterFunctionFactoryTests.java

@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -36,6 +37,8 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.test.web.reactive.server.WebTestClient; import org.springframework.test.web.reactive.server.WebTestClient;
import org.springframework.web.reactive.function.server.HandlerStrategies; import org.springframework.web.reactive.function.server.HandlerStrategies;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import org.springframework.web.reactive.result.view.View; import org.springframework.web.reactive.result.view.View;
import org.springframework.web.reactive.result.view.ViewResolver; import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.ServerWebExchange;
@ -166,13 +169,17 @@ class WelcomePageRouterFunctionFactoryTests {
private WebTestClient withStaticIndex() { private WebTestClient withStaticIndex() {
WelcomePageRouterFunctionFactory factory = factoryWithoutTemplateSupport(this.indexLocations, "/**"); WelcomePageRouterFunctionFactory factory = factoryWithoutTemplateSupport(this.indexLocations, "/**");
return WebTestClient.bindToRouterFunction(factory.createRouterFunction()).build(); RouterFunction<ServerResponse> routerFunction = factory.createRouterFunction();
assertThat(routerFunction).isNotNull();
return WebTestClient.bindToRouterFunction(routerFunction).build();
} }
private WebTestClient withTemplateIndex() { private WebTestClient withTemplateIndex() {
WelcomePageRouterFunctionFactory factory = factoryWithTemplateSupport(this.noIndexLocations); WelcomePageRouterFunctionFactory factory = factoryWithTemplateSupport(this.noIndexLocations);
TestViewResolver testViewResolver = new TestViewResolver(); TestViewResolver testViewResolver = new TestViewResolver();
return WebTestClient.bindToRouterFunction(factory.createRouterFunction()) RouterFunction<ServerResponse> routerFunction = factory.createRouterFunction();
assertThat(routerFunction).isNotNull();
return WebTestClient.bindToRouterFunction(routerFunction)
.handlerStrategies(HandlerStrategies.builder().viewResolver(testViewResolver).build()) .handlerStrategies(HandlerStrategies.builder().viewResolver(testViewResolver).build())
.build(); .build();
} }
@ -180,7 +187,9 @@ class WelcomePageRouterFunctionFactoryTests {
private WebTestClient withStaticAndTemplateIndex() { private WebTestClient withStaticAndTemplateIndex() {
WelcomePageRouterFunctionFactory factory = factoryWithTemplateSupport(this.indexLocations); WelcomePageRouterFunctionFactory factory = factoryWithTemplateSupport(this.indexLocations);
TestViewResolver testViewResolver = new TestViewResolver(); TestViewResolver testViewResolver = new TestViewResolver();
return WebTestClient.bindToRouterFunction(factory.createRouterFunction()) RouterFunction<ServerResponse> routerFunction = factory.createRouterFunction();
assertThat(routerFunction).isNotNull();
return WebTestClient.bindToRouterFunction(routerFunction)
.handlerStrategies(HandlerStrategies.builder().viewResolver(testViewResolver).build()) .handlerStrategies(HandlerStrategies.builder().viewResolver(testViewResolver).build())
.build(); .build();
} }
@ -226,7 +235,8 @@ class WelcomePageRouterFunctionFactoryTests {
private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory(); private final DataBufferFactory bufferFactory = new DefaultDataBufferFactory();
@Override @Override
public Mono<Void> render(Map<String, ?> model, MediaType contentType, ServerWebExchange exchange) { public Mono<Void> render(@Nullable Map<String, ?> model, @Nullable MediaType contentType,
ServerWebExchange exchange) {
DataBuffer buffer = this.bufferFactory.wrap("welcome-page-template".getBytes(StandardCharsets.UTF_8)); DataBuffer buffer = this.bufferFactory.wrap("welcome-page-template".getBytes(StandardCharsets.UTF_8));
return exchange.getResponse().writeWith(Mono.just(buffer)); return exchange.getResponse().writeWith(Mono.just(buffer));
} }

7
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/ControllerEndpointWebFluxIntegrationTests.java

@ -16,6 +16,7 @@
package org.springframework.boot.webflux.autoconfigure.actuate.web; package org.springframework.boot.webflux.autoconfigure.actuate.web;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -44,11 +45,13 @@ import org.springframework.web.bind.annotation.GetMapping;
@SuppressWarnings("removal") @SuppressWarnings("removal")
class ControllerEndpointWebFluxIntegrationTests { class ControllerEndpointWebFluxIntegrationTests {
private AnnotationConfigReactiveWebApplicationContext context; private @Nullable AnnotationConfigReactiveWebApplicationContext context;
@AfterEach @AfterEach
void close() { void close() {
this.context.close(); if (this.context != null) {
this.context.close();
}
} }
@Test @Test

8
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxEndpointAccessIntegrationTests.java

@ -30,6 +30,7 @@ import org.springframework.boot.jackson.autoconfigure.JacksonAutoConfiguration;
import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration; import org.springframework.boot.reactor.netty.autoconfigure.NettyReactiveWebServerAutoConfiguration;
import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext; import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext;
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner; import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
import org.springframework.boot.web.server.WebServer;
import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext; import org.springframework.boot.web.server.reactive.context.AnnotationConfigReactiveWebServerApplicationContext;
import org.springframework.boot.web.server.reactive.context.ReactiveWebServerApplicationContext; import org.springframework.boot.web.server.reactive.context.ReactiveWebServerApplicationContext;
import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration; import org.springframework.boot.webflux.autoconfigure.HttpHandlerAutoConfiguration;
@ -137,9 +138,10 @@ class WebFluxEndpointAccessIntegrationTests {
} }
private WebTestClient createClient(AssertableReactiveWebApplicationContext context) { private WebTestClient createClient(AssertableReactiveWebApplicationContext context) {
int port = context.getSourceApplicationContext(ReactiveWebServerApplicationContext.class) WebServer webServer = context.getSourceApplicationContext(ReactiveWebServerApplicationContext.class)
.getWebServer() .getWebServer();
.getPort(); assertThat(webServer).isNotNull();
int port = webServer.getPort();
ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder() ExchangeStrategies exchangeStrategies = ExchangeStrategies.builder()
.codecs((configurer) -> configurer.defaultCodecs().maxInMemorySize(-1)) .codecs((configurer) -> configurer.defaultCodecs().maxInMemorySize(-1))
.build(); .build();

4
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/actuate/web/WebFluxManagementChildContextConfigurationIntegrationTests.java

@ -26,6 +26,7 @@ import java.util.function.Consumer;
import org.apache.catalina.Valve; import org.apache.catalina.Valve;
import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.valves.AccessLogValve; import org.apache.catalina.valves.AccessLogValve;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir; import org.junit.jupiter.api.io.TempDir;
@ -80,6 +81,7 @@ class WebFluxManagementChildContextConfigurationIntegrationTests {
.withPropertyValues("server.port=0", "management.server.port=0", "management.endpoints.web.exposure.include=*"); .withPropertyValues("server.port=0", "management.server.port=0", "management.endpoints.web.exposure.include=*");
@TempDir @TempDir
@SuppressWarnings("NullAway.Init")
Path temp; Path temp;
@Test @Test
@ -122,7 +124,7 @@ class WebFluxManagementChildContextConfigurationIntegrationTests {
}); });
} }
private AccessLogValve findAccessLogValve() { private @Nullable AccessLogValve findAccessLogValve() {
assertThat(this.webServers).hasSize(2); assertThat(this.webServers).hasSize(2);
Tomcat tomcat = ((TomcatWebServer) this.webServers.get(1)).getTomcat(); Tomcat tomcat = ((TomcatWebServer) this.webServers.get(1)).getTomcat();
for (Valve valve : tomcat.getEngine().getPipeline().getValves()) { for (Valve valve : tomcat.getEngine().getPipeline().getValves()) {

21
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DefaultErrorWebExceptionHandlerIntegrationTests.java

@ -22,6 +22,7 @@ import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
@ -568,7 +569,7 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
private static final class LogIdFilter implements WebFilter { private static final class LogIdFilter implements WebFilter {
private String logId; private @Nullable String logId;
@Override @Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
@ -576,7 +577,7 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
return chain.filter(exchange); return chain.filter(exchange);
} }
String getLogId() { @Nullable String getLogId() {
return this.logId; return this.logId;
} }
@ -627,8 +628,9 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
ErrorAttributes errorAttributes() { ErrorAttributes errorAttributes() {
return new DefaultErrorAttributes() { return new DefaultErrorAttributes() {
@Override @Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { public Map<String, @Nullable Object> getErrorAttributes(ServerRequest request,
Map<String, Object> errorAttributes = super.getErrorAttributes(request, options); ErrorAttributeOptions options) {
Map<String, @Nullable Object> errorAttributes = super.getErrorAttributes(request, options);
errorAttributes.put("error", "custom error"); errorAttributes.put("error", "custom error");
errorAttributes.put("newAttribute", "value"); errorAttributes.put("newAttribute", "value");
errorAttributes.remove("path"); errorAttributes.remove("path");
@ -648,8 +650,9 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
return new DefaultErrorAttributes() { return new DefaultErrorAttributes() {
@Override @Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { public Map<String, @Nullable Object> getErrorAttributes(ServerRequest request,
Map<String, Object> errorAttributes = new HashMap<>(); ErrorAttributeOptions options) {
Map<String, @Nullable Object> errorAttributes = new HashMap<>();
errorAttributes.put("status", 400); errorAttributes.put("status", 400);
errorAttributes.put("error", "custom error"); errorAttributes.put("error", "custom error");
return errorAttributes; return errorAttributes;
@ -693,8 +696,10 @@ class DefaultErrorWebExceptionHandlerIntegrationTests {
return new DefaultErrorAttributes() { return new DefaultErrorAttributes() {
@Override @Override
public Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) { public Map<String, @Nullable Object> getErrorAttributes(ServerRequest request,
Map<String, Object> attributes = new LinkedHashMap<>(super.getErrorAttributes(request, options)); ErrorAttributeOptions options) {
Map<String, @Nullable Object> attributes = new LinkedHashMap<>(
super.getErrorAttributes(request, options));
attributes.remove("status"); attributes.remove("status");
return attributes; return attributes;
} }

1
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/error/DummyBody.java

@ -21,6 +21,7 @@ import jakarta.validation.constraints.NotNull;
public class DummyBody { public class DummyBody {
@NotNull @NotNull
@SuppressWarnings("NullAway.Init")
private String content; private String content;
public String getContent() { public String getContent() {

85
module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/error/DefaultErrorAttributesTests.java

@ -22,6 +22,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.jspecify.annotations.Nullable;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.springframework.boot.web.error.ErrorAttributeOptions; import org.springframework.boot.web.error.ErrorAttributeOptions;
@ -77,8 +78,8 @@ class DefaultErrorAttributesTests {
@Test @Test
void includeTimeStamp() { void includeTimeStamp() {
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.defaults()); .getErrorAttributes(buildServerRequest(request, NOT_FOUND), ErrorAttributeOptions.defaults());
assertThat(attributes.get("timestamp")).isInstanceOf(Date.class); assertThat(attributes.get("timestamp")).isInstanceOf(Date.class);
} }
@ -86,8 +87,8 @@ class DefaultErrorAttributesTests {
void defaultStatusCode() { void defaultStatusCode() {
Error error = new OutOfMemoryError("Test error"); Error error = new OutOfMemoryError("Test error");
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.defaults()); .getErrorAttributes(buildServerRequest(request, error), ErrorAttributeOptions.defaults());
assertThat(attributes).containsEntry("error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase()); assertThat(attributes).containsEntry("error", HttpStatus.INTERNAL_SERVER_ERROR.getReasonPhrase());
assertThat(attributes).containsEntry("status", 500); assertThat(attributes).containsEntry("status", 500);
} }
@ -96,8 +97,8 @@ class DefaultErrorAttributesTests {
void annotatedResponseStatusCode() { void annotatedResponseStatusCode() {
Exception error = new CustomException(); Exception error = new CustomException();
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.defaults()); .getErrorAttributes(buildServerRequest(request, error), ErrorAttributeOptions.defaults());
assertThat(attributes).containsEntry("error", HttpStatus.EXPECTATION_FAILED.getReasonPhrase()); assertThat(attributes).containsEntry("error", HttpStatus.EXPECTATION_FAILED.getReasonPhrase());
assertThat(attributes).doesNotContainKey("message"); assertThat(attributes).doesNotContainKey("message");
assertThat(attributes).containsEntry("status", HttpStatus.EXPECTATION_FAILED.value()); assertThat(attributes).containsEntry("status", HttpStatus.EXPECTATION_FAILED.value());
@ -107,7 +108,8 @@ class DefaultErrorAttributesTests {
void annotatedResponseStatusCodeWithExceptionMessage() { void annotatedResponseStatusCodeWithExceptionMessage() {
Exception error = new CustomException("Test Message"); Exception error = new CustomException("Test Message");
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(
buildServerRequest(request, error),
ErrorAttributeOptions.of(Include.MESSAGE, Include.STATUS, Include.ERROR)); ErrorAttributeOptions.of(Include.MESSAGE, Include.STATUS, Include.ERROR));
assertThat(attributes).containsEntry("error", HttpStatus.EXPECTATION_FAILED.getReasonPhrase()); assertThat(attributes).containsEntry("error", HttpStatus.EXPECTATION_FAILED.getReasonPhrase());
assertThat(attributes).containsEntry("message", "Test Message"); assertThat(attributes).containsEntry("message", "Test Message");
@ -118,7 +120,8 @@ class DefaultErrorAttributesTests {
void annotatedResponseStatusCodeWithCustomReasonPhrase() { void annotatedResponseStatusCodeWithCustomReasonPhrase() {
Exception error = new Custom2Exception(); Exception error = new Custom2Exception();
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, error), Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(
buildServerRequest(request, error),
ErrorAttributeOptions.of(Include.MESSAGE, Include.STATUS, Include.ERROR)); ErrorAttributeOptions.of(Include.MESSAGE, Include.STATUS, Include.ERROR));
assertThat(attributes).containsEntry("error", HttpStatus.EXPECTATION_FAILED.getReasonPhrase()); assertThat(attributes).containsEntry("error", HttpStatus.EXPECTATION_FAILED.getReasonPhrase());
assertThat(attributes).containsEntry("status", HttpStatus.EXPECTATION_FAILED.value()); assertThat(attributes).containsEntry("status", HttpStatus.EXPECTATION_FAILED.value());
@ -128,8 +131,8 @@ class DefaultErrorAttributesTests {
@Test @Test
void includeStatusCode() { void includeStatusCode() {
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.defaults()); .getErrorAttributes(buildServerRequest(request, NOT_FOUND), ErrorAttributeOptions.defaults());
assertThat(attributes).containsEntry("error", HttpStatus.NOT_FOUND.getReasonPhrase()); assertThat(attributes).containsEntry("error", HttpStatus.NOT_FOUND.getReasonPhrase());
assertThat(attributes).containsEntry("status", 404); assertThat(attributes).containsEntry("status", 404);
} }
@ -139,7 +142,7 @@ class DefaultErrorAttributesTests {
Error error = new OutOfMemoryError("Test error"); Error error = new OutOfMemoryError("Test error");
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
ServerRequest serverRequest = buildServerRequest(request, error); ServerRequest serverRequest = buildServerRequest(request, error);
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest, Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest,
ErrorAttributeOptions.of(Include.MESSAGE)); ErrorAttributeOptions.of(Include.MESSAGE));
assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error);
assertThat(attributes).doesNotContainKey("exception"); assertThat(attributes).doesNotContainKey("exception");
@ -151,7 +154,7 @@ class DefaultErrorAttributesTests {
Error error = new OutOfMemoryError("Test error"); Error error = new OutOfMemoryError("Test error");
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
ServerRequest serverRequest = buildServerRequest(request, error); ServerRequest serverRequest = buildServerRequest(request, error);
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest, Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest,
ErrorAttributeOptions.defaults()); ErrorAttributeOptions.defaults());
assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error);
assertThat(attributes).doesNotContainKey("message"); assertThat(attributes).doesNotContainKey("message");
@ -163,7 +166,7 @@ class DefaultErrorAttributesTests {
this.errorAttributes = new DefaultErrorAttributes(); this.errorAttributes = new DefaultErrorAttributes();
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
ServerRequest serverRequest = buildServerRequest(request, error); ServerRequest serverRequest = buildServerRequest(request, error);
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest, Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest,
ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE)); ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE));
assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error); assertThat(this.errorAttributes.getError(serverRequest)).isSameAs(error);
assertThat(attributes).containsEntry("exception", RuntimeException.class.getName()); assertThat(attributes).containsEntry("exception", RuntimeException.class.getName());
@ -177,7 +180,7 @@ class DefaultErrorAttributesTests {
this.errorAttributes = new DefaultErrorAttributes(); this.errorAttributes = new DefaultErrorAttributes();
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
ServerRequest serverRequest = buildServerRequest(request, error); ServerRequest serverRequest = buildServerRequest(request, error);
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest, Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest,
ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE, Include.STATUS)); ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE, Include.STATUS));
assertThat(attributes).containsEntry("status", 400); assertThat(attributes).containsEntry("status", 400);
assertThat(attributes).containsEntry("message", "invalid request"); assertThat(attributes).containsEntry("message", "invalid request");
@ -192,7 +195,7 @@ class DefaultErrorAttributesTests {
this.errorAttributes = new DefaultErrorAttributes(); this.errorAttributes = new DefaultErrorAttributes();
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
ServerRequest serverRequest = buildServerRequest(request, error); ServerRequest serverRequest = buildServerRequest(request, error);
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest, Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest,
ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE, Include.STATUS)); ErrorAttributeOptions.of(Include.EXCEPTION, Include.MESSAGE, Include.STATUS));
assertThat(attributes).containsEntry("status", 406); assertThat(attributes).containsEntry("status", 406);
assertThat(attributes).containsEntry("message", "could not process request"); assertThat(attributes).containsEntry("message", "could not process request");
@ -204,8 +207,8 @@ class DefaultErrorAttributesTests {
void notIncludeTrace() { void notIncludeTrace() {
RuntimeException ex = new RuntimeException("Test"); RuntimeException ex = new RuntimeException("Test");
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.defaults()); .getErrorAttributes(buildServerRequest(request, ex), ErrorAttributeOptions.defaults());
assertThat(attributes).doesNotContainKey("trace"); assertThat(attributes).doesNotContainKey("trace");
} }
@ -213,40 +216,42 @@ class DefaultErrorAttributesTests {
void includeTrace() { void includeTrace() {
RuntimeException ex = new RuntimeException("Test"); RuntimeException ex = new RuntimeException("Test");
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.of(Include.STACK_TRACE)); .getErrorAttributes(buildServerRequest(request, ex), ErrorAttributeOptions.of(Include.STACK_TRACE));
assertThat(attributes.get("trace").toString()).startsWith("java.lang"); Object trace = attributes.get("trace");
assertThat(trace).isNotNull();
assertThat(trace.toString()).startsWith("java.lang");
} }
@Test @Test
void includePathByDefault() { void includePathByDefault() {
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.defaults()); .getErrorAttributes(buildServerRequest(request, NOT_FOUND), ErrorAttributeOptions.defaults());
assertThat(attributes).containsEntry("path", "/test"); assertThat(attributes).containsEntry("path", "/test");
} }
@Test @Test
void includePath() { void includePath() {
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.of(Include.PATH)); .getErrorAttributes(buildServerRequest(request, NOT_FOUND), ErrorAttributeOptions.of(Include.PATH));
assertThat(attributes).containsEntry("path", "/test"); assertThat(attributes).containsEntry("path", "/test");
} }
@Test @Test
void pathShouldIncludeContext() { void pathShouldIncludeContext() {
MockServerHttpRequest request = MockServerHttpRequest.get("/context/test").contextPath("/context").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/context/test").contextPath("/context").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.of(Include.PATH)); .getErrorAttributes(buildServerRequest(request, NOT_FOUND), ErrorAttributeOptions.of(Include.PATH));
assertThat(attributes).containsEntry("path", "/context/test"); assertThat(attributes).containsEntry("path", "/context/test");
} }
@Test @Test
void excludePath() { void excludePath() {
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, NOT_FOUND), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.of()); .getErrorAttributes(buildServerRequest(request, NOT_FOUND), ErrorAttributeOptions.of());
assertThat(attributes).doesNotContainEntry("path", "/test"); assertThat(attributes).doesNotContainEntry("path", "/test");
} }
@ -254,7 +259,7 @@ class DefaultErrorAttributesTests {
void includeLogPrefix() { void includeLogPrefix() {
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
ServerRequest serverRequest = buildServerRequest(request, NOT_FOUND); ServerRequest serverRequest = buildServerRequest(request, NOT_FOUND);
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest, Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest,
ErrorAttributeOptions.defaults()); ErrorAttributeOptions.defaults());
assertThat(attributes).containsEntry("requestId", serverRequest.exchange().getRequest().getId()); assertThat(attributes).containsEntry("requestId", serverRequest.exchange().getRequest().getId());
} }
@ -267,8 +272,8 @@ class DefaultErrorAttributesTests {
bindingResult.addError(new ObjectError("c", "d")); bindingResult.addError(new ObjectError("c", "d"));
Exception ex = new WebExchangeBindException(stringParam, bindingResult); Exception ex = new WebExchangeBindException(stringParam, bindingResult);
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(
ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); buildServerRequest(request, ex), ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS));
assertThat(attributes.get("message")).asString() assertThat(attributes.get("message")).asString()
.startsWith("Validation failed for argument at index 0 in method: " + "int " + getClass().getName() .startsWith("Validation failed for argument at index 0 in method: " + "int " + getClass().getName()
+ ".method(java.lang.String), with 1 error(s)"); + ".method(java.lang.String), with 1 error(s)");
@ -284,7 +289,7 @@ class DefaultErrorAttributesTests {
bindingResult.addError(new ObjectError("c", "d")); bindingResult.addError(new ObjectError("c", "d"));
Exception ex = new WebExchangeBindException(stringParam, bindingResult); Exception ex = new WebExchangeBindException(stringParam, bindingResult);
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes( Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(
buildServerRequest(request, new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid", ex)), buildServerRequest(request, new ResponseStatusException(HttpStatus.BAD_REQUEST, "Invalid", ex)),
ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS));
assertThat(attributes.get("message")).isEqualTo("Invalid"); assertThat(attributes.get("message")).isEqualTo("Invalid");
@ -305,8 +310,8 @@ class DefaultErrorAttributesTests {
}))); })));
HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult); HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult);
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(
ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); buildServerRequest(request, ex), ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS));
assertThat(attributes.get("message")).asString() assertThat(attributes.get("message")).asString()
.isEqualTo( .isEqualTo(
"Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1"); "Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1");
@ -322,8 +327,8 @@ class DefaultErrorAttributesTests {
bindingResult.addError(new ObjectError("c", "d")); bindingResult.addError(new ObjectError("c", "d"));
Exception ex = new WebExchangeBindException(stringParam, bindingResult); Exception ex = new WebExchangeBindException(stringParam, bindingResult);
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), Map<String, @Nullable Object> attributes = this.errorAttributes
ErrorAttributeOptions.defaults()); .getErrorAttributes(buildServerRequest(request, ex), ErrorAttributeOptions.defaults());
assertThat(attributes).doesNotContainKey("message"); assertThat(attributes).doesNotContainKey("message");
assertThat(attributes).doesNotContainKey("errors"); assertThat(attributes).doesNotContainKey("errors");
} }
@ -342,8 +347,8 @@ class DefaultErrorAttributesTests {
List.of(parameterValidationResult)); List.of(parameterValidationResult));
HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult); HandlerMethodValidationException ex = new HandlerMethodValidationException(methodValidationResult);
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(buildServerRequest(request, ex), Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(
ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS)); buildServerRequest(request, ex), ErrorAttributeOptions.of(Include.MESSAGE, Include.BINDING_ERRORS));
assertThat(attributes.get("message")).asString() assertThat(attributes.get("message")).asString()
.isEqualTo( .isEqualTo(
"Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1"); "Validation failed for method='public java.lang.String java.lang.String.substring(int)'. Error count: 1");
@ -358,7 +363,7 @@ class DefaultErrorAttributesTests {
this.errorAttributes = new DefaultErrorAttributes(); this.errorAttributes = new DefaultErrorAttributes();
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
ServerRequest serverRequest = buildServerRequest(request, error); ServerRequest serverRequest = buildServerRequest(request, error);
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest, Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest,
ErrorAttributeOptions.defaults().excluding(Include.STATUS)); ErrorAttributeOptions.defaults().excluding(Include.STATUS));
assertThat(attributes).doesNotContainKey("status"); assertThat(attributes).doesNotContainKey("status");
} }
@ -370,7 +375,7 @@ class DefaultErrorAttributesTests {
this.errorAttributes = new DefaultErrorAttributes(); this.errorAttributes = new DefaultErrorAttributes();
MockServerHttpRequest request = MockServerHttpRequest.get("/test").build(); MockServerHttpRequest request = MockServerHttpRequest.get("/test").build();
ServerRequest serverRequest = buildServerRequest(request, error); ServerRequest serverRequest = buildServerRequest(request, error);
Map<String, Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest, Map<String, @Nullable Object> attributes = this.errorAttributes.getErrorAttributes(serverRequest,
ErrorAttributeOptions.defaults().excluding(Include.ERROR)); ErrorAttributeOptions.defaults().excluding(Include.ERROR));
assertThat(attributes).doesNotContainKey("error"); assertThat(attributes).doesNotContainKey("error");
} }

Loading…
Cancel
Save