/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * 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.alibaba.citrus.webx.servlet; import static com.alibaba.citrus.test.TestEnvStatic.*; import static com.alibaba.citrus.test.TestUtil.*; import static com.alibaba.citrus.util.ServletUtil.*; import static org.easymock.EasyMock.*; import static org.junit.Assert.*; import java.io.File; import java.util.Map; import javax.servlet.FilterChain; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.alibaba.citrus.service.requestcontext.RequestContext; import com.alibaba.citrus.util.CollectionUtil; import com.alibaba.citrus.webx.AbstractWebxTests; import com.alibaba.citrus.webx.WebxComponent; import com.alibaba.citrus.webx.WebxComponents; import com.alibaba.citrus.webx.config.WebxConfiguration; import com.alibaba.citrus.webx.support.AbstractWebxController; import com.alibaba.citrus.webx.util.RequestURIFilter; import com.alibaba.citrus.webx.util.WebxUtil; import com.meterware.servletunit.PatchedServletRunner; import org.junit.Before; import org.junit.Test; import org.springframework.beans.BeansException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.context.WebApplicationContext; public class WebxFrameworkFilterTests extends AbstractWebxTests { private WebxFrameworkFilter filter; private WebxComponents components; @Before public void init() throws Exception { MyController.resetAttributes(); prepareWebClient(null, "/myapps"); filter = (WebxFrameworkFilter) client.newInvocation("http://www.taobao.com/myapps/app1").getFilter(); assertNotNull(filter); components = filter.getWebxComponents(); assertNotNull(components); } @Test public void isExcluded() throws Exception { filter.setExcludes("/aa , *.jpg"); assertExcluded(true, "/aa/bb"); assertExcluded(false, "/cc/aa/bb"); assertExcluded(true, "/cc/test.jpg"); assertExcluded(true, "/cc/aa/bb/test.jpg"); assertExcluded(false, "/cc/aa/bb/test.htm"); // 对于internal路径,虽然匹配excludes但也不排除 assertExcluded(true, "/internal/test.jpg", true); } private void assertExcluded(boolean excluded, String requestURI) throws Exception { assertExcluded(excluded, requestURI, false); } private void assertExcluded(boolean excluded, String requestURI, boolean internal) throws Exception { RequestURIFilter excludes = getFieldValue(filter, "excludeFilter", RequestURIFilter.class); HttpServletRequest request = createMock(HttpServletRequest.class); HttpServletResponse response = createMock(HttpServletResponse.class); FilterChain filterChain = createMock(FilterChain.class); // 不会调用getContextPath和getRequestURI expect(request.getServletPath()).andReturn(requestURI).anyTimes(); expect(request.getPathInfo()).andReturn(null).anyTimes(); if (excluded && !internal) { filterChain.doFilter(request, response); } replay(request, response, filterChain); if (internal) { assertFalse(filter.isExcluded(getResourcePath(request))); } else { assertEquals(excluded, excludes.matches(requestURI)); } if (excluded && !internal) { filter.doFilter(request, response, filterChain); // 对excluded request调用doFilter,应该立即返回 assertTrue(filter.isExcluded(getResourcePath(request))); } verify(request, response, filterChain); } @Test public void componentPath_wrong() throws Exception { File webInf = new File(srcdir, "app2/WEB-INF"); File webXml = new File(webInf, "web.xml"); try { new PatchedServletRunner(webXml, ""); fail(); } catch (IllegalArgumentException e) { assertThat(e, exception("default component \"app1\" should not have component path \"/my/app1\"")); } } @Test public void getComponent() throws Exception { assertNull(components.getComponent("notexist")); // root component WebxComponent rootComponent = components.getComponent(null); assertNull(rootComponent.getName()); assertEquals("", rootComponent.getComponentPath()); assertSame(components.getParentWebxConfiguration(), rootComponent.getWebxConfiguration()); assertSame(components.getParentApplicationContext(), rootComponent.getApplicationContext()); assertSame(components, rootComponent.getWebxComponents()); assertEquals(components.toString(), rootComponent.toString()); try { rootComponent.getWebxController(); fail(); } catch (UnsupportedOperationException e) { assertThat(e, exception("RootComponent.getWebxController()")); } } @Test public void findComponent() throws Exception { WebxComponent app1 = components.getComponent("app1"); WebxComponent app4 = components.getComponent("app4"); WebxComponent app5 = components.getComponent("app5"); assertEquals("/app1", app1.getComponentPath()); assertEquals("", app4.getComponentPath()); assertEquals("/my/app5", app5.getComponentPath()); assertSame(app1, components.findMatchedComponent("app1")); assertSame(app1, components.findMatchedComponent("app1/")); assertSame(app1, components.findMatchedComponent("/app1")); assertSame(app1, components.findMatchedComponent("/app1/test")); // default assertSame(app4, components.findMatchedComponent("/app1_test")); // specified component path assertSame(app4, components.findMatchedComponent("/app5")); assertSame(app5, components.findMatchedComponent("/my/app5")); assertSame(app5, components.findMatchedComponent("/my/app5/test")); } @Test public void readResource_app4_defaultComponent() throws Exception { invokeServlet("/myapps/plaintext.txt"); assertEquals(200, clientResponseCode); assertThat(clientResponseContent, containsAll("hello, app4")); assertEquals("yes", MyController.getAttribute("onRefresh")); assertEquals("yes", MyController.getAttribute("postProcessWebApplicationContext")); assertEquals(components.getComponent("app4"), MyController.getAttribute("handleRequest")); } @Test public void readResource_app5() throws Exception { invokeServlet("/myapps/my/app5/plaintext.txt"); assertEquals(200, clientResponseCode); assertThat(clientResponseContent, containsAll("hello, app5")); assertEquals("yes", MyController.getAttribute("onRefresh")); assertEquals("yes", MyController.getAttribute("postProcessWebApplicationContext")); assertEquals(components.getComponent("app5"), MyController.getAttribute("handleRequest")); } @Test public void autowireComponentObject() { ComponentsAware componentsAware; // parent context componentsAware = getComponentsAware(components.getParentApplicationContext()); assertSame(components, componentsAware.components); assertNull(componentsAware.component); // component context componentsAware = getComponentsAware(components.getComponent("app1").getApplicationContext()); assertSame(components, componentsAware.components); assertSame(components.getComponent("app1"), componentsAware.component); componentsAware = getComponentsAware(components.getComponent("app2").getApplicationContext()); assertSame(components, componentsAware.components); assertSame(components.getComponent("app2"), componentsAware.component); componentsAware = getComponentsAware(components.getComponent("app3").getApplicationContext()); assertSame(components, componentsAware.components); assertSame(components.getComponent("app3"), componentsAware.component); componentsAware = getComponentsAware(components.getComponent("app4").getApplicationContext()); assertSame(components, componentsAware.components); assertSame(components.getComponent("app4"), componentsAware.component); componentsAware = getComponentsAware(components.getComponent("app5").getApplicationContext()); assertSame(components, componentsAware.components); assertSame(components.getComponent("app5"), componentsAware.component); } @Test public void getConfiguration_fromComponent() { // parent configuration WebxConfiguration parentConfiguration = (WebxConfiguration) components.getParentApplicationContext().getBean( "webxConfiguration"); assertNotNull(parentConfiguration); // component's configureation WebxConfiguration configuration = components.getComponent("app1").getWebxConfiguration(); assertNotSame(parentConfiguration, configuration); assertSame(parentConfiguration, getFieldValue(configuration, "parent", WebxConfiguration.class)); } @Test public void autowireController() { MyController controller = (MyController) components.getComponent("app4").getWebxController(); // get component assertEquals("app4", controller.getComponent().getName()); // get others assertEquals(controller.getComponent(), controller.componentsAware.component); } private ComponentsAware getComponentsAware(WebApplicationContext context) { return (ComponentsAware) context.getBean("componentsAware"); } public static class ComponentsAware { @Autowired(required = false) private WebxComponent component; @Autowired private WebxComponents components; } public static class MyController extends AbstractWebxController { private static ThreadLocal<Map<String, Object>> log = new ThreadLocal<Map<String, Object>>(); @Autowired private ComponentsAware componentsAware; public static void resetAttributes() { log.set(CollectionUtil.<String, Object>createHashMap()); } public static Object getAttribute(String key) { return log.get().get(key); } public static void setAttribute(String key, Object value) { Map<String, Object> attrs = log.get(); if (attrs != null) { attrs.put(key, value); } } @Override public void onRefreshContext() throws BeansException { super.onRefreshContext(); setAttribute("onRefresh", "yes"); } @Override public void onFinishedProcessContext() { super.onFinishedProcessContext(); setAttribute("postProcessWebApplicationContext", "yes"); } public boolean service(RequestContext requestContext) throws Exception { setAttribute("handleRequest", getComponent()); // 测试component是否被置入request attrs assertSame(getComponent(), WebxUtil.getCurrentComponent(requestContext.getRequest())); return false; } } }