com.meltmedia.cadmium.servlets.ErrorPageFilterSelectionTest.java Source code

Java tutorial

Introduction

Here is the source code for com.meltmedia.cadmium.servlets.ErrorPageFilterSelectionTest.java

Source

/**
 *    Copyright 2012 meltmedia
 *
 *    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 com.meltmedia.cadmium.servlets;

import com.meltmedia.cadmium.core.ContentService;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.CharSequenceInputStream;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Arrays;
import java.util.Collection;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;

/**
 * Tests the selection of the proper error page by the ErrorPageFilter servlet.
 * 
 * @author Christian Trimble
 */
@RunWith(Parameterized.class)
public class ErrorPageFilterSelectionTest {

    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] { { sendErrorFilterChain(404), "patient/404", "/patient/blah" },
                { sendErrorFilterChain(407), "40x", "/hcp/ehh" },
                { sendErrorFilterChain(412), "patient/4xx", "/patient/blah/ehh" },
                { sendErrorFilterChain(501), "501", "/" }, { sendErrorFilterChain(502), "50x", "/" },
                { sendErrorFilterChain(510), "5xx", "/" },
                { throwExceptionFilterChain(new Exception("Oops!")), "50x", "/" },
                { successFilterChain("Success"), "Success", "/" } });
    }

    /**
     * Creates a filter chain that calls sendError(int) with the specified status code.
     * 
     * @param statusCode the status code to send.
     * @return a filter chain that simulates a sendError condition.
     */
    public static FilterChain sendErrorFilterChain(final int statusCode) {
        return new FilterChain() {
            @Override
            public void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException {
                ((HttpServletResponse) res).sendError(statusCode);
            }
        };
    }

    /**
     * Creates a filter chain that throws a ServletException with the specified cause.
     * @param cause the cause of the exception that will be thrown.
     * @return a filter chain that simulates an exception.
     */
    public static FilterChain throwExceptionFilterChain(final Throwable cause) {
        return new FilterChain() {
            @Override
            public void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException {
                throw new ServletException(cause);
            }
        };
    }

    /**
     * Creates a filter chain that sends a 200 response.
     * 
     * @param content the content to write to the res object.
     * @return a filter chain that simulates a 200 response.
     */
    public static FilterChain successFilterChain(final String content) {
        return new FilterChain() {
            @Override
            public void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException {
                HttpServletResponse httpRes = (HttpServletResponse) res;
                httpRes.setStatus(200);
                OutputStream out = null;
                InputStream in = null;
                try {
                    out = res.getOutputStream();
                    in = new ByteArrayInputStream(content.getBytes());
                    IOUtils.copy(in, out);
                } finally {
                    IOUtils.closeQuietly(out);
                    IOUtils.closeQuietly(in);
                }
            }
        };
    }

    /**
     * The filter chain to execute inside the filter.
     */
    private FilterChain chain;

    /**
     * The content we expect to be written to the response writer.
     */
    private String expectedContent;

    /**
     * The filter that will be tested.
     */
    private ErrorPageFilter filter;

    /**
     * The path info for the simulated request.
     */
    private String pathInfo;

    /**
     * Creates a new test object from the parameters.
     * 
     * @param chain the chain that will be called in the filter.
     * @param expectedContent the expected content on the response writer.
     * @param pathInfo The path info for a simulated request.
     */
    public ErrorPageFilterSelectionTest(FilterChain chain, String expectedContent, String pathInfo) {
        this.chain = chain;
        this.expectedContent = expectedContent;
        this.pathInfo = pathInfo;
    }

    /**
     * Mock up the content service for the error pages and create the filter.
     * 
     * @throws ServletException if there is a problem initializing the filter.
     * @throws IOException if there is a problem mocking the content service.
     */
    @Before
    public void beforeTest() throws IOException, ServletException {
        ContentService contentService = mock(ContentService.class);
        when(contentService.getResourceAsStream(startsWith("/hcp"))).thenReturn(null);
        when(contentService.getResourceAsStream(startsWith("/patient/blah"))).thenReturn(null);
        when(contentService.getResourceAsStream("/404.html"))
                .thenReturn(new CharSequenceInputStream("404", "UTF-8"));
        when(contentService.getResourceAsStream("/patient/404.html"))
                .thenReturn(new CharSequenceInputStream("patient/404", "UTF-8"));
        when(contentService.getResourceAsStream("/patient/4xx.html"))
                .thenReturn(new CharSequenceInputStream("patient/4xx", "UTF-8"));
        when(contentService.getResourceAsStream("/407.html")).thenReturn(null);
        when(contentService.getResourceAsStream("/412.html")).thenReturn(null);
        when(contentService.getResourceAsStream("/40x.html"))
                .thenReturn(new CharSequenceInputStream("40x", "UTF-8"));
        when(contentService.getResourceAsStream("/41x.html")).thenReturn(null);
        when(contentService.getResourceAsStream("/4xx.html"))
                .thenReturn(new CharSequenceInputStream("4xx", "UTF-8"));
        when(contentService.getResourceAsStream("/501.html"))
                .thenReturn(new CharSequenceInputStream("501", "UTF-8"));
        when(contentService.getResourceAsStream("/502.html")).thenReturn(null);
        when(contentService.getResourceAsStream("/510.html")).thenReturn(null);
        when(contentService.getResourceAsStream("/50x.html"))
                .thenReturn(new CharSequenceInputStream("50x", "UTF-8"));
        when(contentService.getResourceAsStream("/51x.html")).thenReturn(null);
        when(contentService.getResourceAsStream("/5xx.html"))
                .thenReturn(new CharSequenceInputStream("5xx", "UTF-8"));

        filter = new ErrorPageFilter();
        filter.setContentService(contentService);

        filter.init(mock(FilterConfig.class));

    }

    /**
     * Clean up the filter that was tested.
     */
    @After
    public void afterTest() {
        filter.destroy();
    }

    /**
     * Calls doFilter on the ErrorPageFilter, capturing the output.  The output is compared to the expected output.
     * 
     * @throws IOException if there is an error in the test.
     * @throws ServletException if there is an error in the test.
     */
    @Test
    public void testFilterChainError() throws IOException, ServletException {
        final ByteArrayOutputStream resultWriter = new ByteArrayOutputStream();

        // Return the result writer for output.
        HttpServletResponse response = mock(HttpServletResponse.class);
        when(response.getOutputStream()).thenReturn(new ServletOutputStream() {
            @Override
            public void write(int i) throws IOException {
                resultWriter.write(i);
            }
        });
        HttpServletRequest request = mock(HttpServletRequest.class);
        when(request.getRequestURI()).thenReturn(pathInfo);
        // act
        filter.doFilter(request, response, chain);

        // assert
        assertEquals("The wrong error content was returned.", expectedContent, resultWriter.toString());
    }
}