| /* |
| * 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.junit; |
| |
| import com.opensymphony.xwork2.ActionContext; |
| import com.opensymphony.xwork2.ActionProxy; |
| import com.opensymphony.xwork2.ActionProxyFactory; |
| import com.opensymphony.xwork2.config.Configuration; |
| import com.opensymphony.xwork2.interceptor.ValidationAware; |
| import com.opensymphony.xwork2.interceptor.annotations.After; |
| import com.opensymphony.xwork2.interceptor.annotations.Before; |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.struts2.ServletActionContext; |
| import org.apache.struts2.dispatcher.Dispatcher; |
| import org.apache.struts2.dispatcher.HttpParameters; |
| import org.apache.struts2.dispatcher.mapper.ActionMapper; |
| import org.apache.struts2.dispatcher.mapper.ActionMapping; |
| import org.apache.struts2.util.StrutsTestCaseHelper; |
| import org.springframework.core.io.DefaultResourceLoader; |
| import org.springframework.mock.web.MockHttpServletRequest; |
| import org.springframework.mock.web.MockHttpServletResponse; |
| import org.springframework.mock.web.MockHttpSession; |
| import org.springframework.mock.web.MockPageContext; |
| import org.springframework.mock.web.MockServletContext; |
| |
| import javax.servlet.ServletException; |
| import javax.servlet.http.HttpServletRequest; |
| import javax.servlet.http.HttpServletResponse; |
| import javax.servlet.http.HttpSession; |
| import java.io.UnsupportedEncodingException; |
| import java.util.Enumeration; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| import static org.junit.Assert.assertNotNull; |
| |
| public abstract class StrutsJUnit4TestCase<T> extends XWorkJUnit4TestCase { |
| |
| protected MockHttpServletResponse response; |
| protected MockHttpServletRequest request; |
| protected MockPageContext pageContext; |
| protected MockServletContext servletContext; |
| protected Map<String, String> dispatcherInitParams; |
| protected Dispatcher dispatcher; |
| |
| protected DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); |
| |
| /** |
| * gets an object from the stack after an action is executed |
| */ |
| protected Object findValueAfterExecute(String key) { |
| return ServletActionContext.getValueStack(request).findValue(key); |
| } |
| |
| /** |
| * gets an object from the stack after an action is executed |
| * |
| * @return The executed action |
| */ |
| @SuppressWarnings("unchecked") |
| protected T getAction() { |
| return (T) findValueAfterExecute("action"); |
| } |
| |
| protected boolean containsErrors() { |
| T action = this.getAction(); |
| if (action instanceof ValidationAware) { |
| return ((ValidationAware) action).hasActionErrors(); |
| } |
| throw new UnsupportedOperationException("Current action does not implement ValidationAware interface"); |
| } |
| |
| /** |
| * Executes an action and returns it's output (not the result returned from |
| * execute()), but the actual output that would be written to the response. |
| * For this to work the configured result for the action needs to be |
| * FreeMarker, or Velocity (JSPs can be used with the Embedded JSP plugin) |
| */ |
| protected String executeAction(String uri) throws ServletException, UnsupportedEncodingException { |
| request.setRequestURI(uri); |
| ActionMapping mapping = getActionMapping(request); |
| |
| assertNotNull(mapping); |
| Dispatcher.getInstance().serviceAction(request, response, mapping); |
| |
| if (response.getStatus() != HttpServletResponse.SC_OK) |
| throw new ServletException("Error code [" + response.getStatus() + "], Error: [" |
| + response.getErrorMessage() + "]"); |
| |
| return response.getContentAsString(); |
| } |
| |
| /** |
| * Creates an action proxy for a request, and sets parameters of the ActionInvocation to the passed |
| * parameters. Make sure to set the request parameters in the protected "request" object before calling this method. |
| */ |
| protected ActionProxy getActionProxy(String uri) { |
| request.setRequestURI(uri); |
| ActionMapping mapping = getActionMapping(request); |
| String namespace = mapping.getNamespace(); |
| String name = mapping.getName(); |
| String method = mapping.getMethod(); |
| |
| Configuration config = configurationManager.getConfiguration(); |
| ActionProxy proxy = config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy( |
| namespace, name, method, new HashMap<String, Object>(), true, false); |
| |
| initActionContext(proxy.getInvocation().getInvocationContext()); |
| |
| // this is normally done in onSetUp(), but we are using Struts internal |
| // objects (proxy and action invocation) |
| // so we have to hack around so it works |
| ServletActionContext.setServletContext(servletContext); |
| ServletActionContext.setRequest(request); |
| ServletActionContext.setResponse(response); |
| |
| ServletActionContext.getContext().put(ServletActionContext.ACTION_MAPPING, mapping); |
| |
| return proxy; |
| } |
| |
| protected void initActionContext(ActionContext actionContext) { |
| actionContext.setParameters(HttpParameters.create(request.getParameterMap()).build()); |
| initSession(actionContext); |
| // set the action context to the one used by the proxy |
| ActionContext.bind(actionContext); |
| } |
| |
| protected void initSession(ActionContext actionContext) { |
| if (actionContext.getSession() == null) { |
| actionContext.withSession(new HashMap<>()); |
| request.setSession(new MockHttpSession(servletContext)); |
| } |
| } |
| |
| /** |
| * Finds an ActionMapping for a given request |
| */ |
| protected ActionMapping getActionMapping(HttpServletRequest request) { |
| return container.getInstance(ActionMapper.class).getMapping(request, configurationManager); |
| } |
| |
| /** |
| * Finds an ActionMapping for a given url |
| */ |
| protected ActionMapping getActionMapping(String url) { |
| MockHttpServletRequest req = new MockHttpServletRequest(); |
| req.setRequestURI(url); |
| return getActionMapping(req); |
| } |
| |
| /** |
| * Injects dependencies on an Object using Struts internal IoC container |
| */ |
| protected void injectStrutsDependencies(Object object) { |
| container.inject(object); |
| } |
| |
| protected void setupBeforeInitDispatcher() throws Exception { |
| } |
| |
| protected void initServletMockObjects() { |
| servletContext = new MockServletContext(resourceLoader); |
| response = new MockHttpServletResponse(); |
| request = new MockHttpServletRequest(); |
| pageContext = new MockPageContext(servletContext, request, response); |
| } |
| |
| public void finishExecution() { |
| HttpSession session = this.request.getSession(); |
| Enumeration attributeNames = session.getAttributeNames(); |
| |
| MockHttpServletRequest nextRequest = new MockHttpServletRequest(); |
| |
| while (attributeNames.hasMoreElements()) { |
| String key = (String) attributeNames.nextElement(); |
| Object attribute = session.getAttribute(key); |
| nextRequest.getSession().setAttribute(key, attribute); |
| } |
| |
| this.response = new MockHttpServletResponse(); |
| this.request = nextRequest; |
| this.pageContext = new MockPageContext(servletContext, request, response); |
| } |
| |
| /** |
| * Sets up the configuration settings, XWork configuration, and |
| * message resources |
| */ |
| @Before |
| public void setUp() throws Exception { |
| super.setUp(); |
| initServletMockObjects(); |
| setupBeforeInitDispatcher(); |
| initDispatcherParams(); |
| initDispatcher(dispatcherInitParams); |
| } |
| |
| protected void initDispatcherParams() { |
| if (StringUtils.isNotBlank(getConfigPath())) { |
| dispatcherInitParams = new HashMap<>(); |
| dispatcherInitParams.put("config", "struts-default.xml," + getConfigPath()); |
| } |
| } |
| |
| protected Dispatcher initDispatcher(Map<String, String> params) { |
| dispatcher = StrutsTestCaseHelper.initDispatcher(servletContext, params); |
| configurationManager = dispatcher.getConfigurationManager(); |
| configuration = configurationManager.getConfiguration(); |
| container = configuration.getContainer(); |
| container.inject(dispatcher); |
| return dispatcher; |
| } |
| |
| /** |
| * Override this method to return a comma separated list of paths to a configuration |
| * file. |
| * <p>The default implementation simply returns <code>null</code>. |
| * |
| * @return a comma separated list of config locations |
| */ |
| protected String getConfigPath() { |
| return null; |
| } |
| |
| @After |
| public void tearDown() throws Exception { |
| super.tearDown(); |
| if (dispatcher != null && dispatcher.getConfigurationManager() != null) { |
| dispatcher.cleanup(); |
| dispatcher = null; |
| } |
| StrutsTestCaseHelper.tearDown(); |
| } |
| |
| } |