http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/I18nInterceptorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/I18nInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/I18nInterceptorTest.java new file mode 100644 index 0000000..5979e58 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/I18nInterceptorTest.java @@ -0,0 +1,207 @@ +/* + * Copyright 2002-2006,2009 The Apache Software Foundation. + * + * 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.opensymphony.xwork2.interceptor; + +import com.opensymphony.xwork2.Action; +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.SimpleFooAction; +import com.opensymphony.xwork2.mock.MockActionInvocation; +import junit.framework.TestCase; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +/** + * Unit test for I18nInterceptor. + * + * @author Claus Ibsen + */ +public class I18nInterceptorTest extends TestCase { + + private I18nInterceptor interceptor; + private ActionContext ac; + private Map<String, Serializable> params; + private Map session; + private ActionInvocation mai; + + public void testEmptyParamAndSession() throws Exception { + interceptor.intercept(mai); + } + + public void testNoSession() throws Exception { + ac.setSession(null); + interceptor.intercept(mai); + } + + public void testDefaultLocale() throws Exception { + params.put(I18nInterceptor.DEFAULT_PARAMETER, "_"); // bad locale that would get us default locale instead + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + + assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here + assertEquals(Locale.getDefault(), session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a locale object + } + + public void testDenmarkLocale() throws Exception { + params.put(I18nInterceptor.DEFAULT_PARAMETER, "da_DK"); + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + + Locale denmark = new Locale("da", "DK"); + assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here + assertEquals(denmark, session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a locale object + } + + public void testDenmarkLocaleRequestOnly() throws Exception { + params.put(I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER, "da_DK"); + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + + Locale denmark = new Locale("da", "DK"); + assertNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here + assertEquals(denmark, mai.getInvocationContext().getLocale()); // should create a locale object + } + + public void testCountryOnlyLocale() throws Exception { + params.put(I18nInterceptor.DEFAULT_PARAMETER, "DK"); + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + + Locale denmark = new Locale("DK"); + assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here + assertEquals(denmark, session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a locale object + } + + public void testLanguageOnlyLocale() throws Exception { + params.put(I18nInterceptor.DEFAULT_PARAMETER, "da_"); + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + + Locale denmark = new Locale("da"); + assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here + assertEquals(denmark, session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a locale object + } + + public void testWithVariant() throws Exception { + params.put(I18nInterceptor.DEFAULT_PARAMETER, "fr_CA_xx"); + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + + Locale variant = new Locale("fr", "CA", "xx"); + Locale locale = (Locale) session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE); + assertNotNull(locale); // should be stored here + assertEquals(variant, locale); + assertEquals("xx", locale.getVariant()); + } + + public void testWithVariantRequestOnly() throws Exception { + params.put(I18nInterceptor.DEFAULT_REQUESTONLY_PARAMETER, "fr_CA_xx"); + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + assertNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); + + Locale variant = new Locale("fr", "CA", "xx"); + Locale locale = mai.getInvocationContext().getLocale(); + assertNotNull(locale); // should be stored here + assertEquals(variant, locale); + assertEquals("xx", locale.getVariant()); + } + + public void testRealLocaleObjectInParams() throws Exception { + params.put(I18nInterceptor.DEFAULT_PARAMETER, Locale.CANADA_FRENCH); + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + + assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here + assertEquals(Locale.CANADA_FRENCH, session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should create a locale object + } + + public void testRealLocalesInParams() throws Exception { + Locale[] locales = new Locale[] { Locale.CANADA_FRENCH }; + assertTrue(locales.getClass().isArray()); + params.put(I18nInterceptor.DEFAULT_PARAMETER, locales); + interceptor.intercept(mai); + + assertNull(params.get(I18nInterceptor.DEFAULT_PARAMETER)); // should have been removed + + assertNotNull(session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); // should be stored here + assertEquals(Locale.CANADA_FRENCH, session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE)); + } + + public void testSetParameterAndAttributeNames() throws Exception { + interceptor.setAttributeName("hello"); + interceptor.setParameterName("world"); + + params.put("world", Locale.CHINA); + interceptor.intercept(mai); + + assertNull(params.get("world")); // should have been removed + + assertNotNull(session.get("hello")); // should be stored here + assertEquals(Locale.CHINA, session.get("hello")); + } + + public void testActionContextLocaleIsPreservedWhenNotOverridden() throws Exception { + final Locale locale1 = Locale.TRADITIONAL_CHINESE; + mai.getInvocationContext().setLocale(locale1); + interceptor.intercept(mai); + + Locale locale = (Locale) session.get(I18nInterceptor.DEFAULT_SESSION_ATTRIBUTE); + assertNull(locale); // should not be stored here + locale = mai.getInvocationContext().getLocale(); + assertEquals(locale1, locale); + } + + @Override + protected void setUp() throws Exception { + interceptor = new I18nInterceptor(); + interceptor.init(); + params = new HashMap<>(); + session = new HashMap(); + + Map<String, Object> ctx = new HashMap<>(); + ctx.put(ActionContext.PARAMETERS, params); + ctx.put(ActionContext.SESSION, session); + ac = new ActionContext(ctx); + + Action action = new SimpleFooAction(); + mai = new MockActionInvocation(); + ((MockActionInvocation) mai).setAction(action); + ((MockActionInvocation) mai).setInvocationContext(ac); + } + + @Override + protected void tearDown() throws Exception { + interceptor.destroy(); + interceptor = null; + ac = null; + params = null; + session = null; + mai = null; + } + +}
http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtilTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtilTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtilTest.java new file mode 100644 index 0000000..6598050 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/MethodFilterInterceptorUtilTest.java @@ -0,0 +1,83 @@ +/* + * Copyright 2002-2009 The Apache Software Foundation. + * + * 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.opensymphony.xwork2.interceptor; + +import com.opensymphony.xwork2.XWorkTestCase; + +import java.util.HashSet; + +public class MethodFilterInterceptorUtilTest extends XWorkTestCase { + + public void testApplyMethodNoWildcards() { + + HashSet<String> included = new HashSet<>(); + included.add("included"); + included.add("includedAgain"); + + HashSet<String> excluded = new HashSet<>(); + excluded.add("excluded"); + excluded.add("excludedAgain"); + + // test expected behavior + assertFalse(MethodFilterInterceptorUtil.applyMethod(excluded, included, "excluded")); + assertTrue(MethodFilterInterceptorUtil.applyMethod(excluded, included, "included")); + + // test precedence + included.add("excluded"); + assertTrue(MethodFilterInterceptorUtil.applyMethod(excluded, included, "excluded")); + + } + + public void testApplyMethodWithWildcards() { + + HashSet<String> included = new HashSet<>(); + included.add("included*"); + + HashSet<String> excluded = new HashSet<>(); + excluded.add("excluded*"); + + assertTrue(MethodFilterInterceptorUtil.applyMethod(excluded, included, "includedMethod")); + assertFalse(MethodFilterInterceptorUtil.applyMethod(excluded, included, "excludedMethod")); + + // test precedence + included.clear(); + excluded.clear(); + included.add("wildIncluded"); + excluded.add("wild*"); + + assertTrue(MethodFilterInterceptorUtil.applyMethod(excluded, included, "wildIncluded")); + assertFalse(MethodFilterInterceptorUtil.applyMethod(excluded, included, "wildNotIncluded")); + + // test precedence + included.clear(); + excluded.clear(); + included.add("*"); + excluded.add("excluded"); + + assertTrue(MethodFilterInterceptorUtil.applyMethod(excluded, included, "anyMethod")); + + // test precedence + included.clear(); + excluded.clear(); + included.add("included"); + excluded.add("*"); + + assertTrue(MethodFilterInterceptorUtil.applyMethod(excluded, included, "included")); + assertFalse(MethodFilterInterceptorUtil.applyMethod(excluded, included, "shouldBeExcluded")); + + } + +} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java new file mode 100644 index 0000000..701d020 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ModelDrivenInterceptorTest.java @@ -0,0 +1,112 @@ +/* + * Copyright 2002-2003,2009 The Apache Software Foundation. + * + * 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.opensymphony.xwork2.interceptor; + +import com.mockobjects.dynamic.ConstraintMatcher; +import com.mockobjects.dynamic.Mock; +import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.util.ValueStack; + +import java.util.Date; + + +/** + * @author $Author$ + * @version $Revision$ + */ +public class ModelDrivenInterceptorTest extends XWorkTestCase { + + Action action; + Mock mockActionInvocation; + ModelDrivenInterceptor modelDrivenInterceptor; + Object model; + PreResultListener preResultListener; + + + public void testModelDrivenGetsPushedOntoStack() throws Exception { + ValueStack stack = ActionContext.getContext().getValueStack(); + action = new ModelDrivenAction(); + mockActionInvocation.expectAndReturn("getAction", action); + mockActionInvocation.expectAndReturn("getStack", stack); + mockActionInvocation.expectAndReturn("invoke", "foo"); + + modelDrivenInterceptor.intercept((ActionInvocation) mockActionInvocation.proxy()); + + Object topOfStack = stack.pop(); + assertEquals("our model should be on the top of the stack", model, topOfStack); + } + + public void testModelDrivenUpdatedAndGetsPushedOntoStack() throws Exception { + ValueStack stack = ActionContext.getContext().getValueStack(); + action = new ModelDrivenAction(); + mockActionInvocation.expectAndReturn("getAction", action); + mockActionInvocation.matchAndReturn("getStack", stack); + mockActionInvocation.expectAndReturn("invoke", "foo"); + mockActionInvocation.expect("addPreResultListener", new ConstraintMatcher() { + + public boolean matches(Object[] objects) { + preResultListener = (PreResultListener) objects[0]; + return true; + } + + public Object[] getConstraints() { + return new Object[0]; //To change body of implemented methods use File | Settings | File Templates. + } + }); + modelDrivenInterceptor.setRefreshModelBeforeResult(true); + + modelDrivenInterceptor.intercept((ActionInvocation) mockActionInvocation.proxy()); + assertNotNull(preResultListener); + model = "this is my model"; + preResultListener.beforeResult((ActionInvocation) mockActionInvocation.proxy(), "success"); + + Object topOfStack = stack.pop(); + assertEquals("our model should be on the top of the stack", model, topOfStack); + assertEquals(1, stack.getRoot().size()); + } + + public void testStackNotModifedForNormalAction() throws Exception { + action = new ActionSupport(); + mockActionInvocation.expectAndReturn("getAction", action); + mockActionInvocation.expectAndReturn("invoke", "foo"); + + // nothing should happen + modelDrivenInterceptor.intercept((ActionInvocation) mockActionInvocation.proxy()); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mockActionInvocation = new Mock(ActionInvocation.class); + modelDrivenInterceptor = new ModelDrivenInterceptor(); + model = new Date(); // any object will do + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + mockActionInvocation.verify(); + } + + + public class ModelDrivenAction extends ActionSupport implements ModelDriven { + + public Object getModel() { + return model; + } + + } +} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java new file mode 100644 index 0000000..b57cb22 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterFilterInterceptorTest.java @@ -0,0 +1,125 @@ +/* + * Copyright 2002-2006,2009 The Apache Software Foundation. + * + * 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.opensymphony.xwork2.interceptor; + +import com.mockobjects.dynamic.Mock; +import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.util.ValueStack; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; + +/** + * Unit test for {@link ParameterFilterInterceptor}. + * + * @author Gabe + */ +public class ParameterFilterInterceptorTest extends XWorkTestCase { + + ActionInvocation invocation; + ParameterFilterInterceptor interceptor; + Mock mockInvocation; + ValueStack stack; + Map<String, Object> contextMap; + + @Override + protected void setUp() throws Exception { + super.setUp(); + contextMap = new HashMap<>(); + stack = ActionContext.getContext().getValueStack(); + mockInvocation = new Mock(ActionInvocation.class); + mockInvocation.expectAndReturn("getStack", stack); + mockInvocation.expectAndReturn("invoke", Action.SUCCESS); + mockInvocation.expectAndReturn("getInvocationContext", new ActionContext(contextMap)); + mockInvocation.matchAndReturn("getAction", new SimpleAction()); + invocation = (ActionInvocation) mockInvocation.proxy(); + interceptor = new ParameterFilterInterceptor(); + interceptor.init(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + interceptor.destroy(); + } + + public void testBasicBlockAll() throws Exception { + runFilterTest(null,null,true,new String[] {"blah", "bladeblah", "bladebladeblah"}); + assertEquals(0, getParameterNames().size()); + } + + public void testBasicAllowed() throws Exception { + runFilterTest("blah",null,true,new String[] {"blah"}); + assertEquals(1, getParameterNames().size()); + } + + public void testBasicBlocked() throws Exception { + runFilterTest(null,"blah",false,new String[] {"blah"}); + assertEquals(0, getParameterNames().size()); + } + public void testAllSubpropertiesBlocked() throws Exception { + runFilterTest(null,"blah",false,new String[] {"blah.deblah", "blah.somethingelse", "blah(22)"}); + assertEquals(0, getParameterNames().size()); + } + + public void testAllSubpropertiesAllowed() throws Exception { + runFilterTest("blah",null,true, + new String[] {"blah.deblah", "blah.somethingelse", "blah(22)"}); + assertEquals(3, getParameterNames().size()); + } + + public void testTreeBlocking() throws Exception { + runFilterTest("blah.deblah","blah,blah.deblah.deblah",false, + new String[] {"blah", "blah.deblah", "blah.deblah.deblah"}); + Collection paramNames=getParameterNames(); + assertEquals(1, paramNames.size()); + assertEquals(paramNames.iterator().next(),"blah.deblah"); + } + + public void testEnsureOnlyPropsBlocked() throws Exception { + runFilterTest(null,"blah",false,new String[] {"blahdeblah"}); + assertEquals(1, getParameterNames().size()); + } + + + private void runFilterTest(String allowed, String blocked, boolean defaultBlocked, String[] paramNames) throws Exception { + interceptor.setAllowed(allowed); + interceptor.setBlocked(blocked); + interceptor.setDefaultBlock(defaultBlocked); + setUpParameters(paramNames); + runAction(); + + } + + private void setUpParameters(String [] paramNames) { + Map<String, String> params = new HashMap<>(); + for (String paramName : paramNames) { + params.put(paramName, "irrelevant what this is"); + + } + contextMap.put(ActionContext.PARAMETERS, params); + } + + private Collection getParameterNames() { + return ((Map)contextMap.get(ActionContext.PARAMETERS)).keySet(); + } + + public void runAction() throws Exception { + interceptor.intercept(invocation); + } + +} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptorTest.java new file mode 100644 index 0000000..e3b4e8f --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParameterRemoverInterceptorTest.java @@ -0,0 +1,116 @@ +package com.opensymphony.xwork2.interceptor; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ActionSupport; +import junit.framework.TestCase; +import org.easymock.MockControl; + +import java.util.LinkedHashMap; +import java.util.Map; + +/** + * @author tmjee + * @version $Date$ $Id$ + */ +public class ParameterRemoverInterceptorTest extends TestCase { + + protected Map<String, Object> contextMap; + protected ActionContext context; + protected MockControl actionInvocationControl; + protected ActionInvocation actionInvocation; + + @Override + protected void setUp() throws Exception { + contextMap = new LinkedHashMap<>(); + context = new ActionContext(contextMap); + + actionInvocationControl = MockControl.createControl(ActionInvocation.class); + actionInvocation = (ActionInvocation) actionInvocationControl.getMock(); + actionInvocationControl.expectAndDefaultReturn(actionInvocation.getAction(), new SampleAction()); + actionInvocationControl.expectAndDefaultReturn(actionInvocation.getInvocationContext(), context); + actionInvocationControl.expectAndDefaultReturn(actionInvocation.invoke(), "success"); + } + + public void testInterception1() throws Exception { + contextMap.put(ActionContext.PARAMETERS, new LinkedHashMap<String, Object>() { + private static final long serialVersionUID = 0L; + { + put("param1", new String[] { "paramValue1" }); + put("param2", new String[] { "paramValue2" }); + put("param3", new String[] { "paramValue3" }); + put("param", new String[] { "paramValue" }); + } + }); + + actionInvocationControl.replay(); + + ParameterRemoverInterceptor interceptor = new ParameterRemoverInterceptor(); + interceptor.setParamNames("param1,param2"); + interceptor.setParamValues("paramValue1,paramValue2"); + interceptor.intercept(actionInvocation); + + Map params = (Map) contextMap.get(ActionContext.PARAMETERS); + assertEquals(params.size(), 2); + assertTrue(params.containsKey("param3")); + assertTrue(params.containsKey("param")); + assertEquals(((String[])params.get("param3"))[0], "paramValue3"); + assertEquals(((String[])params.get("param"))[0], "paramValue"); + + actionInvocationControl.verify(); + } + + + public void testInterception2() throws Exception { + contextMap.put(ActionContext.PARAMETERS, new LinkedHashMap<String, Object>() { + private static final long serialVersionUID = 0L; + { + put("param1", new String[] { "paramValue2" }); + put("param2", new String[] { "paramValue1" }); + } + }); + + actionInvocationControl.replay(); + + ParameterRemoverInterceptor interceptor = new ParameterRemoverInterceptor(); + interceptor.setParamNames("param1,param2"); + interceptor.setParamValues("paramValue1,paramValue2"); + interceptor.intercept(actionInvocation); + + Map params = (Map) contextMap.get(ActionContext.PARAMETERS); + assertEquals(params.size(), 0); + + actionInvocationControl.verify(); + } + + + public void testInterception3() throws Exception { + contextMap.put(ActionContext.PARAMETERS, new LinkedHashMap<String, Object>() { + private static final long serialVersionUID = 0L; + { + put("param1", new String[] { "paramValueOne" }); + put("param2", new String[] { "paramValueTwo" }); + } + }); + + actionInvocationControl.replay(); + + ParameterRemoverInterceptor interceptor = new ParameterRemoverInterceptor(); + interceptor.setParamNames("param1,param2"); + interceptor.setParamValues("paramValue1,paramValue2"); + interceptor.intercept(actionInvocation); + + Map params = (Map) contextMap.get(ActionContext.PARAMETERS); + assertEquals(params.size(), 2); + assertTrue(params.containsKey("param1")); + assertTrue(params.containsKey("param2")); + assertEquals(((String[])params.get("param1"))[0], "paramValueOne"); + assertEquals(((String[])params.get("param2"))[0], "paramValueTwo"); + + actionInvocationControl.verify(); + } + + class SampleAction extends ActionSupport { + private static final long serialVersionUID = 7489487258845368260L; + } +} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java new file mode 100644 index 0000000..abf0f72 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/ParametersInterceptorTest.java @@ -0,0 +1,856 @@ +/* + * Copyright 2002-2006,2009 The Apache Software Foundation. + * + * 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.opensymphony.xwork2.interceptor; + +import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.config.entities.ActionConfig; +import com.opensymphony.xwork2.config.providers.MockConfigurationProvider; +import com.opensymphony.xwork2.config.providers.XWorkConfigurationProvider; +import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider; +import com.opensymphony.xwork2.conversion.impl.XWorkConverter; +import com.opensymphony.xwork2.mock.MockActionInvocation; +import com.opensymphony.xwork2.ognl.OgnlValueStack; +import com.opensymphony.xwork2.ognl.OgnlValueStackFactory; +import com.opensymphony.xwork2.ognl.SecurityMemberAccess; +import com.opensymphony.xwork2.ognl.accessor.CompoundRootAccessor; +import com.opensymphony.xwork2.util.CompoundRoot; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; +import junit.framework.Assert; +import ognl.OgnlContext; +import ognl.PropertyAccessor; + +import java.io.File; +import java.util.*; + + +/** + * Unit test for {@link ParametersInterceptor}. + * + * @author Jason Carreira + */ +public class ParametersInterceptorTest extends XWorkTestCase { + + public void testParameterNameAware() { + ParametersInterceptor pi = createParametersInterceptor(); + final Map<String, Object> actual = injectValueStackFactory(pi); + ValueStack stack = createStubValueStack(actual); + final Map<String, Object> expected = new HashMap<String, Object>() { + { + put("fooKey", "fooValue"); + put("barKey", "barValue"); + } + }; + Object a = new ParameterNameAware() { + public boolean acceptableParameterName(String parameterName) { + return expected.containsKey(parameterName); + } + }; + final Map<String, Object> parameters = new HashMap<String, Object>() { + { + put("fooKey", "fooValue"); + put("barKey", "barValue"); + put("error-key", "error"); + put("error key", "error"); + put("error:key", "error"); + put("error+key", "error"); + put("test%test", "test%test"); + } + }; + pi.setParameters(a, stack, parameters); + assertEquals(expected, actual); + } + + public void testInsecureParameters() throws Exception { + // given + loadConfigurationProviders(new XWorkConfigurationProvider(), new XmlConfigurationProvider("xwork-param-test.xml")); + final Map<String, Object> params = new HashMap<String, Object>() { + { + put("name", "(#context[\"xwork.MethodAccessor.denyMethodExecution\"]= new " + + "java.lang.Boolean(false), #_memberAccess[\"allowStaticMethodAccess\"]= new java.lang.Boolean(true), " + + "@java.lang.Runtime@getRuntime().exec('mkdir /tmp/PWNAGE'))(meh)"); + put("top['name'](0)", "true"); + } + }; + + ParametersInterceptor pi = new ParametersInterceptor(); + container.inject(pi); + ValueStack vs = ActionContext.getContext().getValueStack(); + + // when + ValidateAction action = new ValidateAction(); + pi.setParameters(action, vs, params); + + // then + assertEquals(1, action.getActionMessages().size()); + + String msg1 = action.getActionMessage(0); + + assertTrue(msg1.contains("Error setting expression 'top['name'](0)' with value 'true'")); + assertNull(action.getName()); + } + + public void testClassPollutionBlockedByPattern() throws Exception { + // given + final String pollution1 = "class.classLoader.jarPath"; + final String pollution2 = "model.class.classLoader.jarPath"; + + loadConfigurationProviders(new XWorkConfigurationProvider(), new XmlConfigurationProvider("xwork-param-test.xml")); + final Map<String, Object> params = new HashMap<String, Object>() { + { + put(pollution1, "bad"); + put(pollution2, "very bad"); + } + }; + + final Map<String, Boolean> excluded = new HashMap<>(); + ParametersInterceptor pi = new ParametersInterceptor() { + + @Override + protected boolean isExcluded(String paramName) { + boolean result = super.isExcluded(paramName); + excluded.put(paramName, result); + return result; + } + + }; + + container.inject(pi); + ValueStack vs = ActionContext.getContext().getValueStack(); + + // when + ValidateAction action = new ValidateAction(); + pi.setParameters(action, vs, params); + + // then + assertEquals(0, action.getActionMessages().size()); + assertTrue(excluded.get(pollution1)); + assertTrue(excluded.get(pollution2)); + } + + public void testClassPollutionBlockedByOgnl() throws Exception { + // given + final String pollution1 = "class.classLoader.jarPath"; + final String pollution2 = "model.class.classLoader.jarPath"; + final String pollution3 = "class.classLoader.defaultAssertionStatus"; + + loadConfigurationProviders(new XWorkConfigurationProvider(), new XmlConfigurationProvider("xwork-class-param-test.xml")); + final Map<String, Object> params = new HashMap<String, Object>() { + { + put(pollution1, "bad"); + put(pollution2, "very bad"); + put(pollution3, true); + } + }; + + final Map<String, Boolean> excluded = new HashMap<>(); + ParametersInterceptor pi = new ParametersInterceptor() { + + @Override + protected boolean isExcluded(String paramName) { + boolean result = super.isExcluded(paramName); + excluded.put(paramName, result); + return result; + } + + }; + + container.inject(pi); + ValueStack vs = ActionContext.getContext().getValueStack(); + + // when + ValidateAction action = new ValidateAction(); + pi.setParameters(action, vs, params); + + // then + assertEquals(3, action.getActionMessages().size()); + + String msg1 = action.getActionMessage(0); + String msg2 = action.getActionMessage(1); + String msg3 = action.getActionMessage(2); + + assertEquals("Error setting expression 'class.classLoader.defaultAssertionStatus' with value 'true'", msg1); + assertEquals("Error setting expression 'class.classLoader.jarPath' with value 'bad'", msg2); + assertEquals("Error setting expression 'model.class.classLoader.jarPath' with value 'very bad'", msg3); + + assertFalse(excluded.get(pollution1)); + assertFalse(excluded.get(pollution2)); + assertFalse(excluded.get(pollution3)); + } + + public void testDoesNotAllowMethodInvocations() throws Exception { + Map<String, Object> params = new HashMap<>(); + params.put("@java.lang.System@exit(1).dummy", "dumb value"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, null, extraContext); + assertEquals(Action.SUCCESS, proxy.execute()); + + String property = System.getProperty("xwork.security.test"); + assertNull(property); + } + + public void testModelDrivenParameters() throws Exception { + Map<String, Object> params = new HashMap<>(); + final String fooVal = "com.opensymphony.xwork2.interceptor.ParametersInterceptorTest.foo"; + params.put("foo", fooVal); + + final String nameVal = "com.opensymphony.xwork2.interceptor.ParametersInterceptorTest.name"; + params.put("name", nameVal); + params.put("count", "15"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.MODEL_DRIVEN_PARAM_TEST, null, extraContext); + assertEquals(Action.SUCCESS, proxy.execute()); + + ModelDrivenAction action = (ModelDrivenAction) proxy.getAction(); + TestBean model = (TestBean) action.getModel(); + assertEquals(nameVal, model.getName()); + assertEquals(15, model.getCount()); + assertEquals(fooVal, action.getFoo()); + } + + public void testParametersDoesNotAffectSession() throws Exception { + Map<String, Object> params = new HashMap<>(); + params.put("blah", "This is blah"); + params.put("#session.foo", "Foo"); + params.put("\u0023session[\'user\']", "0wn3d"); + params.put("\\u0023session[\'user\']", "0wn3d"); + params.put("\u0023session.user2", "0wn3d"); + params.put("\\u0023session.user2", "0wn3d"); + params.put("('\u0023'%20%2b%20'session[\'user3\']')(unused)", "0wn3d"); + params.put("('\\u0023' + 'session[\\'user4\\']')(unused)", "0wn3d"); + params.put("('\u0023'%2b'session[\'user5\']')(unused)", "0wn3d"); + params.put("('\\u0023'%2b'session[\'user5\']')(unused)", "0wn3d"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + ValueStack stack = proxy.getInvocation().getStack(); + HashMap<String, Object> session = new HashMap<>(); + stack.getContext().put("session", session); + proxy.execute(); + assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getBlah()); + assertNull(session.get("foo")); + assertNull(session.get("user")); + assertNull(session.get("user2")); + assertNull(session.get("user3")); + assertNull(session.get("user4")); + assertNull(session.get("user5")); + } + + public void testArrayClassPollutionBlockedByPattern() throws Exception { + // given + final String pollution1 = "model.class.classLoader.jarPath"; + final String pollution2 = "model['class']['classLoader']['jarPath']"; + final String pollution3 = "model[\"class\"]['classLoader']['jarPath']"; + final String pollution4 = "class.classLoader.jarPath"; + final String pollution5 = "class['classLoader']['jarPath']"; + final String pollution6 = "class[\"classLoader\"]['jarPath']"; + + loadConfigurationProviders(new XWorkConfigurationProvider(), new XmlConfigurationProvider("xwork-param-test.xml")); + final Map<String, Object> params = new HashMap<String, Object>() { + { + put(pollution1, "bad"); + put(pollution2, "bad"); + put(pollution3, "bad"); + put(pollution4, "bad"); + put(pollution5, "bad"); + put(pollution6, "bad"); + } + }; + + final Map<String, Boolean> excluded = new HashMap<String, Boolean>(); + ParametersInterceptor pi = new ParametersInterceptor() { + + @Override + protected boolean isExcluded(String paramName) { + boolean result = super.isExcluded(paramName); + excluded.put(paramName, result); + return result; + } + + }; + + container.inject(pi); + ValueStack vs = ActionContext.getContext().getValueStack(); + + // when + ValidateAction action = new ValidateAction(); + pi.setParameters(action, vs, params); + + // then + assertEquals(0, action.getActionMessages().size()); + assertTrue(excluded.get(pollution1)); + assertTrue(excluded.get(pollution2)); + assertTrue(excluded.get(pollution3)); + assertTrue(excluded.get(pollution4)); + assertTrue(excluded.get(pollution5)); + assertTrue(excluded.get(pollution6)); + } + + public void testAccessToOgnlInternals() throws Exception { + // given + Map<String, Object> params = new HashMap<>(); + params.put("blah", "This is blah"); + params.put("('\\u0023_memberAccess[\\'allowStaticMethodAccess\\']')(meh)", "true"); + params.put("('(aaa)(('\\u0023context[\\'xwork.MethodAccessor.denyMethodExecution\\']\\u003d\\u0023foo')(\\u0023foo\\u003dnew java.lang.Boolean(\"false\")))", ""); + params.put("(asdf)(('\\u0023rt.exit(1)')(\\u0023rt\\[email protected]@getRuntime()))", "1"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + ValueStack stack = proxy.getInvocation().getStack(); + + // when + proxy.execute(); + proxy.getAction(); + + //then + assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getBlah()); + boolean allowMethodAccess = ((SecurityMemberAccess) ((OgnlContext) stack.getContext()).getMemberAccess()).getAllowStaticMethodAccess(); + assertFalse(allowMethodAccess); + } + + public void testParameters() throws Exception { + Map<String, Object> params = new HashMap<>(); + params.put("blah", "This is blah"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getBlah()); + } + + public void testParametersWithSpacesInTheName() throws Exception { + Map<String, Object> params = new HashMap<>(); + params.put("theProtectedMap['p0 p1']", "test1"); + params.put("theProtectedMap['p0p1 ']", "test2"); + params.put("theProtectedMap[' p0p1 ']", "test3"); + params.put("theProtectedMap[' p0 p1 ']", "test4"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + Map<String, String> existingMap = ((SimpleAction) proxy.getAction()).getTheProtectedMap(); + assertEquals(0, existingMap.size()); + } + + public void testParametersWithChineseInTheName() throws Exception { + Map<String, Object> params = new HashMap<>(); + params.put("theProtectedMap['åå']", "test1"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + Map<String, String> existingMap = ((SimpleAction) proxy.getAction()).getTheProtectedMap(); + assertEquals(1, existingMap.size()); + } + + public void testLargeParameterNameWithDefaultLimit() throws Exception { + ParametersInterceptor parametersInterceptor = createParametersInterceptor(); + doTestParameterNameLengthRestriction(parametersInterceptor, ParametersInterceptor.PARAM_NAME_MAX_LENGTH); + } + + public void testLargeParameterNameWithCustomLimit() throws Exception { + ParametersInterceptor parametersInterceptor = createParametersInterceptor(); + int limit = 20; + parametersInterceptor.setParamNameMaxLength(limit); + doTestParameterNameLengthRestriction(parametersInterceptor, limit); + } + + private void doTestParameterNameLengthRestriction(ParametersInterceptor parametersInterceptor, + int paramNameMaxLength) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < paramNameMaxLength + 1; i++) { + sb.append("x"); + } + + Map<String, Object> actual = new LinkedHashMap<>(); + parametersInterceptor.setValueStackFactory(createValueStackFactory(actual)); + ValueStack stack = createStubValueStack(actual); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put(sb.toString(), ""); + parameters.put("huuhaa", ""); + + Action action = new SimpleAction(); + parametersInterceptor.setParameters(action, stack, parameters); + assertEquals(1, actual.size()); + } + + public void testExcludedTrickyParameters() throws Exception { + Map<String, Object> params = new HashMap<String, Object>() { + { + put("blah", "This is blah"); + put("name", "try_1"); + put("(name)", "try_2"); + put("['name']", "try_3"); + put("['na' + 'me']", "try_4"); + put("{name}[0]", "try_5"); + put("(new string{'name'})[0]", "try_6"); + put("#{key: 'name'}.key", "try_7"); + + } + }; + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + + ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME); + ParametersInterceptor pi = (ParametersInterceptor) config.getInterceptors().get(0).getInterceptor(); + pi.setExcludeParams("name"); + + proxy.execute(); + + SimpleAction action = (SimpleAction) proxy.getAction(); + assertNull(action.getName()); + assertEquals("This is blah", (action).getBlah()); + } + + public void testAcceptedTrickyParameters() throws Exception { + Map<String, Object> params = new HashMap<String, Object>() { + { + put("blah", "This is blah"); + put("baz", "123"); + put("name", "try_1"); + put("(name)", "try_2"); + put("['name']", "try_3"); + put("['na' + 'me']", "try_4"); + put("{name}[0]", "try_5"); + put("(new string{'name'})[0]", "try_6"); + put("#{key: 'name'}.key", "try_7"); + } + }; + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + + ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME); + ParametersInterceptor pi = (ParametersInterceptor) config.getInterceptors().get(0).getInterceptor(); + pi.setAcceptParamNames("blah, baz"); + + proxy.execute(); + + SimpleAction action = (SimpleAction) proxy.getAction(); + assertNull("try_1", action.getName()); + assertEquals("This is blah", (action).getBlah()); + assertEquals(123, action.getBaz()); + } + + + public void testParametersNotAccessPrivateVariables() throws Exception { + Map<String, Object> params = new HashMap<>(); + params.put("protectedMap.foo", "This is blah"); + params.put("theProtectedMap.boo", "This is blah"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + SimpleAction action = (SimpleAction) proxy.getAction(); + assertEquals(1, action.getTheProtectedMap().size()); + assertNotNull(action.getTheProtectedMap().get("boo")); + assertNull(action.getTheProtectedMap().get("foo")); + } + + public void testParametersNotAccessProtectedMethods() throws Exception { + Map<String, Object> params = new HashMap<>(); + params.put("theSemiProtectedMap.foo", "This is blah"); + params.put("theProtectedMap.boo", "This is blah"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + SimpleAction action = (SimpleAction) proxy.getAction(); + assertEquals(1, action.getTheProtectedMap().size()); + assertNotNull(action.getTheProtectedMap().get("boo")); + assertNull(action.getTheProtectedMap().get("foo")); + } + + /** + * This test demonstrates a vulnerability which allows to execute arbitrary code. + * For further details and explanations see https://cwiki.apache.org/confluence/display/WW/S2-009 + * + * @throws Exception + */ + public void testEvalExpressionAsParameterName() throws Exception { + Map<String, Object> params = new HashMap<>(); + params.put("blah", "(#context[\"xwork.MethodAccessor.denyMethodExecution\"]= new " + + "java.lang.Boolean(false), #_memberAccess[\"allowStaticMethodAccess\"]= new java.lang.Boolean(true), " + + "@java.lang.Runtime@getRuntime().exec('mkdir /tmp/PWNAGE'))(meh)"); + params.put("top['blah'](0)", "true"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + @SuppressWarnings("unused") + SimpleAction action = (SimpleAction) proxy.getAction(); + File pwn = new File("/tmp/PWNAGE"); + boolean dirExists = pwn.exists(); + @SuppressWarnings("unused") + boolean deleted = pwn.delete(); + Assert.assertFalse("Remote exploit: The PWN folder has been created", dirExists); + } + + public void testParametersOverwriteField() throws Exception { + Map<String, Object> params = new LinkedHashMap<>(); + params.put("existingMap.boo", "This is blah"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + SimpleAction action = (SimpleAction) proxy.getAction(); + assertEquals(1, action.getTheExistingMap().size()); + assertNotNull(action.getTheExistingMap().get("boo")); + assertNull(action.getTheExistingMap().get("existingKey")); + } + + public void testNonexistentParametersGetLoggedInDevMode() throws Exception { + XmlConfigurationProvider provider = new XmlConfigurationProvider("xwork-test-beans.xml"); + container.inject(provider); + loadConfigurationProviders(provider, + new MockConfigurationProvider(Collections.singletonMap("devMode", "true"))); + Map<String, Object> params = new HashMap<>(); + params.put("not_a_property", "There is no action property named like this"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME); + container.inject(config.getInterceptors().get(0).getInterceptor()); + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + final String actionMessage = "" + ((SimpleAction) proxy.getAction()).getActionMessages().toArray()[0]; + assertTrue(actionMessage.contains("Error setting expression 'not_a_property' with value 'There is no action property named like this'")); + } + + public void testNonexistentParametersAreIgnoredInProductionMode() throws Exception { + XmlConfigurationProvider provider = new XmlConfigurationProvider("xwork-test-beans.xml"); + container.inject(provider); + loadConfigurationProviders(provider, + new MockConfigurationProvider(Collections.singletonMap("devMode", "false"))); + Map<String, Object> params = new HashMap<>(); + params.put("not_a_property", "There is no action property named like this"); + + HashMap<String, Object> extraContext = new HashMap<>(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME); + container.inject(config.getInterceptors().get(0).getInterceptor()); + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, null, extraContext); + proxy.execute(); + assertTrue(((SimpleAction) proxy.getAction()).getActionMessages().isEmpty()); + } + + public void testNoParametersAction() throws Exception { + ParametersInterceptor interceptor = new ParametersInterceptor(); + interceptor.init(); + + MockActionInvocation mai = new MockActionInvocation(); + Action action = new NoParametersAction(); + mai.setAction(action); + + interceptor.doIntercept(mai); + interceptor.destroy(); + } + + public void testNoOrdered() throws Exception { + ParametersInterceptor pi = createParametersInterceptor(); + final Map<String, Object> actual = new LinkedHashMap<>(); + pi.setValueStackFactory(createValueStackFactory(actual)); + ValueStack stack = createStubValueStack(actual); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("user.address.city", "London"); + parameters.put("user.name", "Superman"); + + Action action = new SimpleAction(); + pi.setParameters(action, stack, parameters); + + assertEquals("ordered should be false by default", false, pi.isOrdered()); + assertEquals(2, actual.size()); + assertEquals("London", actual.get("user.address.city")); + assertEquals("Superman", actual.get("user.name")); + + // is not ordered + List<Object> values = new ArrayList<Object>(actual.values()); + assertEquals("London", values.get(0)); + assertEquals("Superman", values.get(1)); + } + + public void testOrdered() throws Exception { + ParametersInterceptor pi = new ParametersInterceptor(); + pi.setOrdered(true); + container.inject(pi); + final Map<String, Object> actual = new LinkedHashMap<>(); + pi.setValueStackFactory(createValueStackFactory(actual)); + ValueStack stack = createStubValueStack(actual); + + Map<String, Object> parameters = new HashMap<>(); + parameters.put("user.address.city", "London"); + parameters.put("user.address['postal']", "QJR387"); + parameters.put("user.name", "Superman"); + + Action action = new SimpleAction(); + pi.setParameters(action, stack, parameters); + + assertEquals(true, pi.isOrdered()); + assertEquals(3, actual.size()); + assertEquals("London", actual.get("user.address.city")); + assertEquals("QJR387", actual.get("user.address['postal']")); + assertEquals("Superman", actual.get("user.name")); + + // should be ordered so user.name should be first + List<Object> values = new ArrayList<Object>(actual.values()); + assertEquals("Superman", values.get(0)); + assertEquals("London", values.get(1)); + assertEquals("QJR387", values.get(2)); + } + + public void testSetOrdered() throws Exception { + ParametersInterceptor pi = createParametersInterceptor(); + assertEquals("ordered should be false by default", false, pi.isOrdered()); + pi.setOrdered(true); + assertEquals(true, pi.isOrdered()); + } + + public void testExcludedParametersAreIgnored() throws Exception { + ParametersInterceptor pi = createParametersInterceptor(); + pi.setExcludeParams("dojo\\..*"); + final Map<String, Object> actual = injectValueStackFactory(pi); + ValueStack stack = injectValueStack(actual); + + final Map<String, Object> expected = new HashMap<String, Object>() { + { + put("fooKey", "fooValue"); + } + }; + + Map<String, Object> parameters = new HashMap<String, Object>() { + { + put("dojo.test", "dojoValue"); + put("fooKey", "fooValue"); + } + }; + pi.setParameters(new NoParametersAction(), stack, parameters); + assertEquals(expected, actual); + } + + public void testInternalParametersAreIgnored() throws Exception { + // given + ParametersInterceptor interceptor = createParametersInterceptor(); + final Map<String, Object> actual = injectValueStackFactory(interceptor); + ValueStack stack = injectValueStack(actual); + + + final Map<String, Object> expected = new HashMap<String, Object>() { + { + put("ordinary.bean", "value"); + } + }; + + Map<String, Object> parameters = new HashMap<String, Object>() { + { + put("ordinary.bean", "value"); + put("#some.internal.object", "true"); + put("(bla)#some.internal.object", "true"); + put("#some.internal.object(bla)#some.internal.object", "true"); + put("#_some.internal.object", "true"); + put("\u0023_some.internal.object", "true"); + put("\u0023_some.internal.object,[dfd],bla(\u0023_some.internal.object)", "true"); + put("\\u0023_some.internal.object", "true"); + } + }; + + // when + interceptor.setParameters(new NoParametersAction(), stack, parameters); + + // then + assertEquals(expected, actual); + } + + private ValueStack injectValueStack(Map<String, Object> actual) { + ValueStack stack = createStubValueStack(actual); + container.inject(stack); + return stack; + } + + private Map<String, Object> injectValueStackFactory(ParametersInterceptor interceptor) { + final Map<String, Object> actual = new HashMap<>(); + interceptor.setValueStackFactory(createValueStackFactory(actual)); + return actual; + } + + private ParametersInterceptor createParametersInterceptor() { + ParametersInterceptor pi = new ParametersInterceptor(); + container.inject(pi); + return pi; + } + + private ValueStackFactory createValueStackFactory(final Map<String, Object> context) { + OgnlValueStackFactory factory = new OgnlValueStackFactory() { + @Override + public ValueStack createValueStack(ValueStack stack) { + return createStubValueStack(context); + } + }; + container.inject(factory); + return factory; + } + + private ValueStack createStubValueStack(final Map<String, Object> actual) { + ValueStack stack = new OgnlValueStack( + container.getInstance(XWorkConverter.class), + (CompoundRootAccessor) container.getInstance(PropertyAccessor.class, CompoundRoot.class.getName()), + container.getInstance(TextProvider.class, "system"), true) { + @Override + public void setValue(String expr, Object value) { + actual.put(expr, value); + } + + @Override + public void setParameter(String expr, Object value) { + actual.put(expr, value); + } + }; + container.inject(stack); + return stack; + } + + /* + public void testIndexedParameters() throws Exception { + Map params = new HashMap(); + params.put("indexedProp[33]", "This is blah"); + + HashMap extraContext = new HashMap(); + extraContext.put(ActionContext.PARAMETERS, params); + + ActionProxy proxy = actionProxyFactory.createActionProxy("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME, extraContext); + proxy.execute(); + assertEquals("This is blah", ((SimpleAction) proxy.getAction()).getIndexedProp(33)); + } + */ + + + private class NoParametersAction implements Action, NoParameters { + + public String execute() throws Exception { + return SUCCESS; + } + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + XmlConfigurationProvider provider = new XmlConfigurationProvider("xwork-test-beans.xml"); + container.inject(provider); + loadConfigurationProviders(provider, new MockConfigurationProvider()); + + ActionConfig config = configuration.getRuntimeConfiguration().getActionConfig("", MockConfigurationProvider.PARAM_INTERCEPTOR_ACTION_NAME); + container.inject(config.getInterceptors().get(0).getInterceptor()); + } + +} + +class ValidateAction implements ValidationAware { + + private List<String> messages = new LinkedList<>(); + private String name; + + public void setActionErrors(Collection<String> errorMessages) { + } + + public Collection<String> getActionErrors() { + return null; + } + + public void setActionMessages(Collection<String> messages) { + } + + public Collection<String> getActionMessages() { + return messages; + } + + public void setFieldErrors(Map<String, List<String>> errorMap) { + } + + public Map<String, List<String>> getFieldErrors() { + return null; + } + + public void addActionError(String anErrorMessage) { + } + + public void addActionMessage(String aMessage) { + messages.add(aMessage); + } + + public void addFieldError(String fieldName, String errorMessage) { + } + + public boolean hasActionErrors() { + return false; + } + + public boolean hasActionMessages() { + return messages.size() > 0; + } + + public boolean hasErrors() { + return false; + } + + public boolean hasFieldErrors() { + return false; + } + + public String getActionMessage(int index) { + return messages.get(index); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/PreResultListenerTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/PreResultListenerTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/PreResultListenerTest.java new file mode 100644 index 0000000..9682741 --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/PreResultListenerTest.java @@ -0,0 +1,119 @@ +/* + * Copyright 2002-2003,2009 The Apache Software Foundation. + * + * 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.opensymphony.xwork2.interceptor; + +import com.mockobjects.dynamic.C; +import com.mockobjects.dynamic.Mock; +import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationException; +import com.opensymphony.xwork2.config.ConfigurationProvider; +import com.opensymphony.xwork2.config.entities.ActionConfig; +import com.opensymphony.xwork2.config.entities.PackageConfig; +import com.opensymphony.xwork2.inject.ContainerBuilder; +import com.opensymphony.xwork2.util.location.LocatableProperties; + +import java.util.HashMap; + + +/** + * PreResultListenerTest + * + * @author Jason Carreira + * Date: Nov 13, 2003 11:16:43 PM + */ +public class PreResultListenerTest extends XWorkTestCase { + + private int count = 1; + + + public void testPreResultListenersAreCalled() throws Exception { + ActionProxy proxy = actionProxyFactory.createActionProxy("package", "action", new HashMap<String, Object>(), false, true); + ActionInvocation invocation = proxy.getInvocation(); + Mock preResultListenerMock1 = new Mock(PreResultListener.class); + preResultListenerMock1.expect("beforeResult", C.args(C.eq(invocation), C.eq(Action.SUCCESS))); + invocation.addPreResultListener((PreResultListener) preResultListenerMock1.proxy()); + proxy.execute(); + preResultListenerMock1.verify(); + } + + public void testPreResultListenersAreCalledInOrder() throws Exception { + ActionProxy proxy = actionProxyFactory.createActionProxy("package", "action", new HashMap<String, Object>(), false, true); + ActionInvocation invocation = proxy.getInvocation(); + CountPreResultListener listener1 = new CountPreResultListener(); + CountPreResultListener listener2 = new CountPreResultListener(); + invocation.addPreResultListener(listener1); + invocation.addPreResultListener(listener2); + proxy.execute(); + assertNotNull(listener1.getMyOrder()); + assertNotNull(listener2.getMyOrder()); + assertEquals(listener1.getMyOrder() + 1, listener2.getMyOrder().intValue()); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + loadConfigurationProviders(new ConfigurationProvider() { + Configuration configuration; + public void destroy() { + } + + public void init(Configuration config) { + this.configuration = config; + } + + public void loadPackages() { + PackageConfig packageConfig = new PackageConfig.Builder("package") + .addActionConfig("action", new ActionConfig.Builder("package", "action", SimpleFooAction.class.getName()).build()) + .build(); + configuration.addPackageConfig("package", packageConfig); + } + + /** + * Tells whether the ConfigurationProvider should reload its configuration + * + * @return + */ + public boolean needsReload() { + return false; + } + + public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException { + builder.factory(ActionProxyFactory.class, DefaultActionProxyFactory.class); + builder.factory(ObjectFactory.class); + + } + }); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + + private class CountPreResultListener implements PreResultListener { + private Integer myOrder = null; + + public Integer getMyOrder() { + return myOrder; + } + + public void beforeResult(ActionInvocation invocation, String resultCode) { + myOrder = count++; + } + } +} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtilTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtilTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtilTest.java new file mode 100644 index 0000000..fa02c8b --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/PrefixMethodInvocationUtilTest.java @@ -0,0 +1,292 @@ +/* + * Copyright 2002-2006,2009 The Apache Software Foundation. + * + * 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.opensymphony.xwork2.interceptor; + +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ActionProxy; +import junit.framework.TestCase; +import org.easymock.MockControl; + +import java.lang.reflect.Method; + +/** + * Test case for PrefixMethodInovcationUtil. + * + * @author tm_jee + * @version $Date$ $Id$ + */ +public class PrefixMethodInvocationUtilTest extends TestCase { + + // === capitalizeMethodName === + public void testCapitalizeMethodName() throws Exception { + assertEquals("SomeMethod", + PrefixMethodInvocationUtil.capitalizeMethodName("someMethod")); + assertEquals("AnotherMethod", + PrefixMethodInvocationUtil.capitalizeMethodName("anotherMethod")); + } + + // === getPrefixMethod === + public void testGetPrefixMethod1() throws Exception { + Object action = new PrefixMethodInvocationUtilTest.Action1(); + Method m = PrefixMethodInvocationUtil.getPrefixedMethod( + new String[] { "prepare", "prepareDo" }, "save", action); + assertNotNull(m); + assertEquals(m.getName(), "prepareSave"); + } + + public void testGetPrefixMethod2() throws Exception { + Object action = new PrefixMethodInvocationUtilTest.Action1(); + Method m = PrefixMethodInvocationUtil.getPrefixedMethod( + new String[] { "prepare", "prepareDo" }, "submit", action); + assertNotNull(m); + assertEquals(m.getName(), "prepareSubmit"); + } + + public void testGetPrefixMethod3() throws Exception { + Object action = new PrefixMethodInvocationUtilTest.Action1(); + Method m = PrefixMethodInvocationUtil.getPrefixedMethod( + new String[] { "prepare", "prepareDo" }, "cancel", action); + assertNotNull(m); + assertEquals(m.getName(), "prepareDoCancel"); + } + + public void testGetPrefixMethod4() throws Exception { + Object action = new PrefixMethodInvocationUtilTest.Action1(); + Method m = PrefixMethodInvocationUtil.getPrefixedMethod( + new String[] { "prepare", "prepareDo" }, "noSuchMethod", action); + assertNull(m); + } + + public void testGetPrefixMethod5() throws Exception { + Object action = new PrefixMethodInvocationUtilTest.Action1(); + Method m = PrefixMethodInvocationUtil.getPrefixedMethod( + new String[] { "noSuchPrefix", "noSuchPrefixDo" }, "save", action); + assertNull(m); + } + + + // === invokePrefixMethod === + public void testInvokePrefixMethod1() throws Exception { + PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1(); + + // ActionProxy + MockControl controlActionProxy = MockControl.createControl(ActionProxy.class); + ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock(); + mockActionProxy.getMethod(); + controlActionProxy.setReturnValue("save"); + + + // ActionInvocation + MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class); + ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock(); + mockActionInvocation.getAction(); + controlActionInvocation.setReturnValue(action); + mockActionInvocation.getProxy(); + controlActionInvocation.setReturnValue(mockActionProxy); + + controlActionProxy.replay(); + controlActionInvocation.replay(); + + + PrefixMethodInvocationUtil.invokePrefixMethod( + mockActionInvocation, + new String[] { "prepare", "prepareDo" }); + + controlActionProxy.verify(); + controlActionInvocation.verify(); + + assertTrue(action.prepareSaveInvoked); + assertFalse(action.prepareDoSaveInvoked); + assertFalse(action.prepareSubmitInvoked); + assertFalse(action.prepareDoCancelInvoked); + } + + public void testInvokePrefixMethod2() throws Exception { + PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1(); + + // ActionProxy + MockControl controlActionProxy = MockControl.createControl(ActionProxy.class); + ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock(); + mockActionProxy.getMethod(); + controlActionProxy.setReturnValue("submit"); + + + // ActionInvocation + MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class); + ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock(); + mockActionInvocation.getAction(); + controlActionInvocation.setReturnValue(action); + mockActionInvocation.getProxy(); + controlActionInvocation.setReturnValue(mockActionProxy); + + controlActionProxy.replay(); + controlActionInvocation.replay(); + + + PrefixMethodInvocationUtil.invokePrefixMethod( + mockActionInvocation, + new String[] { "prepare", "prepareDo" }); + + controlActionProxy.verify(); + controlActionInvocation.verify(); + + assertFalse(action.prepareSaveInvoked); + assertFalse(action.prepareDoSaveInvoked); + assertTrue(action.prepareSubmitInvoked); + assertFalse(action.prepareDoCancelInvoked); + } + + public void testInvokePrefixMethod3() throws Exception { + PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1(); + + // ActionProxy + MockControl controlActionProxy = MockControl.createControl(ActionProxy.class); + ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock(); + mockActionProxy.getMethod(); + controlActionProxy.setReturnValue("cancel"); + + + // ActionInvocation + MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class); + ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock(); + mockActionInvocation.getAction(); + controlActionInvocation.setReturnValue(action); + mockActionInvocation.getProxy(); + controlActionInvocation.setReturnValue(mockActionProxy); + + controlActionProxy.replay(); + controlActionInvocation.replay(); + + + PrefixMethodInvocationUtil.invokePrefixMethod( + mockActionInvocation, + new String[] { "prepare", "prepareDo" }); + + controlActionProxy.verify(); + controlActionInvocation.verify(); + + assertFalse(action.prepareSaveInvoked); + assertFalse(action.prepareDoSaveInvoked); + assertFalse(action.prepareSubmitInvoked); + assertTrue(action.prepareDoCancelInvoked); + } + + public void testInvokePrefixMethod4() throws Exception { + PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1(); + + // ActionProxy + MockControl controlActionProxy = MockControl.createControl(ActionProxy.class); + ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock(); + mockActionProxy.getMethod(); + controlActionProxy.setReturnValue("noSuchMethod"); + + + // ActionInvocation + MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class); + ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock(); + mockActionInvocation.getAction(); + controlActionInvocation.setReturnValue(action); + mockActionInvocation.getProxy(); + controlActionInvocation.setReturnValue(mockActionProxy); + + controlActionProxy.replay(); + controlActionInvocation.replay(); + + + PrefixMethodInvocationUtil.invokePrefixMethod( + mockActionInvocation, + new String[] { "prepare", "prepareDo" }); + + controlActionProxy.verify(); + controlActionInvocation.verify(); + + assertFalse(action.prepareSaveInvoked); + assertFalse(action.prepareDoSaveInvoked); + assertFalse(action.prepareSubmitInvoked); + assertFalse(action.prepareDoCancelInvoked); + } + + public void testInvokePrefixMethod5() throws Exception { + PrefixMethodInvocationUtilTest.Action1 action = new PrefixMethodInvocationUtilTest.Action1(); + + // ActionProxy + MockControl controlActionProxy = MockControl.createControl(ActionProxy.class); + ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock(); + mockActionProxy.getMethod(); + controlActionProxy.setReturnValue("save"); + + + // ActionInvocation + MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class); + ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock(); + mockActionInvocation.getAction(); + controlActionInvocation.setReturnValue(action); + mockActionInvocation.getProxy(); + controlActionInvocation.setReturnValue(mockActionProxy); + + controlActionProxy.replay(); + controlActionInvocation.replay(); + + + PrefixMethodInvocationUtil.invokePrefixMethod( + mockActionInvocation, + new String[] { "noSuchPrefix", "noSuchPrefixDo" }); + + controlActionProxy.verify(); + controlActionInvocation.verify(); + + assertFalse(action.prepareSaveInvoked); + assertFalse(action.prepareDoSaveInvoked); + assertFalse(action.prepareSubmitInvoked); + assertFalse(action.prepareDoCancelInvoked); + } + + + + + /** + * Just a simple object for testing method invocation on its methods. + * + * @author tm_jee + * @version $Date$ $Id$ + */ + public static class Action1 { + + boolean prepareSaveInvoked = false; + boolean prepareDoSaveInvoked = false; + boolean prepareSubmitInvoked = false; + boolean prepareDoCancelInvoked = false; + + + // save + public void prepareSave() { + prepareSaveInvoked = true; + } + public void prepareDoSave() { + prepareDoSaveInvoked = true; + } + + // submit + public void prepareSubmit() { + prepareSubmitInvoked = true; + } + + // cancel + public void prepareDoCancel() { + prepareDoCancelInvoked = true; + } + } +} http://git-wip-us.apache.org/repos/asf/struts/blob/31af5842/core/src/test/java/com/opensymphony/xwork2/interceptor/PrepareInterceptorTest.java ---------------------------------------------------------------------- diff --git a/core/src/test/java/com/opensymphony/xwork2/interceptor/PrepareInterceptorTest.java b/core/src/test/java/com/opensymphony/xwork2/interceptor/PrepareInterceptorTest.java new file mode 100644 index 0000000..1b0f95d --- /dev/null +++ b/core/src/test/java/com/opensymphony/xwork2/interceptor/PrepareInterceptorTest.java @@ -0,0 +1,221 @@ +/* + * $Id$ + * Copyright 2002-2007,2009 The Apache Software Foundation. + * + * 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.opensymphony.xwork2.interceptor; + +import com.mockobjects.dynamic.Mock; +import com.opensymphony.xwork2.*; +import com.opensymphony.xwork2.mock.MockActionInvocation; +import com.opensymphony.xwork2.mock.MockActionProxy; +import junit.framework.TestCase; +import org.easymock.MockControl; + +/** + * Unit test for PrepareInterceptor. + * + * @author Claus Ibsen + * @author tm_jee + */ +public class PrepareInterceptorTest extends TestCase { + + private Mock mock; + private PrepareInterceptor interceptor; + + public void testPrepareCalledDefault() throws Exception { + MockActionInvocation mai = new MockActionInvocation(); + MockActionProxy mockActionProxy = new MockActionProxy(); + mockActionProxy.setMethod("execute"); + mai.setProxy(mockActionProxy); + mai.setAction(mock.proxy()); + mock.expect("prepare"); + + interceptor.intercept(mai); + } + + public void testPrepareCalledFalse() throws Exception { + MockActionInvocation mai = new MockActionInvocation(); + MockActionProxy mockActionProxy = new MockActionProxy(); + mockActionProxy.setMethod("execute"); + mai.setProxy(mockActionProxy); + mai.setAction(mock.proxy()); + + interceptor.setAlwaysInvokePrepare("false"); + interceptor.intercept(mai); + } + + public void testPrepareCalledTrue() throws Exception { + MockActionInvocation mai = new MockActionInvocation(); + MockActionProxy mockActionProxy = new MockActionProxy(); + mockActionProxy.setMethod("execute"); + mai.setProxy(mockActionProxy); + mai.setAction(mock.proxy()); + mock.expect("prepare"); + + interceptor.setAlwaysInvokePrepare("true"); + interceptor.intercept(mai); + } + + public void testFirstCallPrepareDoIsTrue() throws Exception { + MockActionInvocation mai = new MockActionInvocation(); + MockActionProxy mockActionProxy = new MockActionProxy(); + mockActionProxy.setMethod("submit"); + mai.setProxy(mockActionProxy); + mai.setAction(mock.proxy()); + mock.expect("prepareSubmit"); + mock.expect("prepare"); + + interceptor.setFirstCallPrepareDo("true"); + interceptor.intercept(mai); + } + + public void testFirstCallPrepareDoIsFalse() throws Exception { + MockActionInvocation mai = new MockActionInvocation(); + MockActionProxy mockActionProxy = new MockActionProxy(); + mockActionProxy.setMethod("submit"); + mai.setProxy(mockActionProxy); + mai.setAction(mock.proxy()); + mock.expect("prepare"); + mock.expect("prepareSubmit"); + + interceptor.setFirstCallPrepareDo("false"); + interceptor.intercept(mai); + } + + public void testNoPrepareCalled() throws Exception { + MockActionInvocation mai = new MockActionInvocation(); + mai.setAction(new SimpleFooAction()); + + interceptor.doIntercept(mai); + } + + public void testPrefixInvocation1() throws Exception { + + MockControl controlAction = MockControl.createControl(ActionInterface.class); + ActionInterface mockAction = (ActionInterface) controlAction.getMock(); + mockAction.prepareSubmit(); + controlAction.setVoidCallable(1); + mockAction.prepare(); + controlAction.setVoidCallable(1); + + MockControl controlActionProxy = MockControl.createControl(ActionProxy.class); + ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock(); + mockActionProxy.getMethod(); + controlActionProxy.setDefaultReturnValue("submit"); + + + MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class); + ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock(); + mockActionInvocation.getAction(); + controlActionInvocation.setDefaultReturnValue(mockAction); + mockActionInvocation.invoke(); + controlActionInvocation.setDefaultReturnValue("okok"); + mockActionInvocation.getProxy(); + controlActionInvocation.setDefaultReturnValue(mockActionProxy); + + + controlAction.replay(); + controlActionProxy.replay(); + controlActionInvocation.replay(); + + PrepareInterceptor interceptor = new PrepareInterceptor(); + String result = interceptor.intercept(mockActionInvocation); + + assertEquals("okok", result); + + controlAction.verify(); + controlActionProxy.verify(); + controlActionInvocation.verify(); + } + + public void testPrefixInvocation2() throws Exception { + + MockControl controlAction = MockControl.createControl(ActionInterface.class); + ActionInterface mockAction = (ActionInterface) controlAction.getMock(); + mockAction.prepare(); + controlAction.setVoidCallable(1); + + MockControl controlActionProxy = MockControl.createControl(ActionProxy.class); + ActionProxy mockActionProxy = (ActionProxy) controlActionProxy.getMock(); + mockActionProxy.getMethod(); + controlActionProxy.setDefaultReturnValue("save"); + + + MockControl controlActionInvocation = MockControl.createControl(ActionInvocation.class); + ActionInvocation mockActionInvocation = (ActionInvocation) controlActionInvocation.getMock(); + mockActionInvocation.getAction(); + controlActionInvocation.setDefaultReturnValue(mockAction); + mockActionInvocation.invoke(); + controlActionInvocation.setDefaultReturnValue("okok"); + mockActionInvocation.getProxy(); + controlActionInvocation.setDefaultReturnValue(mockActionProxy); + + + controlAction.replay(); + controlActionProxy.replay(); + controlActionInvocation.replay(); + + PrepareInterceptor interceptor = new PrepareInterceptor(); + String result = interceptor.intercept(mockActionInvocation); + + assertEquals("okok", result); + + controlAction.verify(); + controlActionProxy.verify(); + controlActionInvocation.verify(); + } + + public void testPrepareThrowException() throws Exception { + MockActionInvocation mai = new MockActionInvocation(); + MockActionProxy mockActionProxy = new MockActionProxy(); + mockActionProxy.setMethod("submit"); + mai.setProxy(mockActionProxy); + mai.setAction(mock.proxy()); + + IllegalAccessException illegalAccessException = new IllegalAccessException(); + mock.expectAndThrow("prepareSubmit", illegalAccessException); + mock.matchAndThrow("prepare", new RuntimeException()); + + try { + interceptor.intercept(mai); + fail("Should not have reached this point."); + } catch (Throwable t) { + assertSame(illegalAccessException, t); + } + } + + @Override + protected void setUp() throws Exception { + mock = new Mock(ActionInterface.class); + interceptor = new PrepareInterceptor(); + } + + @Override + protected void tearDown() throws Exception { + mock.verify(); + } + + + /** + * Simple interface to test prefix action invocation + * eg. prepareSubmit(), prepareSave() etc. + * + * @author tm_jee + */ + public interface ActionInterface extends Action, Preparable { + void prepareSubmit() throws Exception; + } + +}
