<?xml version="1.0"?>
<!--
  Copyright 2002,2004 The Apache Software Foundation.
  
  Licensed 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.
-->
<j:jelly
    xmlns:j="jelly:core"
    xmlns="jelly:http"
    trim="false">
    <!-- a session holds shared http state info -->
    <session>
Tests for Get tag
-----------------
        <get var="mtc" uri="http://www.multitask.com.au/"/>
        <j:if test='${mtc.statusCode == 200}'>
            request ok
        </j:if>
            Results for mtc url are:
            http return code = ${mtc.statusCode}
            http status text = '${mtc.statusText}'
            size of result = ${mtc.responseBodyAsString.length()}
            response time = ${mtc.responseTime}
            
        <j:forEach items="${mtc.responseHeaders}" var="header" indexVar="i">
            header[${i}] = ${header}
        </j:forEach>
        
        <!-- test parameters and headers -->
        <get var="mtc2" uri="http://www.multitask.com.au/default.html">
            <parameter name="page" value="mt @News"/>
            <parameter name="page2" value="junk"/>
            <header name="Content-Type" value="text/plain"/>
        </get>
        queryString = ${mtc2.queryString}, length = ${mtc2.responseBodyAsString.length()}
        response time = ${mtc2.responseTime}
        <j:forEach items="${mtc2.requestHeaders}" var="rHeader" indexVar="i">
            reqHeader[${i}] = ${rHeader}
        </j:forEach>
        <!-- test a 404 -->
        <get var="badurl" uri="http://www.multitask.com.au/snafu.html"/>
        http return code = ${badurl.statusCode}
        bad response time = ${badurl.responseTime} in msec
Tests for Post tag
------------------
        <post var="jdc" uri="http://developer.java.sun.com/servlet/SessionServlet">
            <parameter name="action" value="login" />
            <parameter name="url" value="/developer/index.jshtml" />
            <parameter name="UserId" value="XXXX" />
            <parameter name="Password" value="XXXX" />
        </post>
        jdc login result = ${jdc.statusCode}
        good login = ${jdc.responseBodyAsString.indexOf("Sorry!") == "-1"}

        jdc response time = ${jdc.responseTime} in msec
        <j:forEach items="${jdc.responseHeaders}" var="header" indexVar="i">
            jdc.header[${i}] = ${header}
        </j:forEach>
Tests for Head tag
------------------
        <head var="jakarta" uri="http://jakarta.apache.org/"/>
        <j:forEach items="${jakarta.responseHeaders}" var="header" indexVar="i">
            header[${i}] = ${header}
        </j:forEach>
Tests for Options tag
---------------------
        <options var="ms" uri="http://www.microsoft.com/"/>
        <j:forEach items="${ms.responseHeaders}" var="header" indexVar="i">
            header[${i}] = ${header}
        </j:forEach>
Tests for Body tag
------------------
        <j:set var="googleKey" value="00000000000000000000000000000000" />
        <post var="google" uri="http://api.google.com/search/beta2">
            <header name="Content-Type" value="text/xml"/>
            <body>
            <env:Envelope
                xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" 
                xmlns:xsd="http://www.w3.org/1999/XMLSchema">
              <env:Body>
                <ns1:doGoogleSearch xmlns:ns1="urn:GoogleSearch"
                     env:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                  <ns1:key xsi:type="xsd:string">${googleKey}</ns1:key>
                  <ns1:q xsi:type="xsd:string">jelly java xml</ns1:q>
                  <ns1:start xsi:type="xsd:int">0</ns1:start>
                  <ns1:maxResults xsi:type="xsd:int">10</ns1:maxResults>
                  <ns1:filter xsi:type="xsd:boolean">true</ns1:filter>
                  <ns1:restrict xsi:type="xsd:string"></ns1:restrict>
                  <ns1:safeSearch xsi:type="xsd:boolean">false</ns1:safeSearch>
                  <ns1:lr xsi:type="xsd:string"></ns1:lr>
                  <ns1:ie xsi:type="xsd:string">latin1</ns1:ie>
                  <ns1:oe xsi:type="xsd:string">latin1</ns1:oe>
                </ns1:doGoogleSearch>
              </env:Body>
            </env:Envelope>
            </body>
        </post>
        <j:forEach items="${google.requestHeaders}" var="rHeader" indexVar="i">
            reqHeader[${i}] = ${rHeader}
        </j:forEach>
        google response = ${google.statusCode}, ${google.statusText}
        ${google.responseBodyAsString}
    </session>
    
    <session>
Tests for Cookie tag
---------------------
        <post var="ph" uri="http://www.pizzahut.com.au/logon.do">
            <parameter name="username" value="xxx"/>
            <parameter name="password" value="xxx"/>
            <parameter name="actionToDo" value="continue"/>
            <parameter name="target" value="registration"/>
        </post>
        SC: ${ph.getResponseHeader("Set-Cookie")}
        <!-- show how to dump cookie name/value pairse -->
        <j:forEach items='${ph.getResponseHeader("Set-Cookie").values}'
            var="element" indexVar="i">
            element[${i}] = ${element}
        </j:forEach>
        
    </session>
 
    <get var="nosessionBad" uri="http://www.multitask.com.au/snafu.html"/>
    outside session get - ${nosessionBad.statusText}
    <get var="nosessionGood" uri="http://www.multitask.com.au/"/>
    outside session get good - ${nosessionGood.statusText}
    
</j:jelly>
