org.javalite.activeweb.RequestDispatcherSpec.java Source code

Java tutorial

Introduction

Here is the source code for org.javalite.activeweb.RequestDispatcherSpec.java

Source

/*
Copyright 2009-2014 Igor Polevoy
    
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.javalite.activeweb;

import org.javalite.test.XPathHelper;
import org.junit.Before;
import org.junit.Test;
import org.springframework.mock.web.MockHttpServletResponse;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import java.io.IOException;

import static org.javalite.test.SystemStreamUtil.*;

/**
 * @author Igor Polevoy
 */
public class RequestDispatcherSpec extends RequestSpec {

    private boolean fellThrough = false;

    private FilterChain badFilterChain;

    @Before
    public void beforeStart() {
        filterChain = new FilterChain() {
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
                    throws IOException, ServletException {
                fellThrough = true;
            }
        };

        badFilterChain = new FilterChain() {
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse)
                    throws IOException, ServletException {
                throw new RuntimeException("I'm a bad... bad exception!");
            }
        };
        Configuration.setUseDefaultLayoutForErrors(true);
    }

    @Test
    public void shouldFallThroughIfRootControllerMissingAndRootPathRequired() throws IOException, ServletException {

        request.setServletPath("/");
        request.setMethod("GET");

        dispatcher.doFilter(request, response, filterChain);
        a(getSystemErr().contains("URI is: '/', but root controller not set")).shouldBeTrue();
    }

    @Test
    public void shouldExcludeImageExclusions() throws IOException, ServletException {

        request.setServletPath("/images/greeting.jpg");
        request.setMethod("GET");
        config.addInitParameter("exclusions", "css,images,js");
        dispatcher.init(config);
        dispatcher.doFilter(request, response, filterChain);

        a(fellThrough).shouldBeTrue();
    }

    @Test
    public void shouldExcludeCssExclusions() throws IOException, ServletException {

        request.setServletPath("/css/main.css");
        request.setMethod("GET");
        config.addInitParameter("exclusions", "css,images,js");
        dispatcher.init(config);
        dispatcher.doFilter(request, response, filterChain);

        a(fellThrough).shouldBeTrue();
    }

    @Test
    public void shouldExcludeHtmlExclusions() throws IOException, ServletException {

        request.setServletPath("/index.html");
        request.setMethod("GET");
        config.addInitParameter("exclusions", "css,images,js,html");
        dispatcher.init(config);
        dispatcher.doFilter(request, response, filterChain);

        a(fellThrough).shouldBeTrue();
    }

    /**
     * If there is exception in the FilterChain below RequestDispatcher, it should not
     * attempt to do anything to it. 
     *
     * @throws IOException
     * @throws ServletException
     */
    @Test
    public void shouldPassExternalExceptionUpTheStack() throws IOException, ServletException {
        request.setServletPath("/css/main.css");
        request.setMethod("GET");
        config.addInitParameter("exclusions", "css,images,js");
        dispatcher.init(config);
        dispatcher.doFilter(request, response, badFilterChain);
        a(response.getContentAsString()).shouldContain("I'm a bad... bad exception!");
    }

    @Test
    public void shouldExecuteSimpleController() throws IOException, ServletException {

        System.setProperty("active_reload", "true");

        request.setServletPath("/hello");
        request.setMethod("GET");

        dispatcher.doFilter(request, response, filterChain);

        String html = response.getContentAsString();
        a(XPathHelper.count("//div", html)).shouldBeEqual(3);
        a(XPathHelper.selectText("//div[@id='content']", html)).shouldBeEqual("hello");
    }

    @Test
    public void shouldRenderSystemErrorIfControllerFailsMiserably() throws ServletException, IOException {
        request.setServletPath("/failing");
        request.setMethod("GET");

        dispatcher.doFilter(request, response, filterChain);

        a(getSystemErr().contains("java.lang.ArithmeticException")).shouldBeTrue();

        a(response.getContentType()).shouldBeEqual("text/html");

        a(response.getContentAsString()).shouldContain("/ by zero");// this is coming from a system/error.ftl
        a(response.getStatus()).shouldBeEqual(500);
    }

    @Test
    public void shouldSend404ErrorIfControllerMissing() throws IOException, ServletException {

        request.setServletPath("/does_not_exist");
        request.setMethod("GET");

        dispatcher.doFilter(request, response, filterChain);

        a(getSystemErr().contains("java.lang.ClassNotFoundException: app.controllers.DoesNotExistController"))
                .shouldBeTrue();

        String html = response.getContentAsString();

        a(XPathHelper.count("//div", html)).shouldBeEqual(3);
        a(XPathHelper.selectText("//div[@id='content']", html))
                .shouldBeEqual("java.lang.ClassNotFoundException: app.controllers.DoesNotExistController");
        a(response.getStatus()).shouldBeEqual(404);
    }

    @Test
    public void shouldSendSystemErrorIfControllerCantCompile() throws IOException, ServletException {

        request.setServletPath("/does_not_exist");
        request.setMethod("GET");
        request.getSession(true).setAttribute("message", "this is only a test");

        dispatcher.doFilter(request, response, filterChain);

        a(getSystemErr().contains("java.lang.ClassNotFoundException: app.controllers.DoesNotExistController"))
                .shouldBeTrue();

        String html = response.getContentAsString();
        System.out.println(html);

        a(XPathHelper.count("//div", html)).shouldBeEqual(3);
        a(XPathHelper.selectText("//div[@id='content']", html))
                .shouldBeEqual("java.lang.ClassNotFoundException: app.controllers.DoesNotExistController");

    }

    @Test
    public void shouldSend404IfControllerDoesNotExtendAppController() throws ServletException, IOException {

        request.setServletPath("/blah");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);

        a(getSystemErr().contains("are you sure it extends " + AppController.class.getName())).shouldBeTrue();

        String html = response.getContentAsString();

        a(XPathHelper.count("//div", html)).shouldBeEqual(3);
        a(XPathHelper.selectText("//div[@id='content']", html)).shouldBeEqual(
                "Class: app.controllers.BlahController is not the expected type, are you sure it extends org.javalite.activeweb.AppController?");
    }

    @Test
    public void shouldSend404IfActionMissing() throws ServletException, IOException {

        request.setServletPath("/hello/hello");
        request.setMethod("GET");

        dispatcher.doFilter(request, response, filterChain);

        a(getSystemErr().contains("java.lang.NoSuchMethodException: app.controllers.HelloController.hello("))
                .shouldBeTrue();

        String html = response.getContentAsString();

        a(XPathHelper.count("//div", html)).shouldBeEqual(3);
        a(XPathHelper.selectText("//div[@id='content']", html)).shouldBeEqual(
                "java.lang.NoSuchMethodException: app.controllers.HelloController.hello(); app.controllers.HelloController.hello()");
    }

    @Test
    public void shouldSend404IfTemplateIsMissing() throws ServletException, IOException {

        request.setServletPath("/hello/no-view");
        request.setMethod("GET");

        dispatcher.doFilter(request, response, filterChain);

        System.out.println(getSystemErr());
        a(getSystemErr().contains("Template \"/hello/no-view.ftl\" not found.")).shouldBeTrue();

        String html = response.getContentAsString();

        a(XPathHelper.count("//div", html)).shouldBeEqual(3);
        a(XPathHelper.selectText("//div[@id='content']", html)).shouldBeEqual(
                "Failed to render template: 'src/test/views/hello/no-view.ftl', with layout: 'src/test/views/layouts/default_layout'; Template \"/hello/no-view.ftl\" not found.");
    }

    @Test
    public void shouldSend500IfTemplateIsNotParsable() throws ServletException, IOException {

        request.setServletPath("/hello/bad-bad-template");
        request.setMethod("GET");

        dispatcher.doFilter(request, response, filterChain);
        String html = response.getContentAsString();
        a(XPathHelper.selectText("//div[@id='content']", html).contains("Unexpected end of file reached"))
                .shouldBeTrue();
    }

    @Test
    public void shouldSend500WithoutDefaultLayout() throws ServletException, IOException {

        Configuration.setUseDefaultLayoutForErrors(false);
        request.setServletPath("/hello/bad-bad-template");
        request.setMethod("GET");

        dispatcher.doFilter(request, response, filterChain);
        String html = response.getContentAsString();

        a(html.contains("default layout")).shouldBeFalse();
    }

    @Test
    public void shouldRenderWithDefaultLayout() throws ServletException, IOException {
        request.setServletPath("/hello");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        String html = response.getContentAsString();
        a(XPathHelper.selectText("//title", html)).shouldBeEqual("default layout");
    }

    @Test
    public void shouldRenderTemplateWithNoLayout() throws ServletException, IOException {
        request.setServletPath("/hello/no_layout");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        String resp = response.getContentAsString();
        a(resp).shouldBeEqual("no layout");
    }

    @Test
    public void shouldRenderWithCustomLayout() throws ServletException, IOException {
        request.setServletPath("/custom");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        String html = response.getContentAsString();
        a(XPathHelper.selectText("//title", html)).shouldBeEqual("custom layout");
    }

    @Test
    public void shouldRenderDifferentTemplateWithCustomLayout() throws ServletException, IOException {
        request.setServletPath("/custom/different");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        String html = response.getContentAsString();
        System.out.println(html);
        a(XPathHelper.selectText("//title", html)).shouldBeEqual("custom layout");
        a(XPathHelper.selectText("//div[@id='content']", html)).shouldBeEqual("different");
    }

    @Test
    public void shouldRenderErrorWithoutLayoutIfRequestIsAjax() throws ServletException, IOException {
        request.setServletPath("/ajax");
        request.setMethod("GET");
        request.addHeader("X-Requested-With", "XMLHttpRequest");
        dispatcher.doFilter(request, response, filterChain);
        String out = response.getContentAsString();
        the(out.contains("java.lang.ArithmeticException: / by zero")).shouldBeTrue();
    }

    @Test
    public void shouldCallDestroyOnAppBootstrap() throws ServletException, IOException {
        replaceError();
        dispatcher.destroy();
        a(getSystemErr()).shouldBeEqual("ahrrr! destroyed!");
    }

    @Test
    public void shouldNotWrapRuntimeException() throws IOException, ServletException {

        request.setServletPath("/db_exception");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        a(response.getContentAsString()).shouldEqual("this is an issue 88");
    }

    @Test
    public void shouldRenderTemplateWithFormatInUri() throws IOException, ServletException {
        request.setServletPath("/document.xml");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        a(response.getContentAsString()).shouldBeEqual("<message>this is xml document</message>");
    }

    @Test
    public void shouldRenderTemplateWithFormatInController() throws IOException, ServletException {
        request.setServletPath("/document/show.xml");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        a(response.getContentAsString()).shouldBeEqual("<message>XML from show action</message>");
    }

    @Test
    public void shouldOverrideTemplateFormatInController() throws IOException, ServletException {
        request.setServletPath("/document/text.xml");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        a(response.getContentAsString()).shouldBeEqual("this is a  text page");
    }

    @Test
    public void shouldUseDefaultLayoutForApplicationError() throws IOException, ServletException {
        request.setServletPath("/error");
        request.setMethod("GET");
        dispatcher.doFilter(request, response, filterChain);
        a(response.getContentAsString()).shouldContain("this is a header");
        a(response.getContentAsString()).shouldContain("this is an application error");
        a(response.getContentAsString()).shouldContain("this is a footer");
    }

    @Test
    public void shouldTurnOffDefaultLayoutForApplicationError() throws IOException, ServletException {
        request.setServletPath("/error");
        request.setMethod("GET");
        Configuration.setUseDefaultLayoutForErrors(false);
        dispatcher.doFilter(request, response, filterChain);
        a(response.getContentAsString()).shouldNotContain("this is a header");
        a(response.getContentAsString()).shouldContain("this is an application error");
        a(response.getContentAsString()).shouldNotContain("this is a footer");
        Configuration.setUseDefaultLayoutForErrors(true);
    }

    @Test
    public void shouldRenderSystemExceptionInCaseAjaxAndInternalError() throws IOException, ServletException {
        request.setServletPath("/ajax");
        request.setMethod("GET");
        request.addHeader("X-Requested-With", "XMLHttpRequest");
        dispatcher.doFilter(request, response, filterChain);
        a(response.getContentAsString()).shouldNotContain("html");
        a(response.getContentAsString()).shouldContain("java.lang.ArithmeticException: / by zero");
    }
}