Package org.apache.myfaces.view.facelets.tag.jsf.core

Source Code of org.apache.myfaces.view.facelets.tag.jsf.core.ValidateBeanTestCase

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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.apache.myfaces.view.facelets.tag.jsf.core;

import java.io.IOException;
import java.lang.reflect.Field;

import javax.faces.component.UIInput;
import javax.faces.component.UIViewRoot;
import javax.faces.validator.BeanValidator;
import javax.faces.validator.Validator;

import org.apache.myfaces.util.ExternalSpecifications;
import org.apache.myfaces.view.facelets.FaceletTestCase;
import org.junit.Assert;
import org.junit.Test;

/**
* Tests for <f:validateBean />.
*
* @author Jakob Korherr (latest modification by $Author: lu4242 $)
* @version $Revision: 1195560 $ $Date: 2011-10-31 17:40:09 +0100 (Mon, 31 Oct 2011) $
*/
public class ValidateBeanTestCase extends FaceletTestCase
{
   
    @Override
    public void setUp() throws Exception
    {
        super.setUp();
       
        // configure bean validation to be available
        _setBeanValidationAvailable(true);
    }

    /**
     * Sets the cached field in ExternalSpecifications to enable or
     * disable bean validation for testing purposes.
     *
     * @param available
     */
    private void _setBeanValidationAvailable(boolean available)
    {
        try
        {
            Field field = ExternalSpecifications.class.getDeclaredField("beanValidationAvailable");
            field.setAccessible(true);
            field.set(ExternalSpecifications.class, available);
        }
        catch (Exception e)
        {
            throw new IllegalStateException("Could not configure BeanValidation for the test case.", e);
        }
    }
   
    /**
     * Gets the validator from the given UIInput with the given validatorClass
     * or null if the UIInput does not have such a validator installed.
     * @param <T>
     * @param input
     * @param validatorClass
     * @return
     */
    @SuppressWarnings("unchecked")
    private <T> T _getValidator(UIInput input, Class<T> validatorClass)
    {
        Validator[] validators = input.getValidators();
        if (validators != null)
        {
            for (Validator validator : validators)
            {
                if (validatorClass.isAssignableFrom(validator.getClass()))
                {
                    return (T) validator;
                }
            }
        }
       
        return null;
    }
   
    /**
     * Tests if the given UIInput has a validator of the given validatorClass installed.
     * @param input
     * @param validatorClass
     * @return
     */
    private boolean _hasValidator(UIInput input, Class<?> validatorClass)
    {
        return (_getValidator(input, validatorClass) != null);
    }
   
    /**
     * Gets the attached BeanValidator from the given UIInput and returns its
     * validationGroups. Returns null if no BeanValidator is attached.
     * @param input
     * @return
     */
    private String _getValidationGroups(UIInput input)
    {
        BeanValidator validator = _getValidator(input, BeanValidator.class);
        if (validator != null)
        {
            return validator.getValidationGroups();
        }
        return null;
    }

    /**
     * Tests the case that the BeanValidator is not a default validator,
     * but the UIInput has a <f:validateBean /> child tag on the facelet.
     * In this case the BeanValidator has to be installed.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testBeanValidatorInstalledManually() throws IOException
    {
        // put the disabled value on the request scope
        externalContext.getRequestMap().put("validateBeanDisabled", Boolean.FALSE);
       
        // build testValidateBean.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBean.xhtml");
       
        // get the component instances
        UIInput input = (UIInput) root.findComponent("form:input");
       
        // the UIInput has to have the BeanValidator installed
        Assert.assertTrue(_hasValidator(input, BeanValidator.class));
    }
   
    /**
     * Tests the case that the UIInput has no nested <f:validateBean>
     * on the facelet, but the BeanValidator is a default validator.
     * In this case the BeanValidator has to be installed.
     * @throws IOException
     */
    @Test
    public void testBeanValidatorInstalledAutomatically() throws IOException
    {
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // build testValidateBeanEmptyInput.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanEmptyInput.xhtml");
       
        // get the component instances
        UIInput input = (UIInput) root.findComponent("form:input");
       
        // the UIInput has to have the BeanValidator installed
        Assert.assertTrue(_hasValidator(input, BeanValidator.class));
    }
   
    /**
     * Tests the case that the BeanValidator is a default validator, but the
     * UIInput has a nested <f:validateBean disabled="true" /> on the facelet.
     * In this case the BeanValidator must not be installed.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testDisabledBeanValidatorNotInstalled() throws IOException
    {
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // put the disabled value on the request scope
        externalContext.getRequestMap().put("validateBeanDisabled", Boolean.TRUE);
       
        // build testValidateBean.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBean.xhtml");
       
        // get the component instances
        UIInput input = (UIInput) root.findComponent("form:input");
       
        // the UIInput must not have the BeanValidator installed
        Assert.assertFalse(_hasValidator(input, BeanValidator.class));
    }
   
    /**
     * Tests the case when <f:validateBean> is used in wrapping mode
     * and the BeanValidator is not a default-validator.
     * In this case the BeanValidator has to be installed on all
     * EditableValueHolders which he is nesting and must not be installed
     * on any other EditableValueHolder on the facelet.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testNestingValidateBean() throws IOException
    {
        // put the disabled value on the request scope
        externalContext.getRequestMap().put("validateBeanDisabled", Boolean.FALSE);
       
        // build testValidateBeanNesting.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanNesting.xhtml");
       
        // get the component instances
        UIInput nestedinput = (UIInput) root.findComponent("form:nestedinput");
        UIInput doublenestedinput = (UIInput) root.findComponent("form:doublenestedinput");
        UIInput nestedinput2 = (UIInput) root.findComponent("form:nestedinput2");
        UIInput nonnestedinput = (UIInput) root.findComponent("form:nonnestedinput");
       
        // all wrapped UIInputs have to have the BeanValidator installed
        Assert.assertTrue(_hasValidator(nestedinput, BeanValidator.class));
        Assert.assertTrue(_hasValidator(doublenestedinput, BeanValidator.class));
        Assert.assertTrue(_hasValidator(nestedinput2, BeanValidator.class));
        Assert.assertFalse(_hasValidator(nonnestedinput, BeanValidator.class));
    }
   
    /**
     * Tests the case when <f:validateBean> is used in wrapping mode,
     * its disabled attribute is true and the BeanValidator is a default-validator.
     * In this case the BeanValidator has to be installed on all
     * EditableValueHolders which are not nested and must not be installed
     * on all nested EditableValueHolders on the facelet.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testNestingValidateBeanDisabled() throws IOException
    {
        // put the disabled value on the request scope
        externalContext.getRequestMap().put("validateBeanDisabled", Boolean.TRUE);
       
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // build testValidateBeanNesting.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanNesting.xhtml");
       
        // get the component instances
        UIInput nestedinput = (UIInput) root.findComponent("form:nestedinput");
        UIInput doublenestedinput = (UIInput) root.findComponent("form:doublenestedinput");
        UIInput nestedinput2 = (UIInput) root.findComponent("form:nestedinput2");
        UIInput nonnestedinput = (UIInput) root.findComponent("form:nonnestedinput");
       
        // all wrapped UIInputs have to have the BeanValidator installed
        Assert.assertFalse(_hasValidator(nestedinput, BeanValidator.class));
        Assert.assertFalse(_hasValidator(doublenestedinput, BeanValidator.class));
        Assert.assertFalse(_hasValidator(nestedinput2, BeanValidator.class));
        Assert.assertTrue(_hasValidator(nonnestedinput, BeanValidator.class));
    }
   
    /**
     * Tests the case that there are two <f:validateBean> tags, one disabled and
     * one not. The disabled one should add the validator id of the BeanValidator
     * to an default-validator exclusion list on the parent (<h:inputText>)
     * whereas the enabled one should manually add the BeanValidator no matter what.
     * In this case the BeanValidator has to be installed (see also MYFACES-2731).
     * @throws IOException
     */
    @Test
    public void testValidateBeanDisabledAndEnabled() throws IOException
    {
        // build testValidateBeanDisabledAndEnabled.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanDisabledAndEnabled.xhtml");
       
        // get the component instances
        UIInput input = (UIInput) root.findComponent("form:input");
       
        // the UIInput has to have the BeanValidator installed
        Assert.assertTrue(_hasValidator(input, BeanValidator.class));
    }
   
    /**
     * Tests the case that there are a wrapping f:validateBean with disabled
     * set to true and one nested f:validateBean. Also the BeanValidator is
     * a default-validator.
     * In this case all EditableValueHolders outside the wrapping f:validateBean
     * and the one EditableValueHolder which is wrapped, but has a f:validateBean
     * itself should have the BeanValidator installed.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testValidateBeanNestingAndNested() throws IOException
    {
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // put the disabled value on the request scope
        externalContext.getRequestMap().put("validateBeanDisabled", Boolean.TRUE);
       
        // build testValidateBeanNestingAndNested.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanNestingAndNested.xhtml");
       
        // get the component instances
        UIInput nestedinput = (UIInput) root.findComponent("form:nestedinput");
        UIInput nestedinputWithValidator = (UIInput) root.findComponent("form:nestedinputWithValidator");
        UIInput nonnestedinput = (UIInput) root.findComponent("form:nonnestedinput");
       
        // no wrapped UIInput has to have the BeanValidator installed,
        // except the one nesting <f:validateBean /> itself.
        Assert.assertFalse(_hasValidator(nestedinput, BeanValidator.class));
        Assert.assertTrue(_hasValidator(nestedinputWithValidator, BeanValidator.class));
        Assert.assertTrue(_hasValidator(nonnestedinput, BeanValidator.class));
    }
   
    /**
     * Tests if the validationGroups are set correctly.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testValidateBeanValidationGroups() throws IOException
    {
        final String validationGroups = "org.apache.myfaces.beanvalidation.Group1," +
                "org.apache.myfaces.beanvalidation.Group2";
       
        // put the validationGroups on the request scope
        externalContext.getRequestMap().put("validationGroups", validationGroups);
       
        // build testValidateBean.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBean.xhtml");
       
        // get the component instances
        UIInput input = (UIInput) root.findComponent("form:input");
       
        // the validationGroups have to match
        Assert.assertEquals(validationGroups, _getValidationGroups(input));
    }
   
    /**
     * Tests the case that the BeanValidator is a default validator and the
     * UIInput on the facelet does not have a custom <f:validateBean> tag.
     * In this case the Default validation group has to be set on the BeanValidator.
     * @throws IOException
     */
    @Test
    public void testValidateBeanDefaultValidationGroup() throws IOException
    {
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // build testValidateBeanEmptyInput.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanEmptyInput.xhtml");
       
        // get the component instances
        UIInput input = (UIInput) root.findComponent("form:input");
       
        // the validationGroups have to match the Default ones
        Assert.assertEquals(javax.validation.groups.Default.class.getName(),
                _getValidationGroups(input));
    }
   
    /**
     * Tests the case that there is a wrapping <f:validateBean> on the facelet
     * with some validationGroups. These validationGroups should be applied to
     * all automatically added BeanValidators of all nested UIInput components.
     * The UIInput outside of the wrapping <f:validateBean> should get the
     * Default validation group.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testValidateBeanValidationGroupsNested() throws IOException
    {
        final String validationGroups = "org.apache.myfaces.beanvalidation.Group1";
       
        // put the validationGroups on the request scope
        externalContext.getRequestMap().put("validationGroups", validationGroups);
       
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // build testValidateBeanNesting.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanNesting.xhtml");
       
        // get the component instances
        UIInput nestedinput = (UIInput) root.findComponent("form:nestedinput");
        UIInput doublenestedinput = (UIInput) root.findComponent("form:doublenestedinput");
        UIInput nestedinput2 = (UIInput) root.findComponent("form:nestedinput2");
        UIInput nonnestedinput = (UIInput) root.findComponent("form:nonnestedinput");
       
        // the validationGroups in the wrapped components have to match
        // org.apache.myfaces.beanvalidation.Group1 and the non-nested ones
        // have to match the Default group.
        Assert.assertEquals(validationGroups, _getValidationGroups(nestedinput));
        Assert.assertEquals(validationGroups, _getValidationGroups(doublenestedinput));
        Assert.assertEquals(validationGroups, _getValidationGroups(nestedinput2));
        Assert.assertEquals(javax.validation.groups.Default.class.getName(),
                _getValidationGroups(nonnestedinput));
    }
   
    /**
     * Tests the case that there is a wrapping <f:validateBean> with some validationGroups
     * and one nested component has its own <f:validateBean> with different validationGroups.
     * In this case the nested component without a validator must get the wrapping validationGroups,
     * the nested component with the validator must get the validationGroups from the
     * validator and the non-nested component must get the Default validationGroups.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testValidateBeanValidationGroupsNestingAndNested() throws IOException
    {
        final String wrappingValidationGroups = "org.apache.myfaces.beanvalidation.Group1";
        final String componentValidationGroups = "org.apache.myfaces.beanvalidation.ACompletelyOtherGroup";
       
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // put the disabled value on the request scope
        externalContext.getRequestMap().put("validateBeanDisabled", Boolean.FALSE);
       
        // put the validationGroups on the request scope
        externalContext.getRequestMap().put("validationGroups", wrappingValidationGroups);
        externalContext.getRequestMap().put("validationGroupsComponent", componentValidationGroups);
       
        // build testValidateBeanNestingAndNested.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanNestingAndNested.xhtml");
       
        // get the component instances
        UIInput nestedinput = (UIInput) root.findComponent("form:nestedinput");
        UIInput nestedinputWithValidator = (UIInput) root.findComponent("form:nestedinputWithValidator");
        UIInput nonnestedinput = (UIInput) root.findComponent("form:nonnestedinput");
       
        // the nested component without a validator must get the wrapping validationGroups,
        // the nested component with the validator must get the validationGroups from the
        // validator and the non-nested component must get the Default validationGroups.
        Assert.assertEquals(wrappingValidationGroups, _getValidationGroups(nestedinput));
        Assert.assertEquals(componentValidationGroups, _getValidationGroups(nestedinputWithValidator));
        Assert.assertEquals(javax.validation.groups.Default.class.getName(),
                _getValidationGroups(nonnestedinput));
    }
   
    /**
     * Tests the case that there are two wrapping <f:validateBean> with different
     * validationGroups.
     * In this case the nested component must get the outer wrapping validationGroups,
     * the double-nested component must get the inner wrapping validationGroups
     * and the non-nested component must get the Default validationGroups.
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testValidateBeanValidationGroupsDoubleNesting() throws IOException
    {
        final String validationGroupsOuter = "org.apache.myfaces.beanvalidation.OuterGroup";
        final String validationGroupsInner = "org.apache.myfaces.beanvalidation.InnerGroup";
       
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // put the validationGroups on the request scope
        externalContext.getRequestMap().put("validationGroupsOuter", validationGroupsOuter);
        externalContext.getRequestMap().put("validationGroupsInner", validationGroupsInner);
       
        // build testValidateBeanDoubleNesting.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanDoubleNesting.xhtml");
       
        // get the component instances
        UIInput nestedinput = (UIInput) root.findComponent("form:nestedinput");
        UIInput doublenestedinput = (UIInput) root.findComponent("form:doublenestedinput");
        UIInput nonnestedinput = (UIInput) root.findComponent("form:nonnestedinput");
       
        // the nested component must get the outer wrapping validationGroups,
        // the double-nested component must get the inner wrapping validationGroups
        // and the non-nested component must get the Default validationGroups.
        Assert.assertEquals(validationGroupsOuter, _getValidationGroups(nestedinput));
        Assert.assertEquals(validationGroupsInner, _getValidationGroups(doublenestedinput));
        Assert.assertEquals(javax.validation.groups.Default.class.getName(),
                _getValidationGroups(nonnestedinput));
    }
   
    /**
     * Tests the case that the BeanValidator is installed as a default-validator,
     * but bean validation is not available in the classpath.
     * In this case the BeanValidator must not be installed. However MyFaces
     * provides a log message for this scenario.
     * @throws IOException
     */
    @Test
    public void testValidateBeanWithBeanValidationNotAvailable() throws IOException
    {
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // configure bean validation to be not available
        _setBeanValidationAvailable(false);
       
        // build testValidateBeanEmptyInput.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanEmptyInput.xhtml");
       
        // get the component instances
        UIInput input = (UIInput) root.findComponent("form:input");
       
        // the UIInput must not have the BeanValidator installed,
        // because bean validation is not available
        Assert.assertFalse(_hasValidator(input, BeanValidator.class));
    }

    /**
     *
     * @throws IOException
     */
    @Test
    @SuppressWarnings("unchecked")
    public void testValidateBeanValidationDisabledDoubleNesting() throws IOException
    {
        final String validationGroupsOuter = "org.apache.myfaces.beanvalidation.OuterGroup";
        final String validationGroupsInner = "org.apache.myfaces.beanvalidation.InnerGroup";
       
        // add the BeanValidator as default-validator
        application.addDefaultValidatorId(BeanValidator.VALIDATOR_ID);
       
        // put the validationGroups on the request scope
        externalContext.getRequestMap().put("validationGroupsOuter", validationGroupsOuter);
        externalContext.getRequestMap().put("validationGroupsInner", validationGroupsInner);
       
        // build testValidateBeanDoubleNesting.xhtml
        UIViewRoot root = facesContext.getViewRoot();
        vdl.buildView(facesContext, root, "testValidateBeanDisableDoubleNesting.xhtml");
       
        // get the component instances
        UIInput nestedinput = (UIInput) root.findComponent("form:nestedinput");
        UIInput doublenestedinput = (UIInput) root.findComponent("form:doublenestedinput");
        UIInput nonnestedinput = (UIInput) root.findComponent("form:nonnestedinput");
        UIInput nesteouterdisabledinput = (UIInput) root.findComponent("form:nesteouterdisabledinput");
       
        // the nested component must get the outer wrapping validationGroups,
        // the double-nested component must get the inner wrapping validationGroups
        // and the non-nested component must get the Default validationGroups.
        Assert.assertEquals(validationGroupsOuter, _getValidationGroups(nestedinput));
        Assert.assertFalse(_hasValidator(doublenestedinput, BeanValidator.class));
        Assert.assertEquals(validationGroupsInner, _getValidationGroups(nesteouterdisabledinput));
        Assert.assertEquals(javax.validation.groups.Default.class.getName(),
                _getValidationGroups(nonnestedinput));
    }

}
TOP

Related Classes of org.apache.myfaces.view.facelets.tag.jsf.core.ValidateBeanTestCase

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.