You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@struts.apache.org by lu...@apache.org on 2015/06/17 23:09:23 UTC
[23/57] [partial] struts git commit: Merges xwork packages into struts
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\\u003d@java.lang.Runtime@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;
+ }
+
+}