BindingResult for resolved async attributes
ViewResolutionResultHandler no longer adds BindingResult objects for async model attributes. Instead AbstractView adds them later when those attributes are resolved to concrete values. Closes gh-22933
This commit is contained in:
@@ -17,8 +17,8 @@
|
||||
package org.springframework.web.reactive.result.view;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
@@ -29,14 +29,15 @@ import reactor.core.publisher.Mono;
|
||||
import reactor.test.StepVerifier;
|
||||
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.lang.Nullable;
|
||||
import org.springframework.mock.http.server.reactive.test.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.test.server.MockServerWebExchange;
|
||||
import org.springframework.tests.sample.beans.TestBean;
|
||||
import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.reactive.BindingContext;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AbstractView}.
|
||||
@@ -54,25 +55,31 @@ public class AbstractViewTests {
|
||||
|
||||
TestBean testBean1 = new TestBean("Bean1");
|
||||
TestBean testBean2 = new TestBean("Bean2");
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
attributes.put("attr1", Mono.just(testBean1).delayElement(Duration.ofMillis(10)));
|
||||
attributes.put("attr2", Flux.just(testBean1, testBean2).delayElements(Duration.ofMillis(10)));
|
||||
attributes.put("attr3", Single.just(testBean2));
|
||||
attributes.put("attr4", Observable.just(testBean1, testBean2));
|
||||
attributes.put("attr5", Mono.empty());
|
||||
|
||||
Map<String, Object> inMap = new HashMap<>();
|
||||
inMap.put("attr1", Mono.just(testBean1).delayElement(Duration.ofMillis(10)));
|
||||
inMap.put("attr2", Flux.just(testBean1, testBean2).delayElements(Duration.ofMillis(10)));
|
||||
inMap.put("attr3", Single.just(testBean2));
|
||||
inMap.put("attr4", Observable.just(testBean1, testBean2));
|
||||
inMap.put("attr5", Mono.empty());
|
||||
|
||||
this.exchange.getAttributes().put(View.BINDING_CONTEXT_ATTRIBUTE, new BindingContext());
|
||||
|
||||
TestView view = new TestView();
|
||||
StepVerifier.create(
|
||||
view.render(attributes, null, this.exchange)).verifyComplete();
|
||||
StepVerifier.create(view.render(inMap, null, this.exchange)).verifyComplete();
|
||||
|
||||
Map<String, Object> actual = view.attributes;
|
||||
assertEquals(testBean1, actual.get("attr1"));
|
||||
assertArrayEquals(new TestBean[] { testBean1, testBean2 },
|
||||
((List<TestBean>) actual.get("attr2")).toArray());
|
||||
assertEquals(testBean2, actual.get("attr3"));
|
||||
assertArrayEquals(new TestBean[] { testBean1, testBean2 },
|
||||
((List<TestBean>) actual.get("attr4")).toArray());
|
||||
assertNull(actual.get("attr5"));
|
||||
Map<String, Object> outMap = view.attributes;
|
||||
assertEquals(testBean1, outMap.get("attr1"));
|
||||
assertEquals(Arrays.asList(testBean1, testBean2), outMap.get("attr2"));
|
||||
assertEquals(testBean2, outMap.get("attr3"));
|
||||
assertEquals(Arrays.asList(testBean1, testBean2), outMap.get("attr4"));
|
||||
assertNull(outMap.get("attr5"));
|
||||
|
||||
assertNotNull(outMap.get(BindingResult.MODEL_KEY_PREFIX + "attr1"));
|
||||
assertNotNull(outMap.get(BindingResult.MODEL_KEY_PREFIX + "attr3"));
|
||||
assertNull(outMap.get(BindingResult.MODEL_KEY_PREFIX + "attr2"));
|
||||
assertNull(outMap.get(BindingResult.MODEL_KEY_PREFIX + "attr4"));
|
||||
assertNull(outMap.get(BindingResult.MODEL_KEY_PREFIX + "attr5"));
|
||||
}
|
||||
|
||||
private static class TestView extends AbstractView {
|
||||
@@ -81,7 +88,7 @@ public class AbstractViewTests {
|
||||
|
||||
@Override
|
||||
protected Mono<Void> renderInternal(Map<String, Object> renderAttributes,
|
||||
MediaType contentType, ServerWebExchange exchange) {
|
||||
@Nullable MediaType contentType, ServerWebExchange exchange) {
|
||||
|
||||
this.attributes = renderAttributes;
|
||||
return Mono.empty();
|
||||
|
||||
Reference in New Issue
Block a user