Merge branch '6.1.x'

This commit is contained in:
rstoyanchev 2024-06-28 15:35:13 +01:00
commit acb427d460
2 changed files with 34 additions and 18 deletions

View File

@ -174,7 +174,7 @@ public class MethodValidationInterceptor implements MethodInterceptor {
Object returnValue = invocation.proceed();
if (this.adaptViolations) {
this.validationAdapter.applyReturnValueValidation(target, method, null, arguments, groups);
this.validationAdapter.applyReturnValueValidation(target, method, null, returnValue, groups);
}
else {
violations = this.validationAdapter.invokeValidatorForReturnValue(target, method, returnValue, groups);

View File

@ -20,7 +20,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
import jakarta.validation.ValidationException;
import jakarta.validation.ConstraintViolationException;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.NotNull;
@ -28,6 +29,8 @@ import jakarta.validation.groups.Default;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.beans.MutablePropertyValues;
@ -46,6 +49,7 @@ import org.springframework.scheduling.annotation.AsyncAnnotationBeanPostProcesso
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.validation.method.MethodValidationException;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@ -59,27 +63,39 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*/
class MethodValidationProxyTests {
@Test
@ParameterizedTest
@ValueSource(booleans = {true, false})
@SuppressWarnings("unchecked")
public void testMethodValidationInterceptor() {
void testMethodValidationInterceptor(boolean adaptViolations) {
MyValidBean bean = new MyValidBean();
ProxyFactory factory = new ProxyFactory(bean);
factory.addAdvice(new MethodValidationInterceptor());
factory.addAdvice(adaptViolations ?
new MethodValidationInterceptor(() -> Validation.buildDefaultValidatorFactory().getValidator(), true) :
new MethodValidationInterceptor());
factory.addAdvisor(new AsyncAnnotationAdvisor());
doTestProxyValidation((MyValidInterface<String>) factory.getProxy());
doTestProxyValidation((MyValidInterface<String>) factory.getProxy(),
(adaptViolations ? MethodValidationException.class : ConstraintViolationException.class));
}
@Test
@ParameterizedTest
@ValueSource(booleans = {true, false})
@SuppressWarnings("unchecked")
public void testMethodValidationPostProcessor() {
void testMethodValidationPostProcessor(boolean adaptViolations) {
StaticApplicationContext context = new StaticApplicationContext();
context.registerSingleton("mvpp", MethodValidationPostProcessor.class);
context.registerBean(MethodValidationPostProcessor.class, adaptViolations ?
() -> {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setAdaptConstraintViolations(true);
return postProcessor;
} :
MethodValidationPostProcessor::new);
MutablePropertyValues pvs = new MutablePropertyValues();
pvs.add("beforeExistingAdvisors", false);
context.registerSingleton("aapp", AsyncAnnotationBeanPostProcessor.class, pvs);
context.registerSingleton("bean", MyValidBean.class);
context.refresh();
doTestProxyValidation(context.getBean("bean", MyValidInterface.class));
doTestProxyValidation(context.getBean("bean", MyValidInterface.class),
adaptViolations ? MethodValidationException.class : ConstraintViolationException.class);
context.close();
}
@ -91,21 +107,21 @@ class MethodValidationProxyTests {
context.registerBean(MyValidInterface.class, () ->
ProxyFactory.getProxy(MyValidInterface.class, new MyValidClientInterfaceMethodInterceptor()));
context.refresh();
doTestProxyValidation(context.getBean(MyValidInterface.class));
doTestProxyValidation(context.getBean(MyValidInterface.class), ConstraintViolationException.class);
context.close();
}
@SuppressWarnings("DataFlowIssue")
private void doTestProxyValidation(MyValidInterface<String> proxy) {
private void doTestProxyValidation(MyValidInterface<String> proxy, Class<? extends Exception> expectedExceptionClass) {
assertThat(proxy.myValidMethod("value", 5)).isNotNull();
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod("value", 15));
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod(null, 5));
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidMethod("value", 0));
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod("value", 15));
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod(null, 5));
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidMethod("value", 0));
proxy.myValidAsyncMethod("value", 5);
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidAsyncMethod("value", 15));
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myValidAsyncMethod(null, 5));
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidAsyncMethod("value", 15));
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myValidAsyncMethod(null, 5));
assertThat(proxy.myGenericMethod("myValue")).isEqualTo("myValue");
assertThatExceptionOfType(ValidationException.class).isThrownBy(() -> proxy.myGenericMethod(null));
assertThatExceptionOfType(expectedExceptionClass).isThrownBy(() -> proxy.myGenericMethod(null));
}
@Test