/*
* Copyright (c) 2010. All rights reserved.
*/
package ro.isdc.wro.http;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static ro.isdc.wro.http.handler.ResourceProxyRequestHandler.PARAM_RESOURCE_ID;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Properties;
import java.util.concurrent.Callable;
import javax.management.MBeanServer;
import javax.management.ObjectName;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import ro.isdc.wro.WroRuntimeException;
import ro.isdc.wro.cache.CacheKey;
import ro.isdc.wro.cache.CacheStrategy;
import ro.isdc.wro.cache.CacheValue;
import ro.isdc.wro.config.Context;
import ro.isdc.wro.config.factory.FilterConfigWroConfigurationFactory;
import ro.isdc.wro.config.factory.PropertiesAndFilterConfigWroConfigurationFactory;
import ro.isdc.wro.config.factory.PropertyWroConfigurationFactory;
import ro.isdc.wro.config.jmx.ConfigConstants;
import ro.isdc.wro.config.jmx.WroConfiguration;
import ro.isdc.wro.http.handler.ReloadCacheRequestHandler;
import ro.isdc.wro.http.handler.ReloadModelRequestHandler;
import ro.isdc.wro.http.handler.RequestHandler;
import ro.isdc.wro.http.handler.ResourceProxyRequestHandler;
import ro.isdc.wro.http.handler.factory.RequestHandlerFactory;
import ro.isdc.wro.http.support.DelegatingServletOutputStream;
import ro.isdc.wro.http.support.UnauthorizedRequestException;
import ro.isdc.wro.manager.factory.BaseWroManagerFactory;
import ro.isdc.wro.manager.factory.ConfigurableWroManagerFactory;
import ro.isdc.wro.manager.factory.DefaultWroManagerFactory;
import ro.isdc.wro.manager.factory.WroManagerFactory;
import ro.isdc.wro.model.WroModel;
import ro.isdc.wro.model.factory.WroModelFactory;
import ro.isdc.wro.model.factory.XmlModelFactory;
import ro.isdc.wro.model.group.Group;
import ro.isdc.wro.model.group.InvalidGroupNameException;
import ro.isdc.wro.model.group.processor.Injector;
import ro.isdc.wro.model.group.processor.InjectorBuilder;
import ro.isdc.wro.model.resource.locator.UriLocator;
import ro.isdc.wro.model.resource.locator.factory.UriLocatorFactory;
import ro.isdc.wro.model.resource.locator.support.DispatcherStreamLocator;
import ro.isdc.wro.model.resource.processor.factory.ConfigurableProcessorsFactory;
import ro.isdc.wro.model.resource.processor.impl.css.CssMinProcessor;
import ro.isdc.wro.model.resource.support.ResourceAuthorizationManager;
import ro.isdc.wro.util.AbstractDecorator;
import ro.isdc.wro.util.ObjectFactory;
import ro.isdc.wro.util.WroTestUtils;
import ro.isdc.wro.util.WroUtil;
import ro.isdc.wro.util.io.NullOutputStream;
/**
* Test for {@link WroFilter} class.
*
* @author Alex Objelean
* @created Created on Jul 13, 2009
*/
public class TestWroFilter {
private WroFilter victim;
@Mock
private FilterConfig mockFilterConfig;
@Mock
private HttpServletRequest mockRequest;
@Mock
private HttpServletResponse mockResponse;
@Mock
private FilterChain mockFilterChain;
@Mock
private ServletContext mockServletContext;
@Mock
private WroManagerFactory mockManagerFactory;
@Mock
private ResourceAuthorizationManager mockAuthorizationManager;
@Mock
private UriLocatorFactory mockUriLocatorFactory;
@Mock
private MBeanServer mockMBeanServer;
@Mock
private UriLocator mockUriLocator;
@BeforeClass
public static void onBeforeClass() {
assertEquals(0, Context.countActive());
}
@AfterClass
public static void onAfterClass() {
assertEquals(0, Context.countActive());
}
@Before
public void setUp()
throws Exception {
Context.set(Context.standaloneContext());
MockitoAnnotations.initMocks(this);
when(mockUriLocatorFactory.getInstance(Mockito.anyString())).thenReturn(mockUriLocator);
when(mockUriLocator.locate(Mockito.anyString())).thenReturn(WroUtil.EMPTY_STREAM);
when(mockUriLocatorFactory.locate(Mockito.anyString())).thenReturn(WroUtil.EMPTY_STREAM);
when(mockRequest.getAttribute(Mockito.anyString())).thenReturn(null);
when(mockManagerFactory.create()).thenReturn(new BaseWroManagerFactory().create());
when(mockFilterConfig.getServletContext()).thenReturn(mockServletContext);
when(mockResponse.getOutputStream()).thenReturn(new DelegatingServletOutputStream(new NullOutputStream()));
victim = new WroFilter() {
@Override
protected void onException(final Exception e, final HttpServletResponse response, final FilterChain chain) {
throw WroRuntimeException.wrap(e);
}
@Override
protected MBeanServer getMBeanServer() {
return mockMBeanServer;
}
};
victim.setWroManagerFactory(mockManagerFactory);
}
private WroManagerFactory createValidManagerFactory() {
return new BaseWroManagerFactory().setModelFactory(createValidModelFactory());
}
private WroModelFactory createValidModelFactory() {
return new XmlModelFactory() {
@Override
protected InputStream getModelResourceAsStream() {
return TestWroFilter.class.getResourceAsStream("wro.xml");
}
};
}
private void initChainOnErrorFilter()
throws ServletException {
victim = new WroFilter();
victim.init(mockFilterConfig);
}
/**
* Set filter init params with proper values and check they are the same in {@link WroConfiguration} object.
*/
@Test(expected = WroRuntimeException.class)
public void testFilterInitParamsAreWrong()
throws Exception {
when(mockFilterConfig.getInitParameter(ConfigConstants.cacheUpdatePeriod.name())).thenReturn("InvalidNumber");
when(mockFilterConfig.getInitParameter(ConfigConstants.modelUpdatePeriod.name())).thenReturn("100");
victim.init(mockFilterConfig);
}
@Test(expected = WroRuntimeException.class)
public void cannotAcceptInvalidAppFactoryClassNameIsSet()
throws Exception {
victim = new WroFilter();
when(mockFilterConfig.getInitParameter(ConfigConstants.managerFactoryClassName.name())).thenReturn("Invalid value");
victim.init(mockFilterConfig);
}
@Test
public void shouldUseInitiallySetManagerEvenIfAnInvalidAppFactoryClassNameIsSet()
throws Exception {
when(mockFilterConfig.getInitParameter(ConfigConstants.managerFactoryClassName.name())).thenReturn("Invalid value");
victim.init(mockFilterConfig);
Assert.assertSame(mockManagerFactory, AbstractDecorator.getOriginalDecoratedObject(victim.getWroManagerFactory()));
}
/**
* Test that in DEPLOYMENT mode if {@link InvalidGroupNameException} is thrown, the response redirect to 404.
*/
@Test
public void testInvalidGroupNameExceptionThrownInDEPLOYMENTMode()
throws Exception {
testChainContinueWhenSpecificExceptionThrown(new InvalidGroupNameException(""));
}
/**
* Test that in DEPLOYMENT mode if {@link InvalidGroupNameException} is thrown, the response redirect to 404.
*/
@Test
public void testUnauthorizedRequestExceptionThrownInDEPLOYMENTMode()
throws Exception {
testChainContinueWhenSpecificExceptionThrown(new UnauthorizedRequestException(""));
}
/**
* Test that in DEPLOYMENT mode if specified exception is thrown, the response redirect to 404.
*/
public void testChainContinueWhenSpecificExceptionThrown(final Throwable e)
throws Exception {
initChainOnErrorFilter();
when(mockManagerFactory.create()).thenThrow(e);
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
verifyChainIsCalled(mockFilterChain);
}
@Test
public void testValidAppFactoryClassNameIsSet()
throws Exception {
when(mockFilterConfig.getInitParameter(ConfigConstants.managerFactoryClassName.name())).thenReturn(
BaseWroManagerFactory.class.getName());
victim.init(mockFilterConfig);
}
/**
* Test that when setting WwroManagerFactory via setter, even if wroConfiguration has a different
* {@link WroManagerFactory} configured, the first one instance is used.
*/
@Test
public void shouldUseCorrectWroManagerFactoryWhenOneIsSet()
throws Exception {
final Class<?> managerClass = TestWroManagerFactory.class;
victim.setWroManagerFactory(null);
when(mockFilterConfig.getInitParameter(ConfigConstants.managerFactoryClassName.name())).thenReturn(
managerClass.getName());
victim.init(mockFilterConfig);
final Class<?> actualClass = ((DefaultWroManagerFactory) AbstractDecorator.getOriginalDecoratedObject(victim.getWroManagerFactory())).getFactory().getClass();
assertSame(managerClass, actualClass);
}
public static class TestWroManagerFactory
extends BaseWroManagerFactory {
}
@Test
public void testJmxDisabled()
throws Exception {
when(mockFilterConfig.getInitParameter(ConfigConstants.jmxEnabled.name())).thenReturn("false");
victim.init(mockFilterConfig);
}
/**
* Set filter init params with proper values and check they are the same in {@link WroConfiguration} object.
*/
@Test
public void testFilterInitParamsAreSetProperly()
throws Exception {
setConfigurationMode(FilterConfigWroConfigurationFactory.PARAM_VALUE_DEPLOYMENT);
when(mockFilterConfig.getInitParameter(ConfigConstants.gzipResources.name())).thenReturn("false");
when(mockFilterConfig.getInitParameter(ConfigConstants.cacheUpdatePeriod.name())).thenReturn("10");
when(mockFilterConfig.getInitParameter(ConfigConstants.modelUpdatePeriod.name())).thenReturn("100");
victim.init(mockFilterConfig);
final WroConfiguration config = victim.getConfiguration();
assertEquals(false, config.isDebug());
assertEquals(false, config.isGzipEnabled());
assertEquals(10, config.getCacheUpdatePeriod());
assertEquals(100, config.getModelUpdatePeriod());
}
@Test
public void testValidHeaderParamIsSet()
throws Exception {
when(mockFilterConfig.getInitParameter(ConfigConstants.header.name())).thenReturn("ETag: 998989");
victim.init(mockFilterConfig);
}
@Test
public void testValidHeaderParamsAreSet()
throws Exception {
when(mockFilterConfig.getInitParameter(ConfigConstants.header.name())).thenReturn(
"ETag: 998989 | Expires: Thu, 15 Apr 2010 20:00:00 GMT");
victim.init(mockFilterConfig);
}
@Test(expected = WroRuntimeException.class)
public void testInvalidHeaderParamIsSet()
throws Exception {
// this test fails only when debug is turned off.
when(mockFilterConfig.getInitParameter(ConfigConstants.header.name())).thenReturn("ETag 998989 expires 1");
victim.init(mockFilterConfig);
}
/**
* Set filter init params with proper values and check they are the same in {@link WroConfiguration} object.
*/
@Test
public void testConfigurationInitParam()
throws Exception {
when(mockFilterConfig.getInitParameter(FilterConfigWroConfigurationFactory.PARAM_CONFIGURATION)).thenReturn(
"anyOtherString");
victim.init(mockFilterConfig);
assertEquals(true, victim.getConfiguration().isDebug());
}
@Test
public void testDisableCacheInitParamInDeploymentMode()
throws Exception {
when(mockFilterConfig.getInitParameter(FilterConfigWroConfigurationFactory.PARAM_CONFIGURATION)).thenReturn(
FilterConfigWroConfigurationFactory.PARAM_VALUE_DEPLOYMENT);
when(mockFilterConfig.getInitParameter(ConfigConstants.disableCache.name())).thenReturn("true");
victim.init(mockFilterConfig);
assertEquals(false, victim.getConfiguration().isDebug());
}
@Test
public void testDisableCacheInitParamInDevelopmentMode()
throws Exception {
when(mockFilterConfig.getInitParameter(ConfigConstants.disableCache.name())).thenReturn("true");
victim.init(mockFilterConfig);
assertEquals(true, victim.getConfiguration().isDebug());
}
/**
* Check what happens when the request cannot be processed and assure that the we proceed with chain.
*
* @throws Exception
*/
public void cannotProcessConfigResourceStream()
throws Exception {
when(mockRequest.getRequestURI()).thenReturn("");
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
verifyChainIsCalled(mockFilterChain);
}
/**
* Check if the chain call was performed.
*/
private void verifyChainIsCalled(final FilterChain chain)
throws IOException, ServletException {
verify(chain, Mockito.atLeastOnce()).doFilter(Mockito.any(HttpServletRequest.class),
Mockito.any(HttpServletResponse.class));
}
/**
* Check if the chain call was performed.
*/
private void verifyChainIsNotCalled(final FilterChain chain)
throws IOException, ServletException {
verify(chain, Mockito.never()).doFilter(Mockito.any(HttpServletRequest.class),
Mockito.any(HttpServletResponse.class));
}
@Test
public void cannotProcessInvalidUri()
throws Exception {
initChainOnErrorFilter();
requestGroupByUri("", mockFilterChain);
verifyChainIsCalled(mockFilterChain);
}
@Test
public void requestValidGroup()
throws Exception {
initChainOnErrorFilter();
requestGroupByUri("/folder/g1.css");
}
@Test
public void requestInvalidGroup()
throws Exception {
initChainOnErrorFilter();
requestGroupByUri("/folder/INVALID_GROUP.css", mockFilterChain);
verifyChainIsCalled(mockFilterChain);
}
@Test
public void cannotAccessUnauthorizedRequest()
throws Exception {
initVictimWithMockAuthManager();
final String resourcePath = "/g1.css";
final String requestUri = ResourceProxyRequestHandler.createProxyPath("", resourcePath);
when(mockAuthorizationManager.isAuthorized(resourcePath)).thenReturn(true);
requestGroupByUri(requestUri, new RequestBuilder(requestUri) {
@Override
protected HttpServletRequest newRequest() {
final HttpServletRequest request = super.newRequest();
when(request.getParameter(PARAM_RESOURCE_ID)).thenReturn(resourcePath);
when(request.getParameter(ResourceProxyRequestHandler.PATH_API)).thenReturn(ResourceProxyRequestHandler.PATH_RESOURCES);
return request;
}
}, mockFilterChain);
verifyChainIsNotCalled(mockFilterChain);
}
/**
* Creates the victim filter which usues mock {@link ResourceAuthorizationManager}.
*/
private void initVictimWithMockAuthManager() {
victim = new WroFilter() {
@Override
protected void onException(final Exception e, final HttpServletResponse response, final FilterChain chain) {
throw WroRuntimeException.wrap(e);
}
@Override
Injector getInjector() {
return new InjectorBuilder(
new BaseWroManagerFactory().setUriLocatorFactory(mockUriLocatorFactory).setResourceAuthorizationManager(
mockAuthorizationManager)).build();
}
};
}
@Test
public void requestUrlRewrittenResource()
throws Exception {
final String resourcePath = "classpath:ro/isdc/wro/http/2.css";
initVictimWithMockAuthManager();
when(mockAuthorizationManager.isAuthorized(resourcePath)).thenReturn(true);
final String requestUri = ResourceProxyRequestHandler.createProxyPath("", resourcePath);
requestGroupByUri(requestUri, new RequestBuilder(requestUri) {
@Override
protected HttpServletRequest newRequest() {
final HttpServletRequest request = super.newRequest();
when(request.getParameter(PARAM_RESOURCE_ID)).thenReturn(resourcePath);
when(request.getParameter(ResourceProxyRequestHandler.PATH_API)).thenReturn(ResourceProxyRequestHandler.PATH_RESOURCES);
return request;
}
});
}
private void requestGroupByUri(final String requestUri)
throws Exception {
requestGroupByUri(requestUri, new RequestBuilder(requestUri), mockFilterChain);
}
private void requestGroupByUri(final String requestUri, final FilterChain chain)
throws Exception {
requestGroupByUri(requestUri, new RequestBuilder(requestUri), chain);
}
@Test
public void testDoFilterInDEPLOYMENTMode()
throws Exception {
when(mockRequest.getRequestURI()).thenReturn("/g2.js");
victim.setWroManagerFactory(createValidManagerFactory());
setConfigurationMode(FilterConfigWroConfigurationFactory.PARAM_VALUE_DEPLOYMENT);
victim.init(mockFilterConfig);
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
}
/**
* Perform initialization and simulates a call to WroFilter with given requestUri.
*
* @param requestUri
*/
private void requestGroupByUri(final String requestUri, final RequestBuilder requestBuilder, final FilterChain chain)
throws Exception {
victim.init(mockFilterConfig);
doFilter(requestUri, requestBuilder, chain);
}
private void doFilter(final String requestUri, final RequestBuilder requestBuilder, final FilterChain chain)
throws Exception {
final HttpServletRequest request = requestBuilder.newRequest();
final ServletOutputStream sos = mock(ServletOutputStream.class);
final HttpServletResponse mockResponse = mock(HttpServletResponse.class);
when(mockResponse.getOutputStream()).thenReturn(sos);
victim.doFilter(request, mockResponse, chain);
}
private void requestGroupByUri(final String requestUri, final RequestBuilder requestBuilder)
throws Exception {
requestGroupByUri(requestUri, requestBuilder, mockFilterChain);
}
/**
* Tests that in DEPLOYMENT mode the API is not exposed.
*/
@Test
public void testApiCallInDEPLOYMENTMode()
throws Exception {
initChainOnErrorFilter();
when(mockRequest.getRequestURI()).thenReturn(ReloadCacheRequestHandler.PATH_API + "/someMethod");
setConfigurationMode(FilterConfigWroConfigurationFactory.PARAM_VALUE_DEPLOYMENT);
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
// No api method exposed -> proceed with chain
verifyChainIsCalled(mockFilterChain);
}
/**
* Tests that in DEPLOYMENT mode the API is not exposed.
*/
@Test
public void testApiCallInDEVELOPMENTModeAndInvalidApiCall()
throws Exception {
initChainOnErrorFilter();
when(mockRequest.getRequestURI()).thenReturn(ReloadCacheRequestHandler.PATH_API + "/someMethod");
// by default configuration is development
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
// No api method exposed -> proceed with chain
verifyChainIsCalled(mockFilterChain);
}
/**
* Tests that in DEVELOPMENT mode the API is exposed.
*/
@Test
public void testApiCallInDEVELOPMENTModeAndReloadCacheCall()
throws Exception {
when(mockRequest.getRequestURI()).thenReturn(ReloadCacheRequestHandler.ENDPOINT_URI);
when(mockResponse.getWriter()).thenReturn(new PrintWriter(System.out));
final CacheStrategy<CacheKey, CacheValue> mockCacheStrategy = mock(CacheStrategy.class);
final WroManagerFactory managerFactory = new BaseWroManagerFactory().setCacheStrategy(mockCacheStrategy);
victim.setWroManagerFactory(managerFactory);
// by default configuration is development
victim.init(mockFilterConfig);
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
// api method exposed -> chain is not called
verifyChainIsNotCalled(mockFilterChain);
verify(mockCacheStrategy).clear();
}
/**
* Tests that in DEPLOYMENT mode the API is NOT exposed.
*/
@Test
public void apiCallInDeploymentMode()
throws Exception {
final Properties props = new Properties();
// init WroConfig properties
props.setProperty(ConfigConstants.debug.name(), Boolean.FALSE.toString());
final WroFilter theFilter = new WroFilter() {
@Override
protected ObjectFactory<WroConfiguration> newWroConfigurationFactory(final FilterConfig filterConfig) {
final PropertyWroConfigurationFactory factory = new PropertyWroConfigurationFactory(props);
return factory;
}
};
// initFilterWithValidConfig(theFilter);
final HttpServletRequest request = mock(HttpServletRequest.class, Mockito.RETURNS_DEEP_STUBS);
when(request.getRequestURI()).thenReturn(ReloadCacheRequestHandler.ENDPOINT_URI);
final HttpServletResponse response = mock(HttpServletResponse.class);
when(response.getWriter()).thenReturn(new PrintWriter(System.out));
// by default configuration is development
theFilter.init(mockFilterConfig);
theFilter.doFilter(request, response, mockFilterChain);
// No api method exposed -> proceed with chain
verifyChainIsCalled(mockFilterChain);
}
/**
* Proves that the model reload has effect.
*/
@Test
public void modelShouldBeReloadedWhenReloadIsTriggered()
throws Exception {
final WroManagerFactory wroManagerFactory = new BaseWroManagerFactory().setModelFactory(new WroModelFactory() {
private boolean wasCreated = false;
public WroModel create() {
if (!wasCreated) {
wasCreated = true;
// return model with no groups defined
return new WroModel();
}
// second time when created add one group
return new WroModel().addGroup(new Group("g1"));
}
public void destroy() {
}
});
final WroFilter filter = new WroFilter() {
@Override
protected WroManagerFactory newWroManagerFactory() {
return wroManagerFactory;
}
@Override
protected ObjectFactory<WroConfiguration> newWroConfigurationFactory(final FilterConfig filterConfig) {
return new ObjectFactory<WroConfiguration>() {
public WroConfiguration create() {
return Context.get().getConfig();
}
};
}
};
filter.init(mockFilterConfig);
final WroModelFactory modelFactory = wroManagerFactory.create().getModelFactory();
assertTrue(modelFactory.create().getGroups().isEmpty());
// reload model
Context.get().getConfig().reloadModel();
// the second time should have one group
assertEquals(1, modelFactory.create().getGroups().size());
}
@Test
public void testReloadCacheCall()
throws Exception {
when(mockRequest.getRequestURI()).thenReturn(ReloadCacheRequestHandler.ENDPOINT_URI);
final ThreadLocal<Integer> status = new ThreadLocal<Integer>();
final HttpServletResponse response = new HttpServletResponseWrapper(mockResponse) {
@Override
public void setStatus(final int sc) {
status.set(sc);
}
};
Context.unset();
Context.set(Context.webContext(mockRequest, response, mockFilterConfig));
victim.init(mockFilterConfig);
victim.doFilter(Context.get().getRequest(), Context.get().getResponse(), mockFilterChain);
assertEquals(Integer.valueOf(HttpServletResponse.SC_OK), status.get());
}
@Test
public void testReloadModelCall()
throws Exception {
when(mockRequest.getRequestURI()).thenReturn(ReloadModelRequestHandler.ENDPOINT_URI);
final ThreadLocal<Integer> status = new ThreadLocal<Integer>();
final HttpServletResponse response = new HttpServletResponseWrapper(mockResponse) {
@Override
public void setStatus(final int sc) {
status.set(sc);
}
};
Context.unset();
Context.set(Context.webContext(mockRequest, response, mockFilterConfig));
victim.init(mockFilterConfig);
victim.doFilter(Context.get().getRequest(), Context.get().getResponse(), mockFilterChain);
assertEquals(Integer.valueOf(HttpServletResponse.SC_OK), status.get());
}
/**
* Mocks the WroFilter.PARAM_CONFIGURATION init param with passed value.
*/
private void setConfigurationMode(final String value) {
when(mockFilterConfig.getInitParameter(FilterConfigWroConfigurationFactory.PARAM_CONFIGURATION)).thenReturn(value);
}
class RequestBuilder {
private final String requestUri;
public RequestBuilder(final String requestUri) {
this.requestUri = requestUri;
}
protected HttpServletRequest newRequest() {
final HttpServletRequest mockRequest = mock(HttpServletRequest.class);
when(mockRequest.getRequestURI()).thenReturn(requestUri);
return mockRequest;
}
}
/**
* Should throw {@link NullPointerException} when provided requestHandler's collection is null.
*/
@Test(expected = NullPointerException.class)
public void shouldNotAcceptNullRequestHandlers()
throws Throwable {
victim.setRequestHandlerFactory(new RequestHandlerFactory() {
public Collection<RequestHandler> create() {
return null;
}
});
try {
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
} catch (final WroRuntimeException e) {
throw e.getCause();
}
}
@Test(expected = NullPointerException.class)
public void cannotAcceptNullRequestHandlerFactory() {
victim.setRequestHandlerFactory(null);
}
@Test(expected = UnauthorizedRequestException.class)
public void testProxyUnauthorizedRequest()
throws Exception {
processProxyWithResourceId("test");
}
private void processProxyWithResourceId(final String resourceId)
throws Exception {
when(mockRequest.getParameter(PARAM_RESOURCE_ID)).thenReturn(resourceId);
when(mockRequest.getParameter(ResourceProxyRequestHandler.PATH_API)).thenReturn(ResourceProxyRequestHandler.PATH_RESOURCES);
when(mockRequest.getRequestURI()).thenReturn(ResourceProxyRequestHandler.createProxyPath("", resourceId));
final WroConfiguration config = new WroConfiguration();
// we don't need caching here, otherwise we'll have clashing during unit tests.
Context.unset();
Context.set(Context.webContext(mockRequest, mockResponse, mockFilterConfig), newConfigWithUpdatePeriodValue(0));
victim.init(mockFilterConfig);
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
}
/**
* Initialize {@link WroConfiguration} object with cacheUpdatePeriod & modelUpdatePeriod equal with provided argument.
*/
private WroConfiguration newConfigWithUpdatePeriodValue(final long periodValue) {
final WroConfiguration config = new WroConfiguration();
config.setCacheUpdatePeriod(periodValue);
config.setModelUpdatePeriod(periodValue);
return config;
}
private void prepareValidRequest(final WroConfiguration config)
throws ServletException {
when(mockRequest.getRequestURI()).thenReturn("/resource/g1.css");
Context.unset();
Context.set(Context.webContext(mockRequest, mockResponse, mockFilterConfig));
victim.setConfiguration(config);
victim.setWroManagerFactory(createValidManagerFactory());
victim.init(mockFilterConfig);
}
@Test
public void shouldNotDestroyWroModelWhenCacheIsNotDisabled()
throws Exception {
final WroConfiguration config = new WroConfiguration();
prepareValidRequest(config);
final WroModelFactory mockModelFactory = Mockito.spy(createValidModelFactory());
victim.setWroManagerFactory(new BaseWroManagerFactory().setModelFactory(mockModelFactory));
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
verify(mockModelFactory, Mockito.never()).destroy();
}
@Test(expected = NullPointerException.class)
public void cannotSetNullConfiguration() {
victim.setConfiguration(null);
}
@Test(expected = IllegalStateException.class)
public void shouldFailWhenConfigurationFactoryFails()
throws Exception {
victim = new WroFilter() {
@Override
protected ObjectFactory<WroConfiguration> newWroConfigurationFactory(final FilterConfig filterConfig) {
throw new IllegalStateException("BOOM!");
}
};
victim.init(mockFilterConfig);
}
@Test
public void shouldChainTheIncludedRequestByDispatcher()
throws Exception {
when(mockRequest.getAttribute(DispatcherStreamLocator.ATTRIBUTE_INCLUDED_BY_DISPATCHER)).thenReturn(Boolean.TRUE);
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
verify(mockManagerFactory, Mockito.never()).create();
verifyChainIsCalled(mockFilterChain);
}
@Test
public void shouldChainWhenFilterIsNotEnabled()
throws Exception {
victim.setEnable(false);
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
verifyChainIsCalled(mockFilterChain);
}
@Test
public void shouldNotChainWhenFilterIsEnabled()
throws Exception {
prepareValidRequest(new WroConfiguration());
victim.setEnable(true);
victim.doFilter(mockRequest, mockResponse, mockFilterChain);
verifyChainIsNotCalled(mockFilterChain);
}
@Test
public void shouldUnregisterMBeanOnDestroy()
throws Exception {
when(mockMBeanServer.isRegistered(Mockito.any(ObjectName.class))).thenReturn(true);
victim.init(mockFilterConfig);
victim.destroy();
verify(mockMBeanServer).unregisterMBean(Mockito.any(ObjectName.class));
}
@Test
public void shouldUseProcessorsConfiguredInWroProperties()
throws Exception {
final ObjectFactory<WroConfiguration> configurationFactory = new PropertiesAndFilterConfigWroConfigurationFactory(
mockFilterConfig) {
@Override
public Properties createProperties() {
final Properties props = new Properties();
props.setProperty(ConfigConstants.managerFactoryClassName.name(), ConfigurableWroManagerFactory.class.getName());
props.setProperty(ConfigurableProcessorsFactory.PARAM_PRE_PROCESSORS, CssMinProcessor.ALIAS);
return props;
}
};
victim.setWroConfigurationFactory(configurationFactory);
victim.setWroManagerFactory(null);
victim.init(mockFilterConfig);
Context.unset();
Context.set(Context.webContext(mockRequest, mockResponse, mockFilterConfig), configurationFactory.create());
final WroManagerFactory factory = victim.getWroManagerFactory();
assertEquals(1, factory.create().getProcessorsFactory().getPreProcessors().size());
}
@Test
public void shouldNotFailWhenInvokedConcurrently() throws Exception {
final String requestUri = "/folder/g1.css";
//Unset it to allow tested filter to set its own context.
Context.unset();
victim.setWroManagerFactory(createValidManagerFactory());
victim.init(mockFilterConfig);
WroTestUtils.runConcurrently(new Callable<Void>() {
public Void call()
throws Exception {
doFilter(requestUri, new RequestBuilder(requestUri), mockFilterChain);
return null;
}
});
}
@After
public void tearDown() {
if (victim != null) {
victim.destroy();
}
Context.unset();
}
}