blob: 9beef5d453b90235f2f3be50f62c14d588550783 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.struts2.views.jsp;
import com.mockobjects.servlet.MockJspWriter;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.ActionProxy;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import org.apache.struts2.dispatcher.Dispatcher;
import org.apache.struts2.dispatcher.mapper.ActionMapping;
import org.apache.struts2.portlet.PortletConstants;
import org.apache.struts2.portlet.PortletPhase;
import org.apache.struts2.portlet.util.PortletUrlHelper;
import org.jmock.Mock;
import org.jmock.cglib.MockObjectTestCase;
import org.jmock.core.Constraint;
import org.springframework.mock.web.MockServletContext;
import javax.portlet.PortletContext;
import javax.portlet.PortletMode;
import javax.portlet.PortletURL;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.WindowState;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import static org.apache.struts2.StrutsStatics.STRUTS_PORTLET_CONTEXT;
/**
*
*/
@SuppressWarnings("unchecked")
public class PortletUrlTagTest extends MockObjectTestCase {
URLTag tag = new URLTag();
Mock mockHttpReq = null;
Mock mockHttpRes = null;
Mock mockPortletReq = null;
Mock mockPortletRes = null;
Mock mockPageCtx = null;
Mock mockPortletUrl = null;
MockJspWriter mockJspWriter = null;
Mock mockCtx = null;
ValueStack stack = null;
Mock mockActionProxy = null;
Mock mockActionInvocation = null;
private Dispatcher dispatcher;
public void setUp() throws Exception {
super.setUp();
ServletContext servletContext = new MockServletContext();
dispatcher = new Dispatcher(servletContext, new HashMap<>());
dispatcher.init();
Dispatcher.setInstance(dispatcher);
stack = dispatcher.getContainer().getInstance(ValueStackFactory.class).createValueStack();
mockActionInvocation = mock(ActionInvocation.class);
mockActionProxy = mock(ActionProxy.class);
mockHttpReq = mock(HttpServletRequest.class);
mockHttpRes = mock(HttpServletResponse.class);
mockPortletReq = mock(RenderRequest.class);
mockPortletRes = mock(RenderResponse.class);
mockPageCtx = mock(PageContext.class);
mockPortletUrl = mock(PortletURL.class);
mockJspWriter = new MockJspWriter();
mockCtx = mock(PortletContext.class);
mockActionProxy.stubs().method("getNamespace").will(returnValue("/view"));
mockActionInvocation.stubs().method("getProxy").will(returnValue(
mockActionProxy.proxy()));
mockPageCtx.stubs().method("getRequest").will(
returnValue(mockHttpReq.proxy()));
mockPageCtx.stubs().method("getResponse").will(
returnValue(mockHttpRes.proxy()));
mockPageCtx.stubs().method("getOut").will(returnValue(mockJspWriter));
mockHttpReq.stubs().method("getScheme").will(returnValue("http"));
mockHttpReq.stubs().method("getAttribute").with(
eq("struts.valueStack")).will(returnValue(stack));
mockHttpReq.stubs().method("getAttribute").with(
eq("javax.portlet.response")).will(
returnValue(mockPortletRes.proxy()));
mockHttpReq.stubs().method("getAttribute").with(
eq("javax.portlet.request")).will(
returnValue(mockPortletReq.proxy()));
mockHttpReq.stubs().method("getAttribute").with(
eq("javax.servlet.include.servlet_path")).will(
returnValue("/servletPath"));
mockHttpReq.stubs().method("getParameterMap").will(
returnValue(Collections.emptyMap()));
mockPortletReq.stubs().method("getPortletMode").will(returnValue(PortletMode.VIEW));
mockPortletReq.stubs().method("getWindowState").will(returnValue(WindowState.NORMAL));
mockPortletReq.stubs().method("getContextPath").will(returnValue("/contextPath"));
tag.setPageContext((PageContext) mockPageCtx.proxy());
Map<PortletMode, String> modeMap = new HashMap<>();
modeMap.put(PortletMode.VIEW, "/view");
modeMap.put(PortletMode.HELP, "/help");
modeMap.put(PortletMode.EDIT, "/edit");
Map<PortletMode, ActionMapping> actionMap = new HashMap<>();
actionMap.put(PortletMode.VIEW, new ActionMapping("defaultView", "/view", "execute", new HashMap<>()));
actionMap.put(PortletMode.HELP, new ActionMapping("defaultHelp", "/help", "execute", new HashMap<>()));
actionMap.put(PortletMode.EDIT, new ActionMapping("defaultEdit", "/edit", "execute", new HashMap<>()));
Map<String, Object> contextMap = stack.getActionContext()
.withSession(new HashMap<>())
.with(PortletConstants.REQUEST, mockPortletReq.proxy())
.with(PortletConstants.RESPONSE, mockPortletRes.proxy())
.with(PortletConstants.PHASE, PortletPhase.RENDER_PHASE)
.with(PortletConstants.MODE_NAMESPACE_MAP, modeMap)
.with(PortletConstants.DEFAULT_ACTION_MAP, actionMap)
.with(STRUTS_PORTLET_CONTEXT, mockCtx.proxy())
.getContextMap();
ActionInvocation ai = (ActionInvocation) mockActionInvocation.proxy();
ActionContext.of(contextMap)
.withValueStack(stack)
.withContainer(dispatcher.getContainer())
.withActionInvocation(ai)
.bind();
}
public void tearDown() throws Exception {
super.tearDown();
if (dispatcher != null && dispatcher.getConfigurationManager() != null) {
dispatcher.cleanup();
dispatcher = null;
}
}
public void testEnsureParamsAreStringArrays() {
Map<String, Object> params = new HashMap<>();
params.put("param1", "Test1");
params.put("param2", new String[]{"Test2"});
Map<String, String[]> result = PortletUrlHelper.ensureParamsAreStringArrays(params);
assertEquals(2, result.size());
assertNotNull(result.get("param1"));
}
public void testSetWindowState() throws Exception {
PortletMode mode = PortletMode.VIEW;
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("createRenderURL").will(
returnValue(mockPortletUrl.proxy()));
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
Map<String, Object> paramMap = new HashMap<>();
paramMap.put(PortletConstants.ACTION_PARAM, new String[]{"/view/testAction"});
paramMap.put(PortletConstants.MODE_PARAM, new String[]{mode.toString()});
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.MAXIMIZED));
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.VIEW));
tag.setAction("testAction");
tag.setWindowState("maximized");
tag.doStartTag();
tag.doEndTag();
}
public void testSetPortletMode() throws Exception {
PortletMode mode = PortletMode.HELP;
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("createRenderURL").will(
returnValue(mockPortletUrl.proxy()));
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
Map<String, Object> paramMap = new HashMap<>();
paramMap.put(PortletConstants.ACTION_PARAM, new String[]{"/help/testAction"});
paramMap.put(PortletConstants.MODE_PARAM, new String[]{mode.toString()});
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.HELP));
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
tag.setNamespace("/help");
tag.setAction("testAction");
tag.setPortletMode("help");
tag.doStartTag();
tag.doEndTag();
}
public void testWhenPortletModeDiffersFromCurrentAndNoParametersAreSetRenderTheDefaults()
throws Exception {
PortletMode mode = PortletMode.HELP;
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("createRenderURL").will(
returnValue(mockPortletUrl.proxy()));
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
Map<String, Object> paramMap = new HashMap<>();
paramMap.put(PortletConstants.ACTION_PARAM, new String[]{"/help/defaultHelp"});
paramMap.put(PortletConstants.MODE_PARAM, new String[]{mode.toString()});
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.HELP));
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
tag.setPortletMode("help");
tag.doStartTag();
tag.doEndTag();
}
public void testUrlWithQueryParams() throws Exception {
PortletMode mode = PortletMode.VIEW;
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("createRenderURL").will(
returnValue(mockPortletUrl.proxy()));
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
Map<String, Object> paramMap = new HashMap<>();
paramMap.put(PortletConstants.ACTION_PARAM, new String[]{"/view/testAction"});
paramMap.put("testParam1", new String[]{"testValue1"});
paramMap.put(PortletConstants.MODE_PARAM, new String[]{mode.toString()});
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.VIEW));
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
tag.setAction("testAction?testParam1=testValue1");
tag.doStartTag();
tag.doEndTag();
}
public void testActionUrl() throws Exception {
PortletMode mode = PortletMode.VIEW;
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("createActionURL").will(
returnValue(mockPortletUrl.proxy()));
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
Map<String, Object> paramMap = new HashMap<>();
paramMap.put(PortletConstants.ACTION_PARAM, new String[]{"/view/testAction"});
paramMap.put(PortletConstants.MODE_PARAM, new String[]{mode.toString()});
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.VIEW));
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
tag.setNamespace("/view");
tag.setAction("testAction");
tag.setPortletUrlType("action");
tag.doStartTag();
tag.doEndTag();
}
public void testResourceUrl() throws Exception {
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("encodeURL").will(returnValue("/contextPath/image.gif"));
mockJspWriter.setExpectedData("/contextPath/image.gif");
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
tag.setValue("image.gif");
tag.doStartTag();
tag.doEndTag();
mockJspWriter.verify();
}
public void testResourceUrlWithNestedParam() throws Exception {
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("encodeURL").with(eq("/contextPath/image.gif?testParam1=testValue1")).will(returnValue("/contextPath/image.gif?testParam1=testValue1"));
mockJspWriter.setExpectedData("/contextPath/image.gif?testParam1=testValue1");
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
ParamTag paramTag = new ParamTag();
paramTag.setPageContext((PageContext) mockPageCtx.proxy());
paramTag.setParent(tag);
paramTag.setName("testParam1");
paramTag.setValue("'testValue1'");
tag.setValue("image.gif");
tag.doStartTag();
paramTag.doStartTag();
paramTag.doEndTag();
tag.doEndTag();
mockJspWriter.verify();
}
public void testResourceUrlWithTwoNestedParam() throws Exception {
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("encodeURL").with(eq("/contextPath/image.gif?testParam1=testValue1&testParam2=testValue2")).will(returnValue("/contextPath/image.gif?testParam1=testValue1&testParam2=testValue2"));
mockJspWriter.setExpectedData("/contextPath/image.gif?testParam1=testValue1&testParam2=testValue2");
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
ParamTag paramTag = new ParamTag();
paramTag.setPageContext((PageContext) mockPageCtx.proxy());
paramTag.setParent(tag);
paramTag.setName("testParam1");
paramTag.setValue("'testValue1'");
ParamTag paramTag2 = new ParamTag();
paramTag2.setPageContext((PageContext) mockPageCtx.proxy());
paramTag2.setParent(tag);
paramTag2.setName("testParam2");
paramTag2.setValue("'testValue2'");
tag.setValue("image.gif");
tag.doStartTag();
paramTag.doStartTag();
paramTag.doEndTag();
paramTag2.doStartTag();
paramTag2.doEndTag();
tag.doEndTag();
mockJspWriter.verify();
}
public void testUrlWithMethod() throws Exception {
PortletMode mode = PortletMode.VIEW;
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("createRenderURL").will(
returnValue(mockPortletUrl.proxy()));
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
tag.setAction("testAction");
Map<String, Object> paramMap = new HashMap<>();
paramMap.put(PortletConstants.ACTION_PARAM, new String[]{"/view/testAction!input"});
paramMap.put(PortletConstants.MODE_PARAM, new String[]{mode.toString()});
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.VIEW));
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
tag.setMethod("input");
tag.doStartTag();
tag.doEndTag();
}
public void testUrlWithNoActionOrMethod() throws Exception {
PortletMode mode = PortletMode.VIEW;
mockHttpReq.stubs().method("getQueryString").will(returnValue(""));
mockPortletRes.expects(once()).method("createRenderURL").will(
returnValue(mockPortletUrl.proxy()));
mockCtx.expects(atLeastOnce()).method("getMajorVersion").will(returnValue(1));
Map<String, Object> paramMap = new HashMap<>();
mockActionProxy.stubs().method("getActionName").will(returnValue("currentExecutingAction"));
paramMap.put(PortletConstants.ACTION_PARAM, new String[]{"/view/currentExecutingAction"});
paramMap.put(PortletConstants.MODE_PARAM, new String[]{mode.toString()});
mockPortletUrl.expects(once()).method("setParameters").with(new ParamMapConstraint(paramMap));
mockPortletUrl.expects(once()).method("setPortletMode").with(eq(PortletMode.VIEW));
mockPortletUrl.expects(once()).method("setWindowState").with(eq(WindowState.NORMAL));
tag.doStartTag();
tag.doEndTag();
}
private static class ParamMapConstraint implements Constraint {
private Map<String, Object> myExpectedMap;
private Map<String, Object> myActualMap = null;
public ParamMapConstraint(Map<String, Object> expectedMap) {
if (expectedMap == null) {
throw new IllegalArgumentException("Use an isNull constraint instead!");
}
myExpectedMap = expectedMap;
}
/* (non-Javadoc)
* @see org.jmock.core.Constraint#eval(java.lang.Object)
*/
public boolean eval(Object val) {
myActualMap = (Map<String, Object>) val;
boolean result = false;
if (val != null) {
if (myExpectedMap.size() == myActualMap.size()) {
Iterator<String> keys = myExpectedMap.keySet().iterator();
boolean allSame = true;
while (keys.hasNext()) {
Object key = keys.next();
if (!myActualMap.containsKey(key)) {
allSame = false;
break;
} else {
String[] expected = (String[]) myExpectedMap.get(key);
String[] actual = (String[]) myActualMap.get(key);
if (!Arrays.equals(expected, actual)) {
allSame = false;
break;
}
}
}
result = allSame;
}
}
return result;
}
/* (non-Javadoc)
* @see org.jmock.core.SelfDescribing#describeTo(java.lang.StringBuffer)
*/
public StringBuffer describeTo(StringBuffer sb) {
sb.append("\n Expected: ");
describeTo(myExpectedMap, sb);
sb.append("\n Actual: ");
describeTo(myActualMap, sb);
return sb;
}
private StringBuffer describeTo(Map<String, Object> map, StringBuffer sb) {
Iterator<String> it = map.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
sb.append(key).append("=");
String[] value = (String[]) map.get(key);
sb.append(value[0]);
if (it.hasNext()) {
sb.append(", ");
}
}
return sb;
}
}
}