Package org.hibernate.validator.test.internal.engine.methodvalidation

Source Code of org.hibernate.validator.test.internal.engine.methodvalidation.AbstractMethodValidationTest

/*
* 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.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.validation.ConstraintDeclarationException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.ElementKind;
import javax.validation.Path;
import javax.validation.Path.ParameterNode;
import javax.validation.Validator;
import javax.validation.constraints.NotNull;

import org.joda.time.DateMidnight;
import org.testng.annotations.Test;

import org.hibernate.validator.test.internal.engine.methodvalidation.model.Address;
import org.hibernate.validator.test.internal.engine.methodvalidation.model.Customer;
import org.hibernate.validator.test.internal.engine.methodvalidation.service.ConsistentDateParameters;
import org.hibernate.validator.test.internal.engine.methodvalidation.service.CustomerRepository;
import org.hibernate.validator.test.internal.engine.methodvalidation.service.CustomerRepositoryImpl;
import org.hibernate.validator.test.internal.engine.methodvalidation.service.CustomerRepositoryWithConstrainedVoidMethod;
import org.hibernate.validator.test.internal.engine.methodvalidation.service.CustomerRepositoryWithConstrainedVoidMethodImpl;
import org.hibernate.validator.test.internal.engine.methodvalidation.service.RepositoryBase;
import org.hibernate.validator.testutil.TestForIssue;

import static org.fest.assertions.Assertions.assertThat;
import static org.hibernate.validator.internal.util.CollectionHelper.newHashMap;
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertConstraintViolation;
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertCorrectConstraintViolationMessages;
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNodeKinds;
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNodeNames;
import static org.hibernate.validator.testutil.ConstraintViolationAssert.assertNumberOfViolations;
import static org.hibernate.validator.testutil.ValidatorUtil.getValidatingProxy;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.fail;

/**
* Integration test for the method-level validation related features of {@link org.hibernate.validator.internal.engine.ValidatorImpl}.
*
* @author Gunnar Morling
* @author Hardy Ferentschik
*/
@Test
public abstract class AbstractMethodValidationTest {
  protected CustomerRepository customerRepository;
  protected RepositoryBase<Customer> repositoryBase;
  protected Validator validator;

  protected abstract void setUp();

  protected abstract String messagePrefix();

  protected void createProxy(Class<?>... groups) {
    customerRepository = getValidatingProxy(
        new CustomerRepositoryImpl(), validator, groups
    );
    repositoryBase = customerRepository;
  }

  @Test
  public void methodValidationYieldsConstraintViolation() {
    try {
      customerRepository.findCustomerByName( null );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {

      Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
      assertNumberOfViolations( constraintViolations, 1 );

      ConstraintViolation<?> constraintViolation = constraintViolations.iterator().next();

      assertConstraintViolation(
          constraintViolation,
          messagePrefix() + "may not be null",
          CustomerRepositoryImpl.class,
          null
      );
      assertEquals(
          constraintViolation.getConstraintDescriptor().getAnnotation().annotationType(), NotNull.class
      );
      assertMethod( constraintViolation, "findCustomerByName", String.class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "findCustomerByName.arg0"
      );
      assertEquals( constraintViolation.getLeafBean(), customerRepository );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), new Object[] { null } );
      assertEquals( constraintViolation.getExecutableReturnValue(), null );
    }
  }

  @Test
  public void validationOfMethodWithMultipleParameters() {
    try {
      customerRepository.findCustomerByAgeAndName( 30, null );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "findCustomerByAgeAndName", Integer.class, String.class );
      assertParameterIndex( constraintViolation, 1 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "findCustomerByAgeAndName.arg1"
      );
      assertEquals( constraintViolation.getExecutableParameters(), new Object[] { 30, null } );
      assertEquals( constraintViolation.getExecutableReturnValue(), null );
    }
  }

  @Test
  public void constraintViolationsAtMultipleParameters() {
    try {
      customerRepository.findCustomerByAgeAndName( 1, null );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 2 );
      assertCorrectConstraintViolationMessages(
          e.getConstraintViolations(),
          messagePrefix() + "may not be null",
          messagePrefix() + "must be greater than or equal to 5"
      );
    }
  }

  @Test
  public void methodValidationWithCascadingParameter() {
    Customer customer = new Customer( null, null );
    try {
      customerRepository.persistCustomer( customer );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "persistCustomer", Customer.class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals(
          constraintViolation.getPropertyPath().toString(), "persistCustomer.arg0.name"
      );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getLeafBean(), customer );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), new Object[] { customer } );
      assertEquals( constraintViolation.getExecutableReturnValue(), null );
    }
  }

  @Test
  public void methodValidationWithCascadingParameterAndCascadingConstraint() {
    Address address = new Address( null );
    Customer customer = new Customer( "Bob", address );

    try {
      customerRepository.persistCustomer( customer );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "persistCustomer", Customer.class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "persistCustomer.arg0.address.city"
      );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getLeafBean(), address );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), new Object[] { customer } );
      assertEquals( constraintViolation.getExecutableReturnValue(), null );
    }
  }

  @Test
  public void cascadingMapParameter() {
    Map<String, Customer> customers = newHashMap();
    Customer bob = new Customer( null );
    customers.put( "Bob", bob );

    try {
      customerRepository.cascadingMapParameter( customers );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "cascadingMapParameter", Map.class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "cascadingMapParameter.arg0[Bob].name"
      );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getLeafBean(), bob );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), new Object[] { customers } );
      assertEquals( constraintViolation.getExecutableReturnValue(), null );
    }
  }

  @Test
  public void cascadingIterableParameter() {
    Customer customer = new Customer( null );
    List<Customer> customers = Arrays.asList( null, customer );

    try {
      customerRepository.cascadingIterableParameter( customers );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "cascadingIterableParameter", List.class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "cascadingIterableParameter.arg0[1].name"
      );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getLeafBean(), customer );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), new Object[] { customers } );
      assertEquals( constraintViolation.getExecutableReturnValue(), null );
    }
  }

  @Test
  public void cascadingArrayParameter() {
    Customer customer = new Customer( null );

    try {
      customerRepository.cascadingArrayParameter( null, customer );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "cascadingArrayParameter", Customer[].class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "cascadingArrayParameter.arg0[1].name"
      );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getLeafBean(), customer );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals(
          constraintViolation.getExecutableParameters(),
          new Object[] { new Object[] { null, customer } }
      );
      assertEquals( constraintViolation.getExecutableReturnValue(), null );
    }
  }

  @Test
  public void constraintsAtMethodFromBaseClassAreEvaluated() {
    try {
      customerRepository.findById( null );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "findById", Long.class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
    }
  }

  @Test
  public void constraintsAtOverriddenMethodAreEvaluated() {
    try {
      customerRepository.foo( null );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "foo", Long.class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
    }
  }

  @Test
  public void validFromOverriddenMethodIsEvaluated() {
    try {
      customerRepository.bar( new Customer( null, null ) );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "bar", Customer.class );
      assertParameterIndex( constraintViolation, 0 );
      assertMethodValidationType( constraintViolation, ElementKind.PARAMETER );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getPropertyPath().toString(), "bar.arg0.name" );
    }
  }

  @Test
  public void parameterValidationOfParameterlessMethod() {
    customerRepository.boz();
  }

  @Test
  public void returnValueValidationYieldsConstraintViolation() {
    try {
      customerRepository.baz();
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertNumberOfViolations( e.getConstraintViolations(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "must be greater than or equal to 10" );
      assertMethod( constraintViolation, "baz" );
      assertMethodValidationType( constraintViolation, ElementKind.RETURN_VALUE );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getPropertyPath().toString(), "baz.<return value>" );
      assertEquals( constraintViolation.getLeafBean(), customerRepository );
      assertEquals( constraintViolation.getInvalidValue(), 9 );
      assertEquals( constraintViolation.getExecutableParameters(), null );
      assertEquals( constraintViolation.getExecutableReturnValue(), 9 );
    }
  }

  @Test
  public void cascadingReturnValue() {
    try {
      customerRepository.cascadingReturnValue();
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertNumberOfViolations( e.getConstraintViolations(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "cascadingReturnValue" );
      assertMethodValidationType( constraintViolation, ElementKind.RETURN_VALUE );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "cascadingReturnValue.<return value>.name"
      );
      assertEquals( constraintViolation.getLeafBean().getClass(), Customer.class );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), null );
      assertEquals( constraintViolation.getExecutableReturnValue(), new Customer( null ) );
    }
  }

  @Test
  public void cascadingReturnValueFromSuperType() {
    try {
      customerRepository.overriddenMethodWithCascadingReturnValue();
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertNumberOfViolations( e.getConstraintViolations(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "overriddenMethodWithCascadingReturnValue" );
      assertMethodValidationType( constraintViolation, ElementKind.RETURN_VALUE );

      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "overriddenMethodWithCascadingReturnValue.<return value>.name"
      );
      assertEquals( constraintViolation.getLeafBean().getClass(), Customer.class );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), null );
      assertEquals( constraintViolation.getExecutableReturnValue(), new Customer( null ) );
    }
  }

  @Test
  public void cascadingIterableReturnValue() {
    try {
      customerRepository.cascadingIterableReturnValue();
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "cascadingIterableReturnValue" );
      assertMethodValidationType( constraintViolation, ElementKind.RETURN_VALUE );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "cascadingIterableReturnValue.<return value>[1].name"
      );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getLeafBean(), new Customer( null ) );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), null );
      assertEquals( constraintViolation.getExecutableReturnValue(), Arrays.asList( null, new Customer( null ) ) );
    }
  }

  @Test
  public void cascadingMapReturnValue() {
    try {
      customerRepository.cascadingMapReturnValue();
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      Customer customer = new Customer( null );
      Map<String, Customer> expectedReturnValue = newHashMap();
      expectedReturnValue.put( "Bob", customer );

      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "cascadingMapReturnValue" );
      assertMethodValidationType( constraintViolation, ElementKind.RETURN_VALUE );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "cascadingMapReturnValue.<return value>[Bob].name"
      );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getLeafBean(), customer );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), null );
      assertEquals( constraintViolation.getExecutableReturnValue(), expectedReturnValue );
    }
  }

  @Test
  public void cascadingArrayReturnValue() {
    try {
      customerRepository.cascadingArrayReturnValue();
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertEquals( e.getConstraintViolations().size(), 1 );

      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertEquals( constraintViolation.getMessage(), messagePrefix() + "may not be null" );
      assertMethod( constraintViolation, "cascadingArrayReturnValue" );
      assertMethodValidationType( constraintViolation, ElementKind.RETURN_VALUE );
      assertEquals(
          constraintViolation.getPropertyPath().toString(),
          "cascadingArrayReturnValue.<return value>[1].name"
      );
      assertEquals( constraintViolation.getRootBeanClass(), CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertEquals( constraintViolation.getLeafBean(), new Customer( null ) );
      assertEquals( constraintViolation.getInvalidValue(), null );
      assertEquals( constraintViolation.getExecutableParameters(), null );
      assertEquals( constraintViolation.getExecutableReturnValue(), new Object[] { null, new Customer( null ) } );
    }
  }

  @Test
  public void overridingMethodStrengthensReturnValueConstraint() {
    try {
      customerRepository.overriddenMethodWithReturnValueConstraint();
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertCorrectConstraintViolationMessages(
          e.getConstraintViolations(),
          messagePrefix() + "must be greater than or equal to 5",
          messagePrefix() + "must be greater than or equal to 10"
      );
    }
  }

  @Test
  public void runtimeTypeDefinesConstraintsToApply() {
    try {
      repositoryBase.overriddenMethodWithReturnValueConstraint();
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      assertCorrectConstraintViolationMessages(
          e.getConstraintViolations(),
          messagePrefix() + "must be greater than or equal to 5",
          messagePrefix() + "must be greater than or equal to 10"
      );
    }
  }

  @Test
  public void methodValidationSucceedsAsNoConstraintOfValidatedGroupAreViolated() {
    customerRepository.parameterConstraintInGroup( null );
  }

  @Test(expectedExceptions = ConstraintViolationException.class)
  public void methodValidationFailsAsConstraintOfValidatedGroupIsViolated() {
    createProxy( CustomerRepository.ValidationGroup.class );
    customerRepository.parameterConstraintInGroup( null );
  }

  @Test(expectedExceptions = ConstraintDeclarationException.class, expectedExceptionsMessageRegExp = "HV000132.*")
  public void voidMethodWithReturnValueConstraintCausesConstraintDeclarationException() {
    CustomerRepositoryWithConstrainedVoidMethod customerRepository = getValidatingProxy(
        new CustomerRepositoryWithConstrainedVoidMethodImpl(), validator
    );

    customerRepository.voidMethodWithIllegalReturnValueConstraint();
  }

  @TestForIssue(jiraKey = "HV-601")
  @Test(expectedExceptions = ConstraintViolationException.class)
  public void shouldValidateGetterLikeNamedMethodWithParameter() {
    customerRepository.getFoo( "" );
  }

  @Test
  public void validationOfCrossParameterConstraint() {
    //given
    DateMidnight startDate = new DateMidnight( 2012, 11, 5 );
    DateMidnight endDate = new DateMidnight( 2012, 11, 4 );

    try {
      //when
      customerRepository.methodWithCrossParameterConstraint( startDate, endDate );
      fail( "Expected ConstraintViolationException wasn't thrown." );
    }
    catch ( ConstraintViolationException e ) {
      //then
      assertThat( e.getConstraintViolations() ).hasSize( 1 );
      ConstraintViolation<?> constraintViolation = e.getConstraintViolations().iterator().next();
      assertCorrectConstraintViolationMessages(
          e.getConstraintViolations(),
          messagePrefix() + "{ConsistentDateParameters.message}"
      );
      assertThat( constraintViolation.getConstraintDescriptor().getAnnotation().annotationType() ).isEqualTo(
          ConsistentDateParameters.class
      );
      assertThat( constraintViolation.getInvalidValue() ).isEqualTo( new Object[] { startDate, endDate } );
      assertEquals( constraintViolation.getLeafBean(), customerRepository );
      assertEquals( constraintViolation.getRootBean(), customerRepository );
      assertThat( constraintViolation.getRootBeanClass() ).isEqualTo( CustomerRepositoryImpl.class );
      assertEquals( constraintViolation.getExecutableParameters(), new Object[] { startDate, endDate } );
      assertEquals( constraintViolation.getExecutableReturnValue(), null );

      assertMethod(
          constraintViolation,
          "methodWithCrossParameterConstraint",
          DateMidnight.class,
          DateMidnight.class
      );

      assertNodeNames(
          constraintViolation.getPropertyPath(),
          "methodWithCrossParameterConstraint",
          "<cross-parameter>"
      );
      assertNodeKinds( constraintViolation.getPropertyPath(), ElementKind.METHOD, ElementKind.CROSS_PARAMETER );
    }
  }

  @Test
  public void methodValidationSucceeds() {
    customerRepository.findCustomerByName( "Bob" );
  }

  private void assertMethod(ConstraintViolation<?> constraintViolation, String methodName, Class<?>... parameterTypes) {
    Iterator<Path.Node> nodeIterator = constraintViolation.getPropertyPath().iterator();

    Path.Node node = nodeIterator.next();
    assertNotNull( node );
    assertEquals( node.getName(), methodName );
    assertEquals( node.getKind(), ElementKind.METHOD );
    assertEquals( node.as( Path.MethodNode.class ).getParameterTypes(), Arrays.asList( parameterTypes ) );
  }

  private void assertParameterIndex(ConstraintViolation<?> constraintViolation, Integer index) {
    Iterator<Path.Node> nodeIterator = constraintViolation.getPropertyPath().iterator();

    // first node is method descriptor
    nodeIterator.next();
    Path.Node node = nodeIterator.next();
    ParameterNode parameterNode = node.as( ParameterNode.class );
    assertEquals( parameterNode.getParameterIndex(), index.intValue() );
  }

  private void assertMethodValidationType(ConstraintViolation<?> constraintViolation, ElementKind kind) {
    Iterator<Path.Node> nodeIterator = constraintViolation.getPropertyPath().iterator();

    // first node is method descriptor
    nodeIterator.next();
    Path.Node node = nodeIterator.next();
    assertEquals( node.getKind(), kind );
  }
}
TOP

Related Classes of org.hibernate.validator.test.internal.engine.methodvalidation.AbstractMethodValidationTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.