package edu.northwestern.bioinformatics.studycalendar.web;

import static org.easymock.classextension.EasyMock.*;
import static org.easymock.classextension.EasyMock.*;
import org.easymock.classextension.EasyMock;
import org.easymock.ArgumentsMatcher;
import org.easymock.IArgumentMatcher;
import org.springframework.context.ApplicationContext;
import org.springframework.mock.web.MockFilterConfig;
import org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.PermissionDeniedDataAccessException;
import org.springframework.ui.ModelMap;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import java.io.IOException;

/**
 * @author Rhett Sutphin
 */
public class OpenSessionInViewInterceptorFilterTest extends ControllerTestCase {
    private OpenSessionInViewInterceptorFilter filter;
    private ApplicationContext applicationContext;
    private OpenSessionInViewInterceptor interceptor;
    private FilterChain filterChain;
    private WebRequestMatcher webRequestMatcher = new WebRequestMatcher();

    protected void setUp() throws Exception {
        super.setUp();
        applicationContext = registerMockFor(WebApplicationContext.class);
        interceptor = registerMockFor(OpenSessionInViewInterceptor.class);
        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, applicationContext);
        expect(applicationContext.getBean("openSessionInViewInterceptor")).andReturn(interceptor);
        filterChain = registerMockFor(FilterChain.class);
        // put a parameter on request for use by WebRequestMatcher
        request.addParameter("Salutation", "Friends, Romans, Countrymen");

        filter = new OpenSessionInViewInterceptorFilter();
        MockFilterConfig filterConfig = new MockFilterConfig(servletContext);
        filter.init(filterConfig);
    }

    public void testBasicBehavior() throws Exception {
        interceptor.preHandle(webRequest());
        filterChain.doFilter(request, response);
        interceptor.postHandle(webRequest(), (ModelMap) isNull());
        interceptor.afterCompletion(webRequest(), (Exception) isNull());

        doFilter();
    }

    public void testExceptionInFilterChainBehavior() throws Exception {
        ServletException exception = new ServletException("Uh oh");

        interceptor.preHandle(webRequest());
        filterChain.doFilter(request, response);
        expectLastCall().andThrow(exception);
        // postHandle should not be called
        interceptor.afterCompletion(webRequest(), (Exception) isNull());

        try {
            doFilter();
            fail("Exception not propagated");
        } catch (ServletException se) {
            assertEquals(exception, se);
        }
    }

    public void testExceptionInPostHandleBehavior() throws Exception {
        DataAccessException exception = new PermissionDeniedDataAccessException("Uh oh", null);

        interceptor.preHandle(webRequest());
        filterChain.doFilter(request, response);
        interceptor.postHandle(webRequest(), (ModelMap) isNull());
        expectLastCall().andThrow(exception);
        interceptor.afterCompletion(webRequest(), (Exception) isNull());

        try {
            doFilter();
            fail("Exception not propagated");
        } catch (DataAccessException dae) {
            assertEquals(exception, dae);
        }
    }

    private void doFilter() throws IOException, ServletException {
        replayMocks();
        filter.doFilter(request, response, filterChain);
        verifyMocks();
    }

    private WebRequest webRequest() {
        reportMatcher(webRequestMatcher);
        return null;
    }

    private class WebRequestMatcher implements IArgumentMatcher {
        public boolean matches(Object argument) {
            if (!(argument instanceof ServletWebRequest)) return false;
            ServletWebRequest actual = (ServletWebRequest) argument;
            return actual.getParameterMap().equals(request.getParameterMap());
        }

        public void appendTo(StringBuffer buffer) {
            buffer.append("wraps ").append(request.toString());
        }
    }
}

@@ -52,39 +52,32 @@
 ar.web;%0A%0Aimport 
-static 
 org.easymock.cla
@@ -77,33 +77,24 @@
 ock.
-classextension.EasyMock.*
+IArgumentMatcher
 ;%0Aim
@@ -160,171 +160,170 @@
 org.
-easymock.classextension.EasyMock;%0Aimport org.easymock.ArgumentsMatcher;%0Aimport org.easymock.IArgumentMatcher;%0Aimport org.springframework.context.ApplicationContext
+springframework.context.ApplicationContext;%0Aimport org.springframework.dao.DataAccessException;%0Aimport org.springframework.dao.PermissionDeniedDataAccessException
 ;%0Aim
@@ -454,16 +454,56 @@
 ceptor;%0A
+import org.springframework.ui.ModelMap;%0A
 import o
@@ -560,67 +560,8 @@
 xt;%0A
-import org.springframework.web.context.request.WebRequest;%0A
 impo
@@ -653,139 +653,38 @@
 ork.
-dao.DataAccessException;%0Aimport org.springframework.dao.PermissionDeniedDataAccessException;%0Aimport org.springframework.ui.ModelMap
+web.context.request.WebRequest
 ;%0A%0Ai

Optimize imports (to remove deprecation warning)