org.apache.cocoon.HtmlUnitTestCase.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.cocoon.HtmlUnitTestCase.java

Source

/*
 * Copyright 1999-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.
 */
package org.apache.cocoon;

import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.SubmitMethod;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebResponse;
import com.gargoylesoftware.htmlunit.html.DomNode;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.xpath.HtmlUnitXPath;
import com.gargoylesoftware.htmlunit.xml.XmlPage;

import junit.framework.TestCase;

import org.apache.avalon.framework.logger.ConsoleLogger;
import org.apache.avalon.framework.logger.Logger;

import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;

import org.apache.commons.io.FileUtils;

import org.jaxen.SimpleNamespaceContext;
import org.jaxen.XPath;
import org.jaxen.dom.DOMXPath;

import org.w3c.dom.Document;
import org.w3c.dom.Node;

import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Base class to run test cases on Cocoon samples.
 * <p>
 *   This class extends the JUnit TestCase class to setup an environment which
 *   makes it possible to easily test Cocoon pages.
 *   First call one of the load methods and then assert on the response object,
 *   XML document (@see loadXmlPage), or HTML document (@see loadHtmlPage). 
 * </p>
 * <p>
 *   Examples:
 * </p>
 * <pre>
 *   public void testStatus() {
 *     loadResponse("/samples/test/status");
 *     assertEquals("Status code", 200, response.getStatusCode());
 *   }
 *
 *   public void testTitle() {
 *     loadHtmlPage("/samples/test/title");
 *     assertXPath("html/head/title"", "The Title");
 *   }
 * </pre>
 *
 * <p>
 *   For loading XML and HTML documents currently on GET requests with
 *   optional querystring are supported.  Please add POST requests and
 *   request parameters when you need them.
 * </p>
 * @version $Id: $
 */
public abstract class HtmlUnitTestCase extends TestCase {
    /**
     * Logger for informative output by test cases.
     * The default log level is WARN but may be changed by setting the
     * property junit.test.loglevel to a different numeric value.
     */
    protected Logger logger;

    /**
     * Base URL of the running Cocoon server which is to be tested.
     * Set by property htmlunit.test.baseurl usually as http://localhost:8888/.
     */
    protected URL baseURL;

    /**
     * Low-level access to WebClient object.
     */
    protected WebClient webClient;

    /**
     * Low-level access to WebResponse object.
     */
    protected WebResponse response;

    /**
     * Low-level access to XML document (org.w3c.dom.Document) or HTML document
     * (com.gargoylesoftware.htmlunit.html.HtmlPage).
     */
    protected Object document;

    /**
     * Low-level access to namespace mappings for XPath expressions.
     */
    protected Map namespaces = new HashMap();

    /* (non-Javadoc)
     * @see junit.framework.TestCase#setUp()
     */
    protected void setUp() throws Exception {
        super.setUp();

        String level = System.getProperty("junit.test.loglevel", "" + ConsoleLogger.LEVEL_WARN);
        this.logger = new ConsoleLogger(Integer.parseInt(level));

        String baseurl = System.getProperty("htmlunit.test.baseurl");
        this.baseURL = new URL(baseurl);
        this.webClient = new WebClient();
        this.webClient.setRedirectEnabled(false);
        this.namespaces.clear();
    }

    /* (non-Javadoc)
     * @see junit.framework.TestCase#tearDown()
     */
    protected void tearDown() throws Exception {
        this.response = null;
        this.document = null;

        super.tearDown();
    }

    /**
     * Sends HTTP GET request and loads response object.
     */
    protected void loadResponse(String pageURL) throws Exception {
        URL url = new URL(baseURL, pageURL);
        this.response = webClient.loadWebResponse(url, SubmitMethod.GET, new ArrayList(0));
    }

    /**
     * Sends HTTP DELETE request and loads response object.
     */
    protected void loadDeleteResponse(String pageURL) throws Exception {
        URL url = new URL(baseURL, pageURL);
        DeleteMethod method = new DeleteMethod(url.toExternalForm());
        this.response = new HttpClientResponse(url, method);
    }

    /**
     * Sends HTTP PUT request and loads response object.
     */
    protected void loadPutResponse(String pageURL, String content) throws Exception {
        URL url = new URL(baseURL, pageURL);
        PutMethod method = new PutMethod(url.toExternalForm());
        method.setRequestEntity(new StringRequestEntity(content));
        this.response = new HttpClientResponse(url, method);
    }

    /**
     * Sends HTTP request and parses response as HTML document.
     */
    protected void loadHtmlPage(String pageURL) throws Exception {
        URL url = new URL(baseURL, pageURL);
        Page page = webClient.getPage(url);
        this.response = page.getWebResponse();
        assertTrue("Response should be an HTML page", page instanceof HtmlPage);
        this.document = page;
        assertNotNull("Response contains invalid HTML", this.document);
    }

    /**
     * Sends HTTP request and parses response as XML document.
     */
    protected void loadXmlPage(String pageURL) throws Exception {
        URL url = new URL(baseURL, pageURL);
        Page page = webClient.getPage(url);
        this.response = page.getWebResponse();
        assertTrue("Response should be an XML page", page instanceof XmlPage);
        XmlPage xmlPage = (XmlPage) page;
        this.document = xmlPage.getXmlDocument();
        assertNotNull("Response contains invalid XML", this.document);
    }

    /**
     * Returns XPath expression as string.
     *
     * @param xpathExpr XPath expression
     *
     * @return Value of XPath expression in current document.
     *         Empty string if XPath not matched.
     */
    protected String evalXPath(String xpathExpr) throws Exception {
        XPath xpath = null;
        if (document == null)
            return null;
        else if (document instanceof HtmlPage)
            xpath = new HtmlUnitXPath(xpathExpr);
        else if (document instanceof Document)
            xpath = new DOMXPath(xpathExpr);
        else
            fail("Document type " + document.getClass().getName());

        xpath.setNamespaceContext(new SimpleNamespaceContext(namespaces));

        return xpath.stringValueOf(document);
    }

    /**
     * Add a namespace mapping for XPath expressions.
     */
    protected void addNamespace(String prefix, String uri) throws Exception {
        namespaces.put(prefix, uri);
    }

    /**
     * Assert that XPath expression result matches exactly expected value.
     */
    protected void assertXPath(String xpathExpr, String expected) throws Exception {
        assertEquals(xpathExpr, expected, evalXPath(xpathExpr));
    }

    /**
     * Copy file from webapp source to deployment area filtering content
     * to replace parameter by value.
     * The source and deployment directories are defined by the properties
     * htmlunit.test.source-dir and htmlunit.test.deploy-dir.
     *
     * This method is most useful for testing the automatic reloading of
     * changed files.
     */
    protected void copyWebappFile(String filename, String param, String value) throws Exception {
        String srcdir = System.getProperty("htmlunit.test.source-dir");
        String dstdir = System.getProperty("htmlunit.test.deploy-dir");
        File srcfile = new File(srcdir + "/" + filename);
        File dstfile = new File(dstdir + "/" + filename);

        final String encoding = "ISO-8859-1";
        StringBuffer content = new StringBuffer(FileUtils.readFileToString(srcfile, encoding));

        int index = content.indexOf(param);
        while (index != -1) {
            content.replace(index, index + param.length(), value);
            index = content.indexOf(param, index + 1);
        }

        FileUtils.writeStringToFile(dstfile, content.toString(), encoding);

        // Leave server some time to realize that file has changed.

        Thread.sleep(1000);
    }
}