/*
 * 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.axis2.scripting;

import junit.framework.TestCase;
import org.apache.axiom.om.OMElement;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.description.AxisService;
import org.apache.axis2.description.Parameter;

import java.util.Iterator;

public class ScriptReceiverTest extends TestCase {
    
    public void testInvokeBusinessLogic() throws AxisFault {
        ScriptReceiver scriptReceiver = new ScriptReceiver();
        MessageContext inMC = TestUtils.createMockMessageContext("<a>petra</a>");
        AxisService axisService = inMC.getAxisService();
        axisService.addParameter(new Parameter(ScriptReceiver.SCRIPT_ATTR, "foo.js"));
        axisService.addParameter(new Parameter(ScriptReceiver.SCRIPT_SRC_PROP,
                                               "function invoke(inMC,outMC) " +
                                                       "{outMC.setPayloadXML(<a>petra</a>) }"));
        inMC.setAxisService(axisService);
        scriptReceiver.invokeBusinessLogic(inMC, inMC);
        Iterator iterator = inMC.getEnvelope().getChildElements();
        iterator.next();
        assertEquals("<a>petra</a>", ((OMElement) iterator.next()).getFirstElement().toString());
    }

    public void testAxisService() throws AxisFault {
        ScriptReceiver scriptReceiver = new ScriptReceiver();
        MessageContext inMC = TestUtils.createMockMessageContext("<a>petra</a>");
        AxisService axisService = inMC.getAxisService();
        axisService.addParameter(new Parameter(ScriptReceiver.SCRIPT_ATTR, "foo.js"));
        axisService.addParameter(ScriptReceiver.SCRIPT_SRC_PROP,
                                "var scope = _AxisService.getScope();function invoke(inMC,outMC) " +
                                        "{outMC.setPayloadXML(<a>{scope}</a>) }");
        scriptReceiver.invokeBusinessLogic(inMC, inMC);
        Iterator iterator = inMC.getEnvelope().getChildElements();
        iterator.next();
        assertEquals("<a>request</a>", ((OMElement) iterator.next()).getFirstElement().toString());
    }

}
