Package

Source Code of CdiValidationTest

import de.huepattl.playground.validation.CdiValidatingService;
import de.huepattl.playground.validation.Employee;

import static org.junit.Assert.*;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jboss.arquillian.container.test.api.Deployment;
import org.jboss.shrinkwrap.api.ShrinkWrap;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.spec.JavaArchive;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.jboss.arquillian.junit.Arquillian;

import javax.ejb.EJBException;
import javax.inject.Inject;

import javax.validation.ConstraintViolationException;
import java.util.Collection;
import java.util.HashSet;

/**
* <p>
* This tests implicit bean and method validation as supported by CDI/EJB. Given
* that we have a CDI managed service
* ({@link de.huepattl.playground.validation.CdiValidatingService}) - whose task
* is not to validate explicitly (it is not a validation service!).</p>
* <p>
* So, we have a managed service and we pass our annotated bean to a service
* method. Just by annotatting the method signature with
* {@link javax.validation.Valid} causes the runtime to validated the given bean
* behind the scenes.</p>
* We also demonstrate passing not NULL and expecting non-NULL results from
* calling a method.
*
* @author Timo Boewing (bjblazko@gmail.com)
* @since 2014-02-12
*/
@RunWith(Arquillian.class)
public class CdiValidationTest extends AbstractValidationTest {

    private static final Logger LOG = LogManager.getLogger(CdiValidationTest.class);

    /**
     * Our CDI managed 'business' service. By definition, this is not an
     * explicit validation service.
     */
    @Inject
    CdiValidatingService service;

    @Deployment
    public static JavaArchive createDeployment() {
        JavaArchive jar = ShrinkWrap.create(JavaArchive.class).addClass(Employee.class).addClass(CdiValidatingService.class)
                .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");
        return jar;
    }

    /**
     * We have a bean that is valid according to its own constraint definitions
     * (see its annotations). When passing the bean to the method, we expect no
     * errors. The method argument for the bean is annotated with {@link
     * javax.validation.Valid}, which causes the runtime to implicitly validate
     * the bean through AOP.
     *
     * @throws Exception BAM!
     */
    @Test
    public void validBean() throws Exception {
        Employee bean = super.newValidBean();
        service.doSomething(bean); // if fails, the unit test throws exception
    }

    /**
     * Let us check if the method's {@link javax.validation.Valid} annotation
     * really works. The bean passed is not valid according to its contraint
     * annotations, but the service method requires a valid bean - defined by
     * the {@link
     * javax.validation.Valid} annotation. FIXME: Cannot get JUnit 'expected'
     * exception working, receiving {@code ArquillianProxyException} instead.
     *
     * @throws Exception BAM!
     */
    @Test
    public void invalidBean() throws Exception {
        Employee bean = new Employee();

        // This is for @BeanConstraints
        bean.setLastName("A");
        bean.setFirstName("B");

        int errors = 0;

        try {
            service.doSomething(bean);
        } catch (EJBException ejbe) {
            // TODO: Remove this block!?!
            ConstraintViolationException ve = (ConstraintViolationException) ejbe.getCause();
            errors = ve.getConstraintViolations().size();
            LOG.info("Found validation errors as expected:");
            super.printValidationMessages(ve.getConstraintViolations());
        } catch (ConstraintViolationException cve) {
            errors = cve.getConstraintViolations().size();
            LOG.info("Found validation errors as expected:");
            super.printValidationMessages(cve.getConstraintViolations());
        }
        assertTrue(errors > 0);
    }

    /**
     * We pass NULL to the method. Since it is annotated with
     * {@link javax.validation.constraints.NotNull}, it may not continue.
     *
     * @throws Exception BAM!
     */
    @Test//(expected = ConstraintViolationException.class)
    public void notNullArgument() throws Exception {
        boolean gotException = false;
        try {
            service.doSomething(null);
        } catch (EJBException wrapped) {
            ConstraintViolationException ve = (ConstraintViolationException) wrapped.getCausedByException();
            gotException = true;
        }
        assertTrue(gotException);
    }

    /**
     * Test if it also works when passing a bunch of invalid beans in a
     * collection.
     *
     * @throws Exception BAM!
     */
    @Test
    public void testManyInvalidBeans() throws Exception {
        int errors = 0;
        Collection<Employee> list = new HashSet<>();
        for (int i = 0; i < 10; i++) {
            list.add(new Employee());
        }

        try {
            service.doSomethingManyBeans(list);
        } catch (EJBException wrapped) {
            ConstraintViolationException ve = (ConstraintViolationException) wrapped.getCausedByException();
            errors = ve.getConstraintViolations().size();
            LOG.info("Found validation errors as expected:");
            super.printValidationMessages(ve.getConstraintViolations());
        }
        assertTrue(errors > 0);
    }

    /**
     * This test just checks that if there is only ONE invalid bean the method
     * not executes like desired.
     *
     * @throws Exception BAM!
     * @see #testManyInvalidBeans()
     */
    @Test
    public void testThatEvenOneInvalidBeanFails() throws Exception {

        int errors = 0;
        Collection<Employee> list = new HashSet<>();
        // Add 10 VALID beans.
        for (int i = 0; i < 10; i++) {
            list.add(super.newValidBean());
        }
        // Add one INVALID bean.
        list.add(new Employee());

        try {
            service.doSomethingManyBeans(list);
        } catch (EJBException wrapped) {
            ConstraintViolationException ve = (ConstraintViolationException) wrapped.getCausedByException();
            errors = ve.getConstraintViolations().size();
            LOG.info("Found validation errors as expected:");
            super.printValidationMessages(ve.getConstraintViolations());
        }
        assertTrue(errors > 0);
    }

    /**
     * Test validation groups. When manually calling a validator via {@link javax.validation.Validator#validate(Object,
     * Class[])}, you can specify the group scope. However, with
     * {@link javax.validation.Valid}, this is not the case and we have to remap
     * the matching groups using the
     * {@link javax.validation.groups.ConvertGroup} annotation.
     *
     * @throws Exception BAM!
     */
    @Test
    public void testGroups() throws Exception {
        Employee bean = super.newValidBean();
        service.doSomethingWithGroups(bean);

        int errors = 0;
        bean.setStricterValueThanOthers("AC");
        try {
            service.doSomethingWithGroups(bean);
        } catch (EJBException wrapped) {
            ConstraintViolationException ve = (ConstraintViolationException) wrapped.getCausedByException();
            errors = ve.getConstraintViolations().size();
            LOG.info("Found validation errors as expected:");
            super.printValidationMessages(ve.getConstraintViolations());
        }
        assertTrue(errors > 0);
    }

    /**
     * We will call a method that will return {@code NULL} although it has a {@link
     * javax.validation.constraints.NotNull} annotation. Thus, we will get a
     * validation exception when calling the method.
     *
     * @throws Exception BAM!
     */
    @Test
    public void testReturningNull() throws Exception {
        boolean foundThatNullWasReturned = false;
        try {
            service.methodReturningNullByAccident();
        } catch (EJBException ex) {
            foundThatNullWasReturned = true;
        }
        assertTrue(foundThatNullWasReturned);
    }

    /**
     * This tests that in a method (two) method arguments are the same. Of
     * course, you might check anything between the arguments. The use case
     * demonstrated however is common for UI related user input of passwords or
     * email addresses (two inputs tht have to match)
     * .<p>
     * We use a custom validation annotation
     * ({@link de.huepattl.playground.validation.annotation.EqualParams}) for
     * this, backed by a custom validator
     * ({@link de.huepattl.playground.validation.validator.EqualParamsValidator})
     * that uses
     * {@link javax.validation.constraintvalidation.SupportedValidationTarget}
     * with {@link
     * javax.validation.constraintvalidation.ValidationTarget}.
     *
     * @throws Exception BAM!
     */
    @Test
    public void testEqualMethodParams() throws Exception {
        int errors = 0;

        service.specifyEmail("same@example.org", "same@example.org");

        try {
            service.specifyEmail("same@example.org", "different@example.org");
        } catch (EJBException wrapped) {
            ConstraintViolationException ve = (ConstraintViolationException) wrapped.getCausedByException();
            errors = ve.getConstraintViolations().size();
            LOG.info("Found validation errors as expected:");
            super.printValidationMessages(ve.getConstraintViolations());
        }
        assertTrue(errors > 0);
    }

}
TOP

Related Classes of CdiValidationTest

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.