/*
* Hibernate Validator, declare and validate application constraints
*
* License: Apache License, Version 2.0
* See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
*/
package org.hibernate.validator.test.internal.engine.methodvalidation;
import java.util.Set;
import javax.validation.ConstraintDeclarationException;
import javax.validation.ConstraintViolation;
import javax.validation.Valid;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import org.testng.annotations.Test;
import org.hibernate.validator.HibernateValidator;
import org.hibernate.validator.HibernateValidatorConfiguration;
import org.hibernate.validator.testutil.ConstraintViolationAssert;
/**
* Integration test for {@link org.hibernate.validator.internal.engine.ValidatorImpl} which tests that illegal method parameter constraints are properly allowed
* when relaxed constraint properties are in effect.
*
* @author Chris Beckey <cbeckey@paypal.com>
*/
public class RelaxedMethodParameterConstraintsTest {
/**
* The converse of disallowParameterConstraintsAddedInSubType,
* relaxes constraint.
*/
@Test
public void allowParameterConstraintsAddedInSubType() {
HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ).configure();
configuration.allowOverridingMethodAlterParameterConstraint( true );
ValidatorFactory factory = configuration.buildValidatorFactory();
Validator validator = factory.getValidator();
Set<? extends ConstraintViolation<?>> violations = validator.forExecutables().validateParameters(
new RealizationWithMethodParameterConstraint(),
RealizationWithMethodParameterConstraint.class.getDeclaredMethods()[0],
new Object[] { "foo" }
);
ConstraintViolationAssert.assertNumberOfViolations( violations, 0 );
configuration.allowOverridingMethodAlterParameterConstraint( false );
}
@Test(expectedExceptions = { ConstraintDeclarationException.class })
public void disallowStrengtheningInSubType() {
HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ).configure();
ValidatorFactory factory = configuration.buildValidatorFactory();
Validator validator = factory.getValidator();
@SuppressWarnings("unused")
Set<ConstraintViolation<RealizationWithAdditionalMethodParameterConstraint>> violations = validator.forExecutables()
.validateParameters(
new RealizationWithAdditionalMethodParameterConstraint(),
RealizationWithAdditionalMethodParameterConstraint.class.getDeclaredMethods()[0],
new Object[] {}
);
}
@Test
public void allowStrengtheningInSubType() {
HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ).configure();
configuration.allowOverridingMethodAlterParameterConstraint( true );
ValidatorFactory factory = configuration.buildValidatorFactory();
Validator validator = factory.getValidator();
Set<ConstraintViolation<RealizationWithAdditionalMethodParameterConstraint>> violations =
validator.forExecutables().validateParameters(
new RealizationWithAdditionalMethodParameterConstraint(),
RealizationWithAdditionalMethodParameterConstraint.class.getDeclaredMethods()[0],
new Object[] { "foo" }
);
ConstraintViolationAssert.assertNumberOfViolations( violations, 0 );
configuration.allowOverridingMethodAlterParameterConstraint( false );
}
@Test(expectedExceptions = ConstraintDeclarationException.class, expectedExceptionsMessageRegExp = "HV000131.*")
public void disallowValidAddedInSubType() {
HibernateValidatorConfiguration configuration = Validation.byProvider( HibernateValidator.class ).configure();
ValidatorFactory factory = configuration.buildValidatorFactory();
Validator validator = factory.getValidator();
validator.forExecutables().validateParameters(
new SubRealizationWithValidConstraintOnMethodParameter(),
SubRealizationWithValidConstraintOnMethodParameter.class.getDeclaredMethods()[0],
new Object[] {}
);
}
@Test
public void allowValidAddedInSubType() {
HibernateValidatorConfiguration configure = Validation.byProvider( HibernateValidator.class ).configure();
configure.allowMultipleCascadedValidationOnReturnValues( true );
ValidatorFactory factory = configure.buildValidatorFactory();
Validator validator = factory.getValidator();
validator.forExecutables().validateParameters(
new SubRealizationWithValidConstraintOnMethodParameter(),
SubRealizationWithValidConstraintOnMethodParameter.class.getDeclaredMethods()[0],
new Object[] { "foo" }
);
configure.allowMultipleCascadedValidationOnReturnValues( false );
}
@Test(expectedExceptions = ConstraintDeclarationException.class, expectedExceptionsMessageRegExp = "HV000152.*")
public void disallowParameterConstraintsInHierarchyWithMultipleRootMethods() {
HibernateValidatorConfiguration configure = Validation.byProvider( HibernateValidator.class ).configure();
ValidatorFactory factory = configure.buildValidatorFactory();
Validator validator = factory.getValidator();
validator.forExecutables().validateParameters(
new RealizationOfTwoInterface(),
RealizationOfTwoInterface.class.getDeclaredMethods()[0],
new Object[] {}
);
}
@Test
public void allowParameterConstraintsInHierarchyWithMultipleRootMethods() {
HibernateValidatorConfiguration configure = Validation.byProvider( HibernateValidator.class ).configure();
configure.allowParallelMethodsDefineParameterConstraints( true );
ValidatorFactory factory = configure.buildValidatorFactory();
Validator validator = factory.getValidator();
validator.forExecutables().validateParameters(
new RealizationOfTwoInterface(),
RealizationOfTwoInterface.class.getDeclaredMethods()[0],
new Object[] { "foo" }
);
configure.allowParallelMethodsDefineParameterConstraints( false );
}
private interface InterfaceWithNoConstraints {
String foo(String s);
}
private interface AnotherInterfaceWithMethodParameterConstraint {
String foo(@NotNull String s);
}
private static class RealizationWithMethodParameterConstraint implements InterfaceWithNoConstraints {
/**
* Adds constraints to an un-constrained method from a super-type, which is not allowed.
*/
@Override
public String foo(@NotNull String s) {
return "Hello World";
}
}
private static class RealizationWithValidConstraintOnMethodParameter
implements InterfaceWithNoConstraints {
/**
* Adds @Valid to an un-constrained method from a super-type, which is not allowed.
*/
@Override
@Valid
public String foo(String s) {
return "Hello Valid World";
}
}
private static class SubRealizationWithValidConstraintOnMethodParameter
extends RealizationWithValidConstraintOnMethodParameter {
/**
* Adds @Valid to an un-constrained method from a super-type, which is not allowed.
*/
@Override
@Valid
public String foo(String s) {
return "Hello Valid World";
}
}
private static class RealizationOfTwoInterface
implements InterfaceWithNoConstraints, AnotherInterfaceWithMethodParameterConstraint {
/**
* Implement a method that is declared by two interfaces, one of which has a constraint
*/
@Override
public String foo(String s) {
return "Hello World";
}
}
private interface InterfaceWithNotNullMethodParameterConstraint {
void bar(@NotNull String s);
}
private static class RealizationWithAdditionalMethodParameterConstraint
implements InterfaceWithNotNullMethodParameterConstraint {
/**
* Adds constraints to a constrained method from a super-type, which is not allowed.
*/
@Override
public void bar(@Size(min = 3) String s) {
}
}
}