package org.apache.struts2.rest; import com.opensymphony.xwork2.ActionContext; import com.opensymphony.xwork2.DefaultUnknownHandlerManager; import com.opensymphony.xwork2.ModelDriven; import com.opensymphony.xwork2.ObjectFactory; import com.opensymphony.xwork2.config.ConfigurationException; import com.opensymphony.xwork2.config.entities.ActionConfig; import com.opensymphony.xwork2.config.entities.InterceptorMapping; import com.opensymphony.xwork2.config.entities.ResultConfig; import com.opensymphony.xwork2.mock.MockActionProxy; import com.opensymphony.xwork2.mock.MockInterceptor; import com.opensymphony.xwork2.util.XWorkTestCaseHelper; import junit.framework.TestCase; import org.apache.struts2.ServletActionContext; import org.apache.struts2.dispatcher.HttpHeaderResult; import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletResponse; import javax.servlet.http.HttpServletResponse; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import static javax.servlet.http.HttpServletResponse.SC_NOT_MODIFIED; public class RestActionInvocationTest extends TestCase { RestActionInvocation restActionInvocation; MockHttpServletRequest request; MockHttpServletResponse response; @Override protected void setUp() throws Exception { super.setUp(); restActionInvocation = new RestActionInvocationTester(); request = new MockHttpServletRequest(); response = new MockHttpServletResponse(); ServletActionContext.setRequest(request); ServletActionContext.setResponse(response); } /** * Test the correct action results: null, String, HttpHeaders, Result * @throws Exception */ public void testSaveResult() throws Exception { Object methodResult = "index"; ActionConfig actionConfig = restActionInvocation.getProxy().getConfig(); assertEquals("index", restActionInvocation.saveResult(actionConfig, methodResult)); setUp(); methodResult = new DefaultHttpHeaders("show"); assertEquals("show", restActionInvocation.saveResult(actionConfig, methodResult)); assertEquals(methodResult, restActionInvocation.httpHeaders); setUp(); methodResult = new HttpHeaderResult(HttpServletResponse.SC_ACCEPTED); assertEquals(null, restActionInvocation.saveResult(actionConfig, methodResult)); assertEquals(methodResult, restActionInvocation.createResult()); setUp(); try { methodResult = new Object(); restActionInvocation.saveResult(actionConfig, methodResult); // ko assertFalse(true); } catch (ConfigurationException c) { // ok, object not allowed } } /** * Test the target selection: exception, error messages, model and null * @throws Exception */ public void testSelectTarget() throws Exception { // Exception Exception e = new Exception(); restActionInvocation.getStack().set("exception", e); restActionInvocation.selectTarget(); assertEquals(e, restActionInvocation.target); // Error messages setUp(); String actionMessage = "Error!"; RestActionSupport action = (RestActionSupport)restActionInvocation.getAction(); action.addActionError(actionMessage); Map<String, Object> errors = new HashMap<String, Object>(); List<String> list = new ArrayList<String>(); list.add(actionMessage); errors.put("actionErrors", list); restActionInvocation.selectTarget(); assertEquals(errors, restActionInvocation.target); // Model with get and no content in post, put, delete setUp(); RestAction restAction = (RestAction)restActionInvocation.getAction(); List<String> model = new ArrayList<String>(); model.add("Item"); restAction.model = model; request.setMethod("GET"); restActionInvocation.selectTarget(); assertEquals(model, restActionInvocation.target); request.setMethod("POST"); restActionInvocation.selectTarget(); assertEquals(null, restActionInvocation.target); request.setMethod("PUT"); restActionInvocation.selectTarget(); assertEquals(null, restActionInvocation.target); request.setMethod("DELETE"); restActionInvocation.selectTarget(); assertEquals(null, restActionInvocation.target); // disable content restriction to GET only model = new ArrayList<String>(); model.add("Item1"); restAction.model = model; request.setMethod("POST"); restActionInvocation.setRestrictToGet("false"); restActionInvocation.selectTarget(); assertEquals(model, restActionInvocation.target); assertEquals(model.get(0), "Item1"); } /** * Test the not modified status code. * @throws Exception */ public void testResultNotModified() throws Exception { request.addHeader("If-None-Match", "123"); request.setMethod("GET"); RestAction restAction = (RestAction)restActionInvocation.getAction(); List<String> model = new ArrayList<String>() { @Override public int hashCode() { return 123; } }; model.add("Item"); restAction.model = model; restActionInvocation.processResult(); assertEquals(SC_NOT_MODIFIED, response.getStatus()); } /** * Test the default error result. * @throws Exception */ public void testDefaultErrorResult() throws Exception { // Exception Exception e = new Exception(); restActionInvocation.getStack().set("exception", e); request.setMethod("GET"); RestAction restAction = (RestAction)restActionInvocation.getAction(); List<String> model = new ArrayList<String>(); model.add("Item"); restAction.model = model; restActionInvocation.setDefaultErrorResultName("default-error"); ResultConfig resultConfig = new ResultConfig.Builder("default-error", "org.apache.struts2.dispatcher.HttpHeaderResult") .addParam("status", "123").build(); ActionConfig actionConfig = new ActionConfig.Builder("org.apache.rest", "RestAction", "org.apache.rest.RestAction") .addResultConfig(resultConfig) .build(); ((MockActionProxy)restActionInvocation.getProxy()).setConfig(actionConfig); restActionInvocation.processResult(); assertEquals(123, response.getStatus()); } public void testNoResult() throws Exception { RestAction restAction = (RestAction)restActionInvocation.getAction(); List<String> model = new ArrayList<String>(); model.add("Item"); restAction.model = model; request.setMethod("GET"); restActionInvocation.setResultCode("index"); try { restActionInvocation.processResult(); // ko assertFalse(true); } catch (ConfigurationException c) { // ok, no result } } /** * Test the global execution * @throws Exception */ public void testInvoke() throws Exception { // Default index method return 'success' ((MockActionProxy)restActionInvocation.getProxy()).setMethod("index"); // Define result 'success' ResultConfig resultConfig = new ResultConfig.Builder("success", "org.apache.struts2.dispatcher.HttpHeaderResult") .addParam("status", "123").build(); ActionConfig actionConfig = new ActionConfig.Builder("org.apache.rest", "RestAction", "org.apache.rest.RestAction") .addResultConfig(resultConfig) .build(); ((MockActionProxy)restActionInvocation.getProxy()).setConfig(actionConfig); request.setMethod("GET"); restActionInvocation.invoke(); assertEquals(123, response.getStatus()); } class RestActionInvocationTester extends RestActionInvocation { RestActionInvocationTester() { super(new HashMap<String, Object>(), true); List<InterceptorMapping> interceptorMappings = new ArrayList<InterceptorMapping>(); MockInterceptor mockInterceptor = new MockInterceptor(); mockInterceptor.setFoo("interceptor"); mockInterceptor.setExpectedFoo("interceptor"); interceptorMappings.add(new InterceptorMapping("interceptor", mockInterceptor)); interceptors = interceptorMappings.iterator(); MockActionProxy actionProxy = new MockActionProxy(); ActionConfig actionConfig = new ActionConfig.Builder("org.apache.rest", "RestAction", "org.apache.rest.RestAction").build(); actionProxy.setConfig(actionConfig); proxy = actionProxy; action = new RestAction(); setMimeTypeHandlerSelector(new DefaultContentTypeHandlerManager()); unknownHandlerManager = new DefaultUnknownHandlerManager(); try { XWorkTestCaseHelper.setUp(); } catch (Exception e) { throw new RuntimeException(e); } invocationContext = ActionContext.getContext(); container = ActionContext.getContext().getContainer(); stack = ActionContext.getContext().getValueStack(); objectFactory = container.getInstance(ObjectFactory.class); } } class RestAction extends RestActionSupport implements ModelDriven<List<String>> { List<String> model; public List<String> getModel() { return model; } } }