Package org.hibernate.beanvalidation.tck.tests.constraints.constraintcomposition

Source Code of org.hibernate.beanvalidation.tck.tests.constraints.constraintcomposition.ConstraintCompositionTest$DummyEntityWithIllegallyComposedConstraint

/*
* JBoss, Home of Professional Open Source
* Copyright 2009, Red Hat, Inc. and/or its affiliates, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.hibernate.beanvalidation.tck.tests.constraints.constraintcomposition;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintDefinitionException;
import javax.validation.ConstraintTarget;
import javax.validation.ConstraintViolation;
import javax.validation.Payload;
import javax.validation.UnexpectedTypeException;
import javax.validation.Validator;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
import javax.validation.executable.ExecutableValidator;
import javax.validation.groups.Default;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.metadata.ConstraintDescriptor;

import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.arquillian.testng.Arquillian;
import org.jboss.shrinkwrap.api.spec.WebArchive;
import org.jboss.test.audit.annotations.SpecAssertion;
import org.jboss.test.audit.annotations.SpecAssertions;
import org.jboss.test.audit.annotations.SpecVersion;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import org.hibernate.beanvalidation.tck.util.TestUtil;
import org.hibernate.beanvalidation.tck.util.shrinkwrap.WebArchiveBuilder;

import static org.hibernate.beanvalidation.tck.util.TestUtil.assertConstraintViolation;
import static org.hibernate.beanvalidation.tck.util.TestUtil.assertCorrectConstraintTypes;
import static org.hibernate.beanvalidation.tck.util.TestUtil.assertCorrectConstraintViolationMessages;
import static org.hibernate.beanvalidation.tck.util.TestUtil.assertCorrectNumberOfViolations;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;

/**
* Tests for composing constraints.
*
* @author Hardy Ferentschik
*/
@SpecVersion(spec = "beanvalidation", version = "1.1.0")
public class ConstraintCompositionTest extends Arquillian {

  private Validator validator;
  private ExecutableValidator executableValidator;

  @Deployment
  public static WebArchive createTestArchive() {
    return new WebArchiveBuilder()
        .withTestClassPackage( ConstraintCompositionTest.class )
        .build();
  }

  @BeforeMethod
  public void setupValidator() {
    validator = TestUtil.getValidatorUnderTest();
    executableValidator = validator.forExecutables();
  }

  @Test
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "a"),
      @SpecAssertion(section = "3.3", id = "p")
  })
  public void testComposedConstraints() {
    FrenchAddress address = getFrenchAddressWithoutZipCode();
    Set<ConstraintViolation<FrenchAddress>> constraintViolations = validator.validate( address );
    assertCorrectNumberOfViolations( constraintViolations, 1 );
    ConstraintViolation<FrenchAddress> constraintViolation = constraintViolations.iterator().next();
    assertCorrectConstraintTypes( constraintViolations, NotNull.class );
    assertCorrectConstraintViolationMessages( constraintViolations, "may not be null" );
    assertConstraintViolation(
        constraintViolation,
        FrenchAddress.class,
        null,
        "zipCode"
    );
  }

  @Test
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "a"),
      @SpecAssertion(section = "3.3", id = "p")
  })
  public void testComposedConstraintsAreRecursive() {
    GermanAddress address = new GermanAddress();
    address.setAddressline1( "Rathausstrasse 5" );
    address.setAddressline2( "3ter Stock" );
    address.setCity( "Karlsruhe" );
    Set<ConstraintViolation<GermanAddress>> constraintViolations = validator.validate( address );
    assertCorrectNumberOfViolations( constraintViolations, 1 );
    assertConstraintViolation(
        constraintViolations.iterator().next(),
        GermanAddress.class,
        null,
        "zipCode"
    );
  }

  @Test
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "b"),
      @SpecAssertion(section = "3.4", id = "s")
  })
  public void testValidationOfMainAnnotationIsAlsoApplied() {
    FrenchAddress address = getFrenchAddressWithoutZipCode();
    address.setZipCode( "00000" );
    Set<ConstraintViolation<FrenchAddress>> constraintViolations = validator.validate( address );
    assertCorrectNumberOfViolations( constraintViolations, 1 );
    assertCorrectConstraintTypes( constraintViolations, FrenchZipcode.class );
    assertCorrectConstraintViolationMessages( constraintViolations, "00000 is a reserved code" );
  }

  @Test
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "c"),
      @SpecAssertion(section = "3.3", id = "n"),
      @SpecAssertion(section = "3.3", id = "q"),
      @SpecAssertion(section = "3.3", id = "r"),
      @SpecAssertion(section = "3.3", id = "s")
  })
  public void testEachFailingConstraintCreatesConstraintViolation() {
    FrenchAddress address = getFrenchAddressWithoutZipCode();
    address.setZipCode( "abc" );
    Set<ConstraintViolation<FrenchAddress>> constraintViolations = validator.validate( address );
    assertCorrectNumberOfViolations( constraintViolations, 3 );
    assertCorrectConstraintTypes( constraintViolations, Pattern.class, Pattern.class, Size.class );
    for ( ConstraintViolation<FrenchAddress> violation : constraintViolations ) {
      assertConstraintViolation(
          violation,
          FrenchAddress.class,
          "abc",
          "zipCode"
      );
    }

    address.setZipCode( "123" );
    constraintViolations = validator.validate( address );
    assertCorrectNumberOfViolations( constraintViolations, 2 );
    assertCorrectConstraintTypes( constraintViolations, Pattern.class, Size.class );
    for ( ConstraintViolation<FrenchAddress> violation : constraintViolations ) {
      assertConstraintViolation(
          violation,
          FrenchAddress.class,
          "123",
          "zipCode"
      );

    }

    address.setZipCode( "33023" );
    constraintViolations = validator.validate( address );
    assertCorrectNumberOfViolations( constraintViolations, 0 );
  }

  @Test
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "d"),
      @SpecAssertion(section = "3.3", id = "e")
  })
  public void testGroupsDefinedOnMainAnnotationAreInherited() {
    FrenchAddress address = getFrenchAddressWithoutZipCode();
    Set<ConstraintViolation<FrenchAddress>> constraintViolations = validator.validate( address );
    assertCorrectNumberOfViolations( constraintViolations, 1 );
    ConstraintViolation<FrenchAddress> constraintViolation = constraintViolations.iterator().next();
    assertCorrectConstraintTypes( constraintViolations, NotNull.class );
    NotNull notNull = (NotNull) constraintViolation.getConstraintDescriptor().getAnnotation();
    List<Class<?>> groups = Arrays.asList( notNull.groups() );
    assertTrue( groups.size() == 2, "There should be two groups" );
    assertTrue( groups.contains( Default.class ), "The default group should be in the list." );
    assertTrue(
        groups.contains( FrenchAddress.FullAddressCheck.class ),
        "The FrenchAddress.FullAddressCheck group should be inherited."
    );
  }

  @Test
  @SpecAssertion(section = "3.3", id = "l")
  public void testOnlySingleConstraintViolation() {
    GermanAddress address = new GermanAddress();
    address.setAddressline1( "Rathausstrasse 5" );
    address.setAddressline2( "3ter Stock" );
    address.setCity( "Karlsruhe" );
    address.setZipCode( "abc" );
    // actually three composing constraints fail, but due to @ReportAsSingleViolation only one will be reported.
    Set<ConstraintViolation<GermanAddress>> constraintViolations = validator.validate( address );
    assertCorrectNumberOfViolations( constraintViolations, 1 );
    assertConstraintViolation(
        constraintViolations.iterator().next(),
        GermanAddress.class,
        "abc",
        "zipCode"
    );
  }

  @Test
  @SpecAssertion(section = "3.3", id = "m")
  public void testAttributesDefinedOnComposingConstraints() {
    BeanDescriptor descriptor = validator.getConstraintsForClass( FrenchAddress.class );
    Set<ConstraintDescriptor<?>> constraintDescriptors = descriptor.getConstraintsForProperty( "zipCode" )
        .getConstraintDescriptors();
    boolean findPattern = checkForAppropriateAnnotation( constraintDescriptors );
    assertTrue( findPattern, "Could not find @Pattern in composing constraints" );
  }

  private boolean checkForAppropriateAnnotation(Set<ConstraintDescriptor<?>> constraintDescriptors) {
    boolean findPattern = false;
    for ( ConstraintDescriptor<?> constraintDescriptor : constraintDescriptors ) {
      Annotation ann = constraintDescriptor.getAnnotation();
      if ( Pattern.class.getName().equals( ann.annotationType().getName() ) ) {
        String regexp = ( (Pattern) ann ).regexp();
        if ( regexp.equals( "bar" ) ) {
          fail( "The regular expression attributes are defined in the composing constraint." );
        }
        findPattern = true;
      }
      findPattern |= checkForAppropriateAnnotation( constraintDescriptor.getComposingConstraints() );
    }
    return findPattern;
  }

  @Test(expectedExceptions = ConstraintDefinitionException.class)
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "o"),
      @SpecAssertion(section = "3.3", id = "t")
  })
  public void testOverriddenAttributesMustMatchInType() {
    validator.validate( new DummyEntityWithZipCode( "foobar" ) );
  }

  @Test(expectedExceptions = UnexpectedTypeException.class)
  @SpecAssertion(section = "3.3", id = "j")
  public void testAllComposingConstraintsMustBeApplicableToAnnotatedType() {
    validator.validate( new Shoe( 41 ) );
  }

  @Test
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "f"),
      @SpecAssertion(section = "3.3", id = "g")
  })
  public void testPayloadPropagationInComposedConstraints() {
    Friend john = new Friend( "John", "Doe" );

    Set<ConstraintViolation<Friend>> constraintViolations = validator.validate( john );

    assertCorrectNumberOfViolations( constraintViolations, 1 );
    assertCorrectConstraintTypes( constraintViolations, NotNull.class );

    ConstraintViolation<Friend> constraintViolation = constraintViolations.iterator().next();
    Set<Class<? extends Payload>> payloads = constraintViolation.getConstraintDescriptor().getPayload();

    assertTrue( payloads.size() == 1, "There should be one payload in the set" );
    Class<? extends Payload> payload = payloads.iterator().next();
    assertTrue( payload.getName().equals( Severity.Warn.class.getName() ), "Unexpected payload" );
  }

  @Test
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "h"),
      @SpecAssertion(section = "3.3", id = "i")
  })
  public void testConstraintTargetPropagationInComposedConstraints() throws Exception {
    Object object = new DummyEntityWithGenericAndCrossParameterConstraint();
    Method method = DummyEntityWithGenericAndCrossParameterConstraint.class.getMethod( "doSomething", int.class );
    Object[] parameterValues = new Object[0];

    Set<ConstraintViolation<Object>> constraintViolations = executableValidator.validateParameters(
        object,
        method,
        parameterValues
    );

    //The composing constraint is expected to fail
    assertCorrectNumberOfViolations( constraintViolations, 1 );
    assertCorrectConstraintTypes( constraintViolations, GenericAndCrossParameterConstraint.class );

    //and it should inherit the constraint target from the composed constraint
    ConstraintViolation<Object> constraintViolation = constraintViolations.iterator().next();
    assertEquals(
        constraintViolation.getConstraintDescriptor().getValidationAppliesTo(),
        ConstraintTarget.PARAMETERS
    );
  }

  @Test(expectedExceptions = ConstraintDefinitionException.class)
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "k"),
      @SpecAssertion(section = "3.3", id = "t")
  })
  public void testMixedConstraintTargetsInComposedAndComposingConstraintsCauseException()
      throws Exception {
    Object object = new DummyEntityWithIllegallyComposedConstraint();
    Method method = DummyEntityWithIllegallyComposedConstraint.class.getMethod(
        "doSomething",
        int.class
    );
    Object[] parameterValues = new Object[0];

    executableValidator.validateParameters(
        object,
        method,
        parameterValues
    );
  }

  @Test(expectedExceptions = ConstraintDefinitionException.class)
  @SpecAssertions({
      @SpecAssertion(section = "3.3", id = "k"),
      @SpecAssertion(section = "3.3", id = "t")
  })
  public void testMixedConstraintTargetsInComposingConstraintsCauseException() throws Exception {
    Object object = new DummyEntityWithAnotherIllegallyComposedConstraint();
    Method method = DummyEntityWithAnotherIllegallyComposedConstraint.class.getMethod(
        "doSomething",
        int.class
    );
    Object[] parameterValues = new Object[0];

    executableValidator.validateParameters(
        object,
        method,
        parameterValues
    );
  }

  private FrenchAddress getFrenchAddressWithoutZipCode() {
    FrenchAddress address = new FrenchAddress();
    address.setAddressline1( "10 rue des Treuils" );
    address.setAddressline2( "BP 12 " );
    address.setCity( "Bordeaux" );
    return address;
  }

  private static class DummyEntityWithZipCode {
    @FrenchZipcodeWithInvalidOverride
    String zip;

    DummyEntityWithZipCode(String zip) {
      this.zip = zip;
    }
  }

  private static class DummyEntityWithGenericAndCrossParameterConstraint {
    @ComposedGenericAndCrossParameterConstraint(validationAppliesTo = ConstraintTarget.PARAMETERS)
    public Object doSomething(int i) {
      return null;
    }
  }

  private static class DummyEntityWithIllegallyComposedConstraint {
    @ParametersNotEmpty
    public Object doSomething(int i) {
      return null;
    }
  }

  private static class DummyEntityWithAnotherIllegallyComposedConstraint {
    @ComposedConstraint
    public void doSomething(int i) {
    }
  }
}
TOP

Related Classes of org.hibernate.beanvalidation.tck.tests.constraints.constraintcomposition.ConstraintCompositionTest$DummyEntityWithIllegallyComposedConstraint

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.