/*
 * 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.extensions.validator.test.propval.crossval;

import javax.faces.component.UIViewRoot;
import javax.faces.component.html.HtmlForm;
import javax.faces.component.html.HtmlInputText;
import javax.faces.convert.DateTimeConverter;

import org.apache.myfaces.extensions.validator.test.propval.AbstractPropertyValidationTestCase;
import org.junit.Test;

import java.util.Date;

/**
 */
public class ELCrossValTestCase extends AbstractPropertyValidationTestCase
{
    HtmlInputText inputComponent1 = null;
    HtmlInputText inputComponent2 = null;

    UIViewRoot rootComponent = null;

    public ELCrossValTestCase()
    {
         inputComponent1 = null;
        inputComponent2 = null;
        rootComponent = null;
    }

    @Override
    protected void setUpTestCase()
    {
        super.setUpTestCase();
        createRequestScopedBean("bean1", getEntityInstance());
        createRequestScopedBean("bean2", getEntityInstance());


        rootComponent = new UIViewRoot();
        HtmlForm form = new HtmlForm();
        form.setId("form");
        rootComponent.getChildren().add(form);

        //input1
        inputComponent1 = new HtmlInputText();
        inputComponent1.setId("input1");
        inputComponent1.setConverter(new DateTimeConverter());
        ((DateTimeConverter)inputComponent1.getConverter()).setPattern("dd.MM.yyyy");
        form.getChildren().add(inputComponent1);

        //input2
        inputComponent2 = new HtmlInputText();
        inputComponent2.setId("input2");
        inputComponent2.setConverter(new DateTimeConverter());
        ((DateTimeConverter)inputComponent2.getConverter()).setPattern("dd.MM.yyyy");
        form.getChildren().add(inputComponent2);
    }


    @Test
    public void testCrossComponentEqualsValidationCorrect() throws Exception
    {
        validateELCrossComponentValidationUseCase("14.05.1983", "14.05.1983", "14.05.1983", "14.05.1983");

        checkMessageCount(0);
    }

    @Test
    public void testCrossComponentEqualsValidationFailedValidation() throws Exception
    {
        validateELCrossComponentValidationUseCase("14.05.1983", "14.05.1983", "14.05.1983", "12.12.2008");

        checkMessageCount(2);
    }

    private void validateELCrossComponentValidationUseCase(String valueBean1Property1, String valueBean1Property2, String valueBean2Property1, String valueBean2Property2)
    {
        createValueBinding(inputComponent1, "value", "#{bean1.date1}");
        createValueBinding(inputComponent2, "value", "#{bean2.date2}");

        //set model values
        resolveBean("bean1", getEntityInstance().getClass()).setDate2((Date)inputComponent1.getConverter().getAsObject(facesContext, inputComponent1, valueBean1Property2));
        resolveBean("bean2", getEntityInstance().getClass()).setDate1((Date)inputComponent2.getConverter().getAsObject(facesContext, inputComponent2, valueBean2Property1));


        //decode
        inputComponent1.setSubmittedValue(valueBean1Property1);
        inputComponent2.setSubmittedValue(valueBean2Property2);

        //validate
        inputComponent1.validate(facesContext);
        inputComponent2.validate(facesContext);

        processCrossValidation();

        //no update model needed
    }

    @Test
    public void testModelAwareCrossEqualsValidationCorrect() throws Exception
    {
        validateELModelAwareCrossValidationUseCase("14.05.1983", "14.05.1983", "14.05.1983", "14.05.1983");

        checkMessageCount(0);
    }

    @Test
    public void testModelAwareCrossEqualsValidationFailedValidation() throws Exception
    {
        validateELModelAwareCrossValidationUseCase("14.05.1983", "14.05.1983", "14.05.1983", "12.12.2008");

        checkMessageCount(1);
    }


    private void validateELModelAwareCrossValidationUseCase(String valueBean1Property1, String valueBean1Property2, String valueBean2Property1, String valueBean2Property2)
    {
        createValueBinding(inputComponent1, "value", "#{bean1.date1}");

        //set model values
        resolveBean("bean1", getEntityInstance().getClass()).setDate2((Date)inputComponent1.getConverter().getAsObject(facesContext, inputComponent1, valueBean1Property2));
        resolveBean("bean2", getEntityInstance().getClass()).setDate1((Date)inputComponent2.getConverter().getAsObject(facesContext, inputComponent2, valueBean2Property1));
        resolveBean("bean2", getEntityInstance().getClass()).setDate2((Date)inputComponent2.getConverter().getAsObject(facesContext, inputComponent2, valueBean2Property2));


        //decode
        inputComponent1.setSubmittedValue(valueBean1Property1);

        //validate
        inputComponent1.validate(facesContext);

        processCrossValidation();

        //no update model needed
    }

    protected ELCrossValTestDateBean getEntityInstance()
    {
        return new ELCrossValTestDateBean();
    }
}