@ -1,5 +1,5 @@
/ *
/ *
* Copyright 2002 - 2020 the original author or authors .
* Copyright 2002 - 2021 the original author or authors .
*
*
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* you may not use this file except in compliance with the License .
@ -21,6 +21,8 @@ import java.time.Duration;
import java.util.Map ;
import java.util.Map ;
import java.util.function.Function ;
import java.util.function.Function ;
import javax.validation.constraints.NotEmpty ;
import io.reactivex.rxjava3.core.Single ;
import io.reactivex.rxjava3.core.Single ;
import org.junit.jupiter.api.BeforeEach ;
import org.junit.jupiter.api.BeforeEach ;
import org.junit.jupiter.api.Test ;
import org.junit.jupiter.api.Test ;
@ -49,16 +51,17 @@ import static org.assertj.core.api.Assertions.assertThat;
*
*
* @author Rossen Stoyanchev
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Juergen Hoeller
* @author Sam Brannen
* /
* /
public class ModelAttributeMethodArgumentResolverTests {
class ModelAttributeMethodArgumentResolverTests {
private BindingContext bindContext ;
private final ResolvableMethod testMethod = ResolvableMethod . on ( getClass ( ) ) . named ( "handle" ) . build ( ) ;
private ResolvableMethod testMethod = ResolvableMethod . on ( getClass ( ) ) . named ( "handle" ) . build ( ) ;
private BindingContext bindContext ;
@BeforeEach
@BeforeEach
public void setup ( ) throws Exception {
void setup ( ) {
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ( ) ;
LocalValidatorFactoryBean validator = new LocalValidatorFactoryBean ( ) ;
validator . afterPropertiesSet ( ) ;
validator . afterPropertiesSet ( ) ;
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer ( ) ;
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer ( ) ;
@ -68,32 +71,38 @@ public class ModelAttributeMethodArgumentResolverTests {
@Test
@Test
public void supports ( ) throws Exception {
void supports ( ) {
ModelAttributeMethodArgumentResolver resolver =
ModelAttributeMethodArgumentResolver resolver =
new ModelAttributeMethodArgumentResolver ( ReactiveAdapterRegistry . getSharedInstance ( ) , false ) ;
new ModelAttributeMethodArgumentResolver ( ReactiveAdapterRegistry . getSharedInstance ( ) , false ) ;
MethodParameter param = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Fo o. class ) ;
MethodParameter param = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Poj o. class ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
param = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Mono . class , Fo o. class ) ;
param = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( NonBindingPoj o. class ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Foo . class ) ;
param = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Mono . class , Pojo . class ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
param = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Mono . class , NonBindingPojo . class ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Pojo . class ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isFalse ( ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isFalse ( ) ;
param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Foo . class ) ;
param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Poj o. class ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isFalse ( ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isFalse ( ) ;
}
}
@Test
@Test
public void supportsWithDefaultResolution ( ) throws Exception {
void supportsWithDefaultResolution ( ) {
ModelAttributeMethodArgumentResolver resolver =
ModelAttributeMethodArgumentResolver resolver =
new ModelAttributeMethodArgumentResolver ( ReactiveAdapterRegistry . getSharedInstance ( ) , true ) ;
new ModelAttributeMethodArgumentResolver ( ReactiveAdapterRegistry . getSharedInstance ( ) , true ) ;
MethodParameter param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Fo o. class ) ;
MethodParameter param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Poj o. class ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Fo o. class ) ;
param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Poj o. class ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
assertThat ( resolver . supportsParameter ( param ) ) . isTrue ( ) ;
param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( String . class ) ;
param = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( String . class ) ;
@ -104,204 +113,286 @@ public class ModelAttributeMethodArgumentResolverTests {
}
}
@Test
@Test
public void createAndBind ( ) throws Exception {
void createAndBind ( ) throws Exception {
testBindFoo ( "fo o" , this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Fo o. class ) , value - > {
testBindPojo ( "poj o" , this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Poj o. class ) , value - > {
assertThat ( value . getClass ( ) ) . isEqualTo ( Fo o. class ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Poj o. class ) ;
return ( Fo o) value ;
return ( Poj o) value ;
} ) ;
} ) ;
}
}
@Test
@Test
public void createAndBindToMono ( ) throws Exception {
void createAndBindToMono ( ) throws Exception {
MethodParameter parameter = this . testMethod
MethodParameter parameter = this . testMethod
. annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Fo o. class ) ;
. annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Poj o. class ) ;
testBindFoo ( "fooMono" , parameter , mono - > {
testBindPojo ( "pojoMono" , parameter , mono - > {
boolean condition = mono instanceof Mono ;
assertThat ( mono ) . isInstanceOf ( Mono . class ) ;
assertThat ( condition ) . as ( mono . getClass ( ) . getName ( ) ) . isTrue ( ) ;
Object value = ( ( Mono < ? > ) mono ) . block ( Duration . ofSeconds ( 5 ) ) ;
Object value = ( ( Mono < ? > ) mono ) . block ( Duration . ofSeconds ( 5 ) ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Fo o. class ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Poj o. class ) ;
return ( Fo o) value ;
return ( Poj o) value ;
} ) ;
} ) ;
}
}
@Test
@Test
public void createAndBindToSingle ( ) throws Exception {
void createAndBindToSingle ( ) throws Exception {
MethodParameter parameter = this . testMethod
MethodParameter parameter = this . testMethod
. annotPresent ( ModelAttribute . class ) . arg ( Single . class , Fo o. class ) ;
. annotPresent ( ModelAttribute . class ) . arg ( Single . class , Poj o. class ) ;
testBindFoo ( "fooSingle" , parameter , single - > {
testBindPojo ( "pojoSingle" , parameter , single - > {
boolean condition = single instanceof Single ;
assertThat ( single ) . isInstanceOf ( Single . class ) ;
assertThat ( condition ) . as ( single . getClass ( ) . getName ( ) ) . isTrue ( ) ;
Object value = ( ( Single < ? > ) single ) . blockingGet ( ) ;
Object value = ( ( Single < ? > ) single ) . blockingGet ( ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Fo o. class ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Poj o. class ) ;
return ( Fo o) value ;
return ( Poj o) value ;
} ) ;
} ) ;
}
}
@Test
@Test
public void bindExisting ( ) throws Exception {
void createButDoNotBind ( ) throws Exception {
Foo foo = new Foo ( ) ;
MethodParameter parameter =
foo . setName ( "Jim" ) ;
this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( NonBindingPojo . class ) ;
this . bindContext . getModel ( ) . addAttribute ( foo ) ;
createButDoNotBindToPojo ( "nonBindingPojo" , parameter , value - > {
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Foo . class ) ;
assertThat ( value ) . isInstanceOf ( NonBindingPojo . class ) ;
testBindFoo ( "foo" , parameter , value - > {
return ( NonBindingPojo ) value ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Foo . class ) ;
return ( Foo ) value ;
} ) ;
} ) ;
}
assertThat ( this . bindContext . getModel ( ) . asMap ( ) . get ( "foo" ) ) . isSameAs ( foo ) ;
@Test
void createButDoNotBindToMono ( ) throws Exception {
MethodParameter parameter =
this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Mono . class , NonBindingPojo . class ) ;
createButDoNotBindToPojo ( "nonBindingPojoMono" , parameter , value - > {
assertThat ( value ) . isInstanceOf ( Mono . class ) ;
Object extractedValue = ( ( Mono < ? > ) value ) . block ( Duration . ofSeconds ( 5 ) ) ;
assertThat ( extractedValue ) . isInstanceOf ( NonBindingPojo . class ) ;
return ( NonBindingPojo ) extractedValue ;
} ) ;
}
}
@Test
@Test
public void bindExistingMono ( ) throws Exception {
void createButDoNotBindToSingle ( ) throws Exception {
Foo foo = new Foo ( ) ;
MethodParameter parameter =
foo . setName ( "Jim" ) ;
this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Single . class , NonBindingPojo . class ) ;
this . bindContext . getModel ( ) . addAttribute ( "fooMono" , Mono . just ( foo ) ) ;
createButDoNotBindToPojo ( "nonBindingPojoSingle" , parameter , value - > {
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Foo . class ) ;
assertThat ( value ) . isInstanceOf ( Single . class ) ;
testBindFoo ( "foo" , parameter , value - > {
Object extractedValue = ( ( Single < ? > ) value ) . blockingGet ( ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Fo o. class ) ;
assertThat ( extractedValue ) . isInstanceOf ( NonBindingPoj o. class ) ;
return ( Foo ) v alue;
return ( NonBindingPojo ) extractedV alue;
} ) ;
} ) ;
}
private void createButDoNotBindToPojo ( String modelKey , MethodParameter methodParameter ,
Function < Object , NonBindingPojo > valueExtractor ) throws Exception {
Object value = createResolver ( )
. resolveArgument ( methodParameter , this . bindContext , postForm ( "name=Enigma" ) )
. block ( Duration . ZERO ) ;
NonBindingPojo nonBindingPojo = valueExtractor . apply ( value ) ;
assertThat ( nonBindingPojo ) . isNotNull ( ) ;
assertThat ( nonBindingPojo . getName ( ) ) . isNull ( ) ;
assertThat ( this . bindContext . getModel ( ) . asMap ( ) . get ( "foo" ) ) . isSameAs ( foo ) ;
String bindingResultKey = BindingResult . MODEL_KEY_PREFIX + modelKey ;
Map < String , Object > model = bindContext . getModel ( ) . asMap ( ) ;
assertThat ( model ) . hasSize ( 2 ) ;
assertThat ( model . get ( modelKey ) ) . isSameAs ( nonBindingPojo ) ;
assertThat ( model . get ( bindingResultKey ) ) . isInstanceOf ( BindingResult . class ) ;
}
}
@Test
@Test
public void bindExistingSingle ( ) throws Exception {
void bindExisting ( ) throws Exception {
Foo foo = new Foo ( ) ;
Pojo pojo = new Poj o( ) ;
foo . setName ( "Jim" ) ;
poj o. setName ( "Jim" ) ;
this . bindContext . getModel ( ) . addAttribute ( "fooSingle" , Single . just ( foo ) ) ;
this . bindContext . getModel ( ) . addAttribute ( po jo ) ;
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Foo . class ) ;
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Poj o. class ) ;
testBindFoo ( "foo" , parameter , value - > {
testBindPojo ( "poj o" , parameter , value - > {
assertThat ( value . getClass ( ) ) . isEqualTo ( Fo o. class ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Poj o. class ) ;
return ( Fo o) value ;
return ( Poj o) value ;
} ) ;
} ) ;
assertThat ( this . bindContext . getModel ( ) . asMap ( ) . get ( "fo o" ) ) . isSameAs ( fo o) ;
assertThat ( this . bindContext . getModel ( ) . asMap ( ) . get ( "poj o" ) ) . isSameAs ( poj o) ;
}
}
@Test
@Test
public void bindExistingMonoToMono ( ) throws Exception {
void bindExistingMono ( ) throws Exception {
Foo foo = new Foo ( ) ;
Pojo pojo = new Pojo ( ) ;
foo . setName ( "Jim" ) ;
pojo . setName ( "Jim" ) ;
String modelKey = "fooMono" ;
this . bindContext . getModel ( ) . addAttribute ( "pojoMono" , Mono . just ( pojo ) ) ;
this . bindContext . getModel ( ) . addAttribute ( modelKey , Mono . just ( foo ) ) ;
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Pojo . class ) ;
testBindPojo ( "pojo" , parameter , value - > {
assertThat ( value . getClass ( ) ) . isEqualTo ( Pojo . class ) ;
return ( Pojo ) value ;
} ) ;
assertThat ( this . bindContext . getModel ( ) . asMap ( ) . get ( "pojo" ) ) . isSameAs ( pojo ) ;
}
@Test
void bindExistingSingle ( ) throws Exception {
Pojo pojo = new Pojo ( ) ;
pojo . setName ( "Jim" ) ;
this . bindContext . getModel ( ) . addAttribute ( "pojoSingle" , Single . just ( pojo ) ) ;
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Pojo . class ) ;
testBindPojo ( "pojo" , parameter , value - > {
assertThat ( value . getClass ( ) ) . isEqualTo ( Pojo . class ) ;
return ( Pojo ) value ;
} ) ;
assertThat ( this . bindContext . getModel ( ) . asMap ( ) . get ( "pojo" ) ) . isSameAs ( pojo ) ;
}
@Test
void bindExistingMonoToMono ( ) throws Exception {
Pojo pojo = new Pojo ( ) ;
pojo . setName ( "Jim" ) ;
String modelKey = "pojoMono" ;
this . bindContext . getModel ( ) . addAttribute ( modelKey , Mono . just ( pojo ) ) ;
MethodParameter parameter = this . testMethod
MethodParameter parameter = this . testMethod
. annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Foo . class ) ;
. annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Poj o. class ) ;
testBindFoo ( modelKey , parameter , mono - > {
testBindPojo ( modelKey , parameter , mono - > {
boolean condition = mono instanceof Mono ;
assertThat ( mono ) . isInstanceOf ( Mono . class ) ;
assertThat ( condition ) . as ( mono . getClass ( ) . getName ( ) ) . isTrue ( ) ;
Object value = ( ( Mono < ? > ) mono ) . block ( Duration . ofSeconds ( 5 ) ) ;
Object value = ( ( Mono < ? > ) mono ) . block ( Duration . ofSeconds ( 5 ) ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Foo . class ) ;
assertThat ( value . getClass ( ) ) . isEqualTo ( Poj o. class ) ;
return ( Foo ) value ;
return ( Poj o) value ;
} ) ;
} ) ;
}
}
private void testBindFoo ( String modelKey , MethodParameter param , Function < Object , Foo > valueExtractor )
private void testBindPoj o ( String modelKey , MethodParameter param , Function < Object , Poj o> valueExtractor )
throws Exception {
throws Exception {
Object value = createResolver ( )
Object value = createResolver ( )
. resolveArgument ( param , this . bindContext , postForm ( "name=Robert&age=25" ) )
. resolveArgument ( param , this . bindContext , postForm ( "name=Robert&age=25" ) )
. block ( Duration . ZERO ) ;
. block ( Duration . ZERO ) ;
Foo foo = valueExtractor . apply ( value ) ;
Pojo poj o = valueExtractor . apply ( value ) ;
assertThat ( foo . getName ( ) ) . isEqualTo ( "Robert" ) ;
assertThat ( poj o. getName ( ) ) . isEqualTo ( "Robert" ) ;
assertThat ( foo . getAge ( ) ) . isEqualTo ( 25 ) ;
assertThat ( poj o. getAge ( ) ) . isEqualTo ( 25 ) ;
String bindingResultKey = BindingResult . MODEL_KEY_PREFIX + modelKey ;
String bindingResultKey = BindingResult . MODEL_KEY_PREFIX + modelKey ;
Map < String , Object > map = bindContext . getModel ( ) . asMap ( ) ;
Map < String , Object > model = bindContext . getModel ( ) . asMap ( ) ;
assertThat ( map . size ( ) ) . as ( map . toString ( ) ) . isEqualTo ( 2 ) ;
assertThat ( model ) . hasSize ( 2 ) ;
assertThat ( map . get ( modelKey ) ) . isSameAs ( foo ) ;
assertThat ( model . get ( modelKey ) ) . isSameAs ( pojo ) ;
assertThat ( map . get ( bindingResultKey ) ) . isNotNull ( ) ;
assertThat ( model . get ( bindingResultKey ) ) . isInstanceOf ( BindingResult . class ) ;
boolean condition = map . get ( bindingResultKey ) instanceof BindingResult ;
assertThat ( condition ) . isTrue ( ) ;
}
}
@Test
@Test
public void validationError ( ) throws Exception {
void validationErrorForPojo ( ) throws Exception {
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Fo o. class ) ;
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Poj o. class ) ;
testValidationError ( parameter , Function . identity ( ) ) ;
testValidationError ( parameter , Function . identity ( ) ) ;
}
}
@Test
@Test
public void validationErrorTo Mono( ) throws Exception {
void validationErrorFor Mono( ) throws Exception {
MethodParameter parameter = this . testMethod
MethodParameter parameter = this . testMethod
. annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Fo o. class ) ;
. annotNotPresent ( ModelAttribute . class ) . arg ( Mono . class , Poj o. class ) ;
testValidationError ( parameter ,
testValidationError ( parameter ,
resolvedArgumentMono - > {
resolvedArgumentMono - > {
Object value = resolvedArgumentMono . block ( Duration . ofSeconds ( 5 ) ) ;
Object value = resolvedArgumentMono . block ( Duration . ofSeconds ( 5 ) ) ;
assertThat ( value ) . isNotNull ( ) ;
assertThat ( value ) . isInstanceOf ( Mono . class ) ;
boolean condition = value instanceof Mono ;
assertThat ( condition ) . isTrue ( ) ;
return ( Mono < ? > ) value ;
return ( Mono < ? > ) value ;
} ) ;
} ) ;
}
}
@Test
@Test
public void validationErrorTo Single( ) throws Exception {
void validationErrorFor Single( ) throws Exception {
MethodParameter parameter = this . testMethod
MethodParameter parameter = this . testMethod
. annotPresent ( ModelAttribute . class ) . arg ( Single . class , Fo o. class ) ;
. annotPresent ( ModelAttribute . class ) . arg ( Single . class , Poj o. class ) ;
testValidationError ( parameter ,
testValidationError ( parameter ,
resolvedArgumentMono - > {
resolvedArgumentMono - > {
Object value = resolvedArgumentMono . block ( Duration . ofSeconds ( 5 ) ) ;
Object value = resolvedArgumentMono . block ( Duration . ofSeconds ( 5 ) ) ;
assertThat ( value ) . isNotNull ( ) ;
assertThat ( value ) . isInstanceOf ( Single . class ) ;
boolean condition = value instanceof Single ;
assertThat ( condition ) . isTrue ( ) ;
return Mono . from ( ( ( Single < ? > ) value ) . toFlowable ( ) ) ;
return Mono . from ( ( ( Single < ? > ) value ) . toFlowable ( ) ) ;
} ) ;
} ) ;
}
}
private void testValidationError ( MethodParameter param , Function < Mono < ? > , Mono < ? > > valueMonoExtractor )
@Test
void validationErrorWithoutBindingForPojo ( ) throws Exception {
MethodParameter parameter = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( ValidatedPojo . class ) ;
testValidationErrorWithoutBinding ( parameter , Function . identity ( ) ) ;
}
@Test
void validationErrorWithoutBindingForMono ( ) throws Exception {
MethodParameter parameter = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Mono . class , ValidatedPojo . class ) ;
testValidationErrorWithoutBinding ( parameter , resolvedArgumentMono - > {
Object value = resolvedArgumentMono . block ( Duration . ofSeconds ( 5 ) ) ;
assertThat ( value ) . isInstanceOf ( Mono . class ) ;
return ( Mono < ? > ) value ;
} ) ;
}
@Test
void validationErrorWithoutBindingForSingle ( ) throws Exception {
MethodParameter parameter = this . testMethod . annotPresent ( ModelAttribute . class ) . arg ( Single . class , ValidatedPojo . class ) ;
testValidationErrorWithoutBinding ( parameter , resolvedArgumentMono - > {
Object value = resolvedArgumentMono . block ( Duration . ofSeconds ( 5 ) ) ;
assertThat ( value ) . isInstanceOf ( Single . class ) ;
return Mono . from ( ( ( Single < ? > ) value ) . toFlowable ( ) ) ;
} ) ;
}
private void testValidationError ( MethodParameter parameter , Function < Mono < ? > , Mono < ? > > valueMonoExtractor )
throws URISyntaxException {
testValidationError ( parameter , valueMonoExtractor , "age=invalid" , "age" , "invalid" ) ;
}
private void testValidationErrorWithoutBinding ( MethodParameter parameter , Function < Mono < ? > , Mono < ? > > valueMonoExtractor )
throws URISyntaxException {
throws URISyntaxException {
ServerWebExchange exchange = postForm ( "age=invalid" ) ;
testValidationError ( parameter , valueMonoExtractor , "name=Enigma" , "name" , null ) ;
Mono < ? > mono = createResolver ( ) . resolveArgument ( param , this . bindContext , exchange ) ;
}
private void testValidationError ( MethodParameter param , Function < Mono < ? > , Mono < ? > > valueMonoExtractor ,
String formData , String field , String rejectedValue ) throws URISyntaxException {
Mono < ? > mono = createResolver ( ) . resolveArgument ( param , this . bindContext , postForm ( formData ) ) ;
mono = valueMonoExtractor . apply ( mono ) ;
mono = valueMonoExtractor . apply ( mono ) ;
StepVerifier . create ( mono )
StepVerifier . create ( mono )
. consumeErrorWith ( ex - > {
. consumeErrorWith ( ex - > {
boolean condition = ex instanceof WebExchangeBindException ;
assertThat ( ex ) . isInstanceOf ( WebExchangeBindException . class ) ;
assertThat ( condition ) . isTrue ( ) ;
WebExchangeBindException bindException = ( WebExchangeBindException ) ex ;
WebExchangeBindException bindException = ( WebExchangeBindException ) ex ;
assertThat ( bindException . getErrorCount ( ) ) . isEqualTo ( 1 ) ;
assertThat ( bindException . getErrorCount ( ) ) . isEqualTo ( 1 ) ;
assertThat ( bindException . hasFieldErrors ( "age" ) ) . isTrue ( ) ;
assertThat ( bindException . hasFieldErrors ( field ) ) . isTrue ( ) ;
assertThat ( bindException . getFieldError ( field ) . getRejectedValue ( ) ) . isEqualTo ( rejectedValue ) ;
} )
} )
. verify ( ) ;
. verify ( ) ;
}
}
@Test
@Test
public void bindDataClass ( ) throws Exception {
void bindDataClass ( ) throws Exception {
testBindBar ( this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( Bar . class ) ) ;
MethodParameter parameter = this . testMethod . annotNotPresent ( ModelAttribute . class ) . arg ( DataClass . class ) ;
}
private void testBindBar ( MethodParameter param ) throws Exception {
Object value = createResolver ( )
Object value = createResolver ( )
. resolveArgument ( param , this . bindContext , postForm ( "name=Robert&age=25&count=1" ) )
. resolveArgument ( parameter , this . bindContext , postForm ( "name=Robert&age=25&count=1" ) )
. block ( Duration . ZERO ) ;
. block ( Duration . ZERO ) ;
Bar bar = ( Bar ) value ;
DataClass dataClass = ( DataClass ) value ;
assertThat ( bar . getName ( ) ) . isEqualTo ( "Robert" ) ;
assertThat ( dataClass . getName ( ) ) . isEqualTo ( "Robert" ) ;
assertThat ( bar . getAge ( ) ) . isEqualTo ( 25 ) ;
assertThat ( dataClass . getAge ( ) ) . isEqualTo ( 25 ) ;
assertThat ( bar . getCount ( ) ) . isEqualTo ( 1 ) ;
assertThat ( dataClass . getCount ( ) ) . isEqualTo ( 1 ) ;
String key = "bar" ;
String modelKey = "dataClass ";
String bindingResultKey = BindingResult . MODEL_KEY_PREFIX + key ;
String bindingResultKey = BindingResult . MODEL_KEY_PREFIX + modelK ey;
Map < String , Object > map = bindContext . getModel ( ) . asMap ( ) ;
Map < String , Object > model = bindContext . getModel ( ) . asMap ( ) ;
assertThat ( map . size ( ) ) . as ( map . toString ( ) ) . isEqualTo ( 2 ) ;
assertThat ( model ) . hasSize ( 2 ) ;
assertThat ( map . get ( key ) ) . isSameAs ( bar ) ;
assertThat ( model . get ( modelKey ) ) . isSameAs ( dataClass ) ;
assertThat ( map . get ( bindingResultKey ) ) . isNotNull ( ) ;
assertThat ( model . get ( bindingResultKey ) ) . isInstanceOf ( BindingResult . class ) ;
boolean condition = map . get ( bindingResultKey ) instanceof BindingResult ;
assertThat ( condition ) . isTrue ( ) ;
}
}
// TODO: SPR-15871, SPR-15542
// TODO: SPR-15871, SPR-15542
@ -320,31 +411,30 @@ public class ModelAttributeMethodArgumentResolverTests {
@SuppressWarnings ( "unused" )
@SuppressWarnings ( "unused" )
void handle (
void handle (
@ModelAttribute @Validated Foo foo ,
@ModelAttribute @Validated Pojo pojo ,
@ModelAttribute @Validated Mono < Foo > mono ,
@ModelAttribute @Validated Mono < Pojo > mono ,
@ModelAttribute @Validated Single < Foo > single ,
@ModelAttribute @Validated Single < Pojo > single ,
Foo fooNotAnnotated ,
@ModelAttribute ( binding = false ) NonBindingPojo nonBindingPojo ,
@ModelAttribute ( binding = false ) Mono < NonBindingPojo > monoNonBindingPojo ,
@ModelAttribute ( binding = false ) Single < NonBindingPojo > singleNonBindingPojo ,
@ModelAttribute ( binding = false ) @Validated ValidatedPojo validatedPojo ,
@ModelAttribute ( binding = false ) @Validated Mono < ValidatedPojo > monoValidatedPojo ,
@ModelAttribute ( binding = false ) @Validated Single < ValidatedPojo > singleValidatedPojo ,
Pojo pojoNotAnnotated ,
String stringNotAnnotated ,
String stringNotAnnotated ,
Mono < Foo > monoNotAnnotated ,
Mono < Poj o> monoNotAnnotated ,
Mono < String > monoStringNotAnnotated ,
Mono < String > monoStringNotAnnotated ,
Bar barNotAnnotated ) {
DataClass dataClass NotAnnotated) {
}
}
@SuppressWarnings ( "unused" )
@SuppressWarnings ( "unused" )
private static class Fo o {
private static class Poj o {
private String name ;
private String name ;
private int age ;
private int age ;
public Foo ( ) {
}
public Foo ( String name ) {
this . name = name ;
}
public String getName ( ) {
public String getName ( ) {
return name ;
return name ;
}
}
@ -364,7 +454,48 @@ public class ModelAttributeMethodArgumentResolverTests {
@SuppressWarnings ( "unused" )
@SuppressWarnings ( "unused" )
private static class Bar {
private static class NonBindingPojo {
private String name ;
public String getName ( ) {
return this . name ;
}
public void setName ( String name ) {
this . name = name ;
}
@Override
public String toString ( ) {
return "NonBindingPojo [name=" + name + "]" ;
}
}
@SuppressWarnings ( "unused" )
private static class ValidatedPojo {
@NotEmpty
private String name ;
public String getName ( ) {
return this . name ;
}
public void setName ( String name ) {
this . name = name ;
}
@Override
public String toString ( ) {
return "ValidatedPojo [name=" + name + "]" ;
}
}
@SuppressWarnings ( "unused" )
private static class DataClass {
private final String name ;
private final String name ;
@ -372,7 +503,7 @@ public class ModelAttributeMethodArgumentResolverTests {
private int count ;
private int count ;
public Bar ( String name , int age ) {
public DataClass ( String name , int age ) {
this . name = name ;
this . name = name ;
this . age = age ;
this . age = age ;
}
}