/* * 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) { } } }