/*
 *  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.renderkit.html;

import org.apache.myfaces.renderkit.html.base.HtmlRendererUtils;
import org.junit.Assert;
import org.apache.myfaces.renderkit.ClientBehaviorEvents;
import org.apache.myfaces.test.base.AbstractJsfTestCase;

import javax.faces.component.UIComponent;
import javax.faces.component.behavior.*;
import javax.faces.component.html.HtmlInputText;

import java.util.*;
import org.apache.myfaces.config.MyfacesConfig;
import org.apache.myfaces.renderkit.html.base.ClientBehaviorRendererUtils;

public class ClientBehaviorRendererUtilsTest extends AbstractJsfTestCase
{

    public ClientBehaviorRendererUtilsTest(String name)
    {
        super(name);
    }
    
    public void setUp() throws Exception
    {
        super.setUp();
        
        servletContext.addInitParameter(MyfacesConfig.RENDER_CLIENTBEHAVIOR_SCRIPTS_AS_STRING, "true");
    }

    public void testBuildBehaviorChain()
    {
        Map<String, List<ClientBehavior>> behaviors = new HashMap<String, List<ClientBehavior>>();

        //Map<String, String> params = new HashMap<String, String>();
        Collection<ClientBehaviorContext.Parameter> params = new ArrayList<ClientBehaviorContext.Parameter>();
        
        UIComponent component = new HtmlInputText();
        Assert.assertEquals("", ClientBehaviorRendererUtils.buildBehaviorChain(facesContext, component, 
                component.getClientId(facesContext),
                ClientBehaviorEvents.CLICK, params, ClientBehaviorEvents.ACTION, params, behaviors, null,
                null));

        Assert.assertEquals("return jsf.util.chain(document.getElementById('j_id__v_0'), event,'huhn', 'suppe');",
                ClientBehaviorRendererUtils.buildBehaviorChain(facesContext,
                        component, component.getClientId(facesContext), ClientBehaviorEvents.CLICK, 
                        params, ClientBehaviorEvents.ACTION, params, behaviors, "huhn",
                        "suppe"));

        ClientBehavior submittingBehavior = new ClientBehaviorBase()
        {
            @Override
            public String getScript(ClientBehaviorContext behaviorContext)
            {
                return "script()";
            }

            @Override
            public Set<ClientBehaviorHint> getHints()
            {
                return EnumSet.allOf(ClientBehaviorHint.class);
            }
        };

        behaviors.put(ClientBehaviorEvents.CLICK, Arrays.asList(submittingBehavior));

        Assert.assertEquals("jsf.util.chain(document.getElementById('j_id__v_0'), event,'huhn', 'script()', 'suppe'); return false;",
                ClientBehaviorRendererUtils.buildBehaviorChain(facesContext,
                        component, component.getClientId(facesContext),
                        ClientBehaviorEvents.CLICK, params, ClientBehaviorEvents.ACTION, params, behaviors, "huhn",
                        "suppe"));

    }
    
    public void testBuildBehaviorChain2()
    {
        Map<String, List<ClientBehavior>> behaviors = new HashMap<String, List<ClientBehavior>>();

        //Map<String, String> params = new HashMap<String, String>();
        Collection<ClientBehaviorContext.Parameter> params = new ArrayList<ClientBehaviorContext.Parameter>();
        
        UIComponent component = new HtmlInputText();
        Assert.assertEquals("", ClientBehaviorRendererUtils.buildBehaviorChain(facesContext, component, 
                ClientBehaviorEvents.CLICK, params, ClientBehaviorEvents.ACTION, params, behaviors, null,
                null));

        Assert.assertEquals("return jsf.util.chain(this, event,'huhn', 'suppe');",
                ClientBehaviorRendererUtils.buildBehaviorChain(facesContext,
                        component, ClientBehaviorEvents.CLICK, params, ClientBehaviorEvents.ACTION, params, behaviors, "huhn",
                        "suppe"));

        ClientBehavior submittingBehavior = new ClientBehaviorBase()
        {
            @Override
            public String getScript(ClientBehaviorContext behaviorContext)
            {
                return "script()";
            }

            @Override
            public Set<ClientBehaviorHint> getHints()
            {
                return EnumSet.allOf(ClientBehaviorHint.class);
            }
        };

        behaviors.put(ClientBehaviorEvents.CLICK, Arrays.asList(submittingBehavior));

        Assert.assertEquals("jsf.util.chain(this, event,'huhn', 'script()', 'suppe'); return false;",
                ClientBehaviorRendererUtils.buildBehaviorChain(facesContext,
                        component, 
                        ClientBehaviorEvents.CLICK, params, ClientBehaviorEvents.ACTION, params, behaviors, "huhn",
                        "suppe"));

    }    
    
    public void testEscapeJavaScriptForChain()
    {
        
        Assert.assertEquals("var foo = &quot; \\\\&quot; test &quot;; alert(foo);", ClientBehaviorRendererUtils.escapeJavaScriptForChain("var foo = &quot; \\&quot; test &quot;; alert(foo);"));
        
        Assert.assertEquals("var foo = \\'bar \\'", ClientBehaviorRendererUtils.escapeJavaScriptForChain("var foo = 'bar '"));
        
        Assert.assertEquals("var foo = \\'bar \\\\\\' \\'", ClientBehaviorRendererUtils.escapeJavaScriptForChain("var foo = 'bar \\' '"));
    }
}