/* * Copyright (c) 2011 Lockheed Martin Corporation * * 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 org.eurekastreams.commons.actions; import static org.junit.Assert.assertSame; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.eurekastreams.commons.actions.async.AsyncAction; import org.eurekastreams.commons.actions.async.TaskHandlerAsyncAction; import org.eurekastreams.commons.actions.context.ActionContext; import org.eurekastreams.commons.actions.context.Principal; import org.eurekastreams.commons.actions.context.PrincipalActionContext; import org.eurekastreams.commons.actions.context.TaskHandlerActionContext; import org.eurekastreams.commons.actions.context.TaskHandlerActionContextImpl; import org.eurekastreams.commons.actions.context.async.AsyncActionContext; import org.eurekastreams.commons.actions.context.service.ServiceActionContext; import org.eurekastreams.commons.actions.service.ServiceAction; import org.eurekastreams.commons.actions.service.TaskHandlerServiceAction; import org.eurekastreams.commons.exceptions.AuthorizationException; import org.eurekastreams.commons.exceptions.ExecutionException; import org.eurekastreams.commons.exceptions.InvalidActionException; import org.eurekastreams.commons.exceptions.ValidationException; import org.eurekastreams.commons.server.UserActionRequest; import org.eurekastreams.commons.task.TaskHandler; import org.eurekastreams.commons.test.EasyMatcher; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.api.Invocation; import org.jmock.integration.junit4.JUnit4Mockery; import org.jmock.lib.action.CustomAction; import org.jmock.lib.legacy.ClassImposteriser; import org.junit.Before; import org.junit.Test; /** * Tests InlineActionExecutor. */ @SuppressWarnings({ "unchecked", "rawtypes" }) public class InlineActionExecutorTest { /** Used for mocking objects. */ private final Mockery mockery = new JUnit4Mockery() { { setImposteriser(ClassImposteriser.INSTANCE); } }; /** Fixture: resultValue. */ private final Serializable resultValue = mockery.mock(Serializable.class, "resultValue"); /** Fixture: Validation Strategy. */ private final ValidationStrategy validationStrategy = mockery.mock(ValidationStrategy.class, "validationStrategy"); /** Fixture: Authorization Strategy. */ private final AuthorizationStrategy authorizationStrategy = mockery.mock(AuthorizationStrategy.class, "authorizationStrategy"); /** Fixture: Execution Strategy. */ private final ExecutionStrategy executionStrategy = mockery.mock(ExecutionStrategy.class, "executionStrategy"); /** Fixture: Execution Strategy. */ private final TaskHandlerExecutionStrategy executionStrategyTH = mockery.mock(TaskHandlerExecutionStrategy.class, "executionStrategyTH"); /** * Fixture: task handler. There should be NO expectations defined on this mock so that any attempt to use it causes * a test error. */ private final TaskHandler taskHandler = mockery.mock(TaskHandler.class, "taskHandler"); /** Fixture: userActionRequests. */ private final List<UserActionRequest> userActionRequests = new ArrayList<UserActionRequest>(); /** Fixture: parent context parameter. */ private final Serializable parentParam = mockery.mock(Serializable.class, "parentParam"); /** Fixture: child context parameter. */ private final Serializable childParam = mockery.mock(Serializable.class, "childParam"); /** Fixture: principal. */ private final Principal principal = mockery.mock(Principal.class, "principal"); /** Fixture: user action request. */ private final UserActionRequest userActionRequest = mockery.mock(UserActionRequest.class, "userActionRequest"); /** Action. */ private final Action asyncAction = new AsyncAction(validationStrategy, executionStrategy, false); /** Action. */ private final Action serviceAction = new ServiceAction(validationStrategy, authorizationStrategy, executionStrategy, false); /** Action. */ private final TaskHandlerAction taskHandlerServiceAction = new TaskHandlerServiceAction(validationStrategy, authorizationStrategy, executionStrategyTH, taskHandler, false); /** Action. */ private final TaskHandlerAction taskHandlerAsyncAction = new TaskHandlerAsyncAction(validationStrategy, executionStrategyTH, taskHandler, false); /** Context. */ private ActionContext asyncActionInnerContext; /** Context. */ private ActionContext serviceActionInnerContext; /** Context. */ private ActionContext serviceActionInnerContextNullPrincipal; /** Matcher for checking the context. */ final EasyMatcher<ActionContext> contextMatcher = new EasyMatcher<ActionContext>() { @Override protected boolean isMatch(final ActionContext inTestObject) { return inTestObject.getParams() == childParam; } }; /** Matcher for checking the context with a principal. */ final EasyMatcher<ActionContext> contextWithPrincipalMatcher = new EasyMatcher<ActionContext>() { @Override protected boolean isMatch(final ActionContext inTestObject) { return inTestObject.getParams() == childParam && inTestObject instanceof PrincipalActionContext && ((PrincipalActionContext) inTestObject).getPrincipal() == principal; } }; /** Matcher for checking the context with a null principal. */ final EasyMatcher<ActionContext> contextWithNullPrincipalMatcher = new EasyMatcher<ActionContext>() { @Override protected boolean isMatch(final ActionContext inTestObject) { return inTestObject.getParams() == childParam && inTestObject instanceof PrincipalActionContext && ((PrincipalActionContext) inTestObject).getPrincipal() == null; } }; /** * Setup before each test. */ @Before public void setUp() { asyncActionInnerContext = new AsyncActionContext(parentParam); serviceActionInnerContext = new ServiceActionContext(parentParam, principal); serviceActionInnerContextNullPrincipal = new ServiceActionContext(parentParam, null); userActionRequests.clear(); mockery.checking(new Expectations() { { allowing(principal).getAccountId(); will(returnValue("somebody")); } }); } // ========== TEST HELPERS =========== /** * Set up expectation for a validator being invoked. * * @param notNull * If the principal should not be null. */ private void expectValidatePrincipal(final boolean notNull) { mockery.checking(new Expectations() { { oneOf(validationStrategy).validate( with(notNull ? contextWithPrincipalMatcher : contextWithNullPrincipalMatcher)); } }); } /** * Set up expectation for a validator being invoked. */ private void expectValidate() { mockery.checking(new Expectations() { { oneOf(validationStrategy).validate(with(contextMatcher)); } }); } /** * Set up expectation for an authorizer being invoked. * * @param notNull * If the principal should not be null. */ private void expectAuthorizePrincipal(final boolean notNull) { mockery.checking(new Expectations() { { oneOf(authorizationStrategy).authorize( (PrincipalActionContext) with(notNull ? contextWithPrincipalMatcher : contextWithNullPrincipalMatcher)); } }); } /** * Set up expectation for an execution being invoked. */ private void expectExecute() { mockery.checking(new Expectations() { { oneOf(executionStrategy).execute(with(contextMatcher)); will(returnValue(resultValue)); } }); } /** * Set up expectation for an execution being invoked. * * @param notNull * If the principal should not be null. */ private void expectExecutePrincipal(final boolean notNull) { mockery.checking(new Expectations() { { oneOf(executionStrategy).execute( with(notNull ? contextWithPrincipalMatcher : contextWithNullPrincipalMatcher)); will(returnValue(resultValue)); } }); } /** * Set up expectation for an execution being invoked. * * @param notNull * If the principal should not be null. */ private void expectExecuteTaskHandlerPrincipal(final boolean notNull) { mockery.checking(new Expectations() { { oneOf(executionStrategyTH).execute(with(new EasyMatcher<TaskHandlerActionContext>() { @Override protected boolean isMatch(final TaskHandlerActionContext inTestObject) { return (notNull ? contextWithPrincipalMatcher : contextWithNullPrincipalMatcher) .matches(inTestObject.getActionContext()); } })); will(new CustomAction("execute task handler execution") { @Override public Object invoke(final Invocation inInvocation) throws Throwable { userActionRequests.add(userActionRequest); return resultValue; } }); } }); } /** * Set up expectation for an execution being invoked. */ private void expectExecuteTaskHandler() { mockery.checking(new Expectations() { { oneOf(executionStrategyTH).execute(with(new EasyMatcher<TaskHandlerActionContext>() { @Override protected boolean isMatch(final TaskHandlerActionContext inTestObject) { return contextMatcher.matches(inTestObject.getActionContext()); } })); will(new CustomAction("execute task handler execution") { @Override public Object invoke(final Invocation inInvocation) throws Throwable { userActionRequests.add(userActionRequest); return resultValue; } }); } }); } /** * Core of tests taking a TaskHandlerAction. * * @param externalActionSelection * Choice for creating SUT. * @param action * Action to invoke SUT with. * @param innerContext * Inner context of TaskHandlerActionContext to invoke SUT with. * @param param * Param to invoke SUT with. */ private void coreTest(final boolean externalActionSelection, final TaskHandlerAction action, final ActionContext innerContext, final Serializable param) { InlineActionExecutor sut = new InlineActionExecutor(externalActionSelection); Serializable result = sut.execute(action, new TaskHandlerActionContextImpl(innerContext, userActionRequests), param); mockery.assertIsSatisfied(); assertSame(resultValue, result); } /** * Core of tests taking an Action (non-TaskHandlerAction). * * @param externalActionSelection * Choice for creating SUT. * @param action * Action to invoke SUT with. * @param innerContext * Inner context of TaskHandlerActionContext to invoke SUT with. * @param param * Param to invoke SUT with. */ private void coreTest(final boolean externalActionSelection, final Action action, final ActionContext innerContext, final Serializable param) { InlineActionExecutor sut = new InlineActionExecutor(externalActionSelection); Serializable result = sut.execute(action, new TaskHandlerActionContextImpl(innerContext, userActionRequests), param); mockery.assertIsSatisfied(); assertSame(resultValue, result); } // ========== EXECUTION COMBINATION TESTS ========== // Format for the combination test names: test_<action type>_<inner context type>_<external choice> // * action type: SA=ServiceAction, AA=AsyncAction, THSA=TaskHandlerServiceAction, THAA=TaskHandlerAsyncAction // * inner context type: SAC=ServiceActionContext, SACn=ServiceActionContext w/ null, AAC=AsyncActionContext // * external choice: E=externally selected action, I=internally selected action // ===== EXECUTION COMBINATION TESTS: for a non-task-handler action ===== /** * Test. */ @Test public void testwithSAwithSACwithE() { expectValidatePrincipal(true); expectAuthorizePrincipal(true); expectExecutePrincipal(true); coreTest(true, serviceAction, serviceActionInnerContext, childParam); } /** * Test. */ @Test public void testwithSAwithSACnwithE() { expectValidatePrincipal(false); expectAuthorizePrincipal(false); expectExecutePrincipal(false); coreTest(true, serviceAction, serviceActionInnerContextNullPrincipal, childParam); } /** * Test. */ @Test public void testwithSAwithAACwithE() { expectValidate(); expectExecute(); coreTest(true, serviceAction, asyncActionInnerContext, childParam); } /** * Test. */ @Test public void testwithSAwithSACwithI() { expectValidatePrincipal(true); expectAuthorizePrincipal(true); expectExecutePrincipal(true); coreTest(false, serviceAction, serviceActionInnerContext, childParam); } /** * Test. */ @Test public void testwithSAwithSACnwithI() { expectValidatePrincipal(false); expectAuthorizePrincipal(false); expectExecutePrincipal(false); coreTest(false, serviceAction, serviceActionInnerContextNullPrincipal, childParam); } /** * Test. */ @Test public void testwithSAwithAACwithI() { expectValidate(); expectExecute(); coreTest(false, serviceAction, asyncActionInnerContext, childParam); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testwithAAwithSACwithE() { coreTest(true, asyncAction, serviceActionInnerContext, childParam); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testwithAAwithSACnwithE() { coreTest(true, asyncAction, serviceActionInnerContextNullPrincipal, childParam); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testwithAAwithAACwithE() { coreTest(true, asyncAction, asyncActionInnerContext, childParam); } /** * Test. */ @Test public void testwithAAwithSACwithI() { expectValidate(); expectExecute(); coreTest(false, asyncAction, serviceActionInnerContext, childParam); } /** * Test. */ @Test public void testwithAAwithSACnwithI() { expectValidate(); expectExecute(); coreTest(false, asyncAction, serviceActionInnerContextNullPrincipal, childParam); } /** * Test. */ @Test public void testwithAAwithAACwithI() { expectValidate(); expectExecute(); coreTest(false, asyncAction, asyncActionInnerContext, childParam); } // ===== EXECUTION COMBINATION TESTS: for a task-handler action ===== /** * Test. */ @Test public void testwithTHSAwithSACwithE() { expectValidatePrincipal(true); expectAuthorizePrincipal(true); expectExecuteTaskHandlerPrincipal(true); coreTest(true, taskHandlerServiceAction, serviceActionInnerContext, childParam); } /** * Test. */ @Test public void testwithTHSAwithSACnwithE() { expectValidatePrincipal(false); expectAuthorizePrincipal(false); expectExecuteTaskHandlerPrincipal(false); coreTest(true, taskHandlerServiceAction, serviceActionInnerContextNullPrincipal, childParam); } /** * Test. */ @Test public void testwithTHSAwithAACwithE() { expectValidate(); expectExecuteTaskHandler(); coreTest(true, taskHandlerServiceAction, asyncActionInnerContext, childParam); } /** * Test. */ @Test public void testwithTHSAwithSACwithI() { expectValidatePrincipal(true); expectAuthorizePrincipal(true); expectExecuteTaskHandlerPrincipal(true); coreTest(false, taskHandlerServiceAction, serviceActionInnerContext, childParam); } /** * Test. */ @Test public void testwithTHSAwithSACnwithI() { expectValidatePrincipal(false); expectAuthorizePrincipal(false); expectExecuteTaskHandlerPrincipal(false); coreTest(false, taskHandlerServiceAction, serviceActionInnerContextNullPrincipal, childParam); } /** * Test. */ @Test public void testwithTHSAwithAACwithI() { expectValidate(); expectExecuteTaskHandler(); coreTest(false, taskHandlerServiceAction, asyncActionInnerContext, childParam); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testwithTHAAwithSACwithE() { coreTest(true, taskHandlerAsyncAction, serviceActionInnerContext, childParam); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testwithTHAAwithSACnwithE() { coreTest(true, taskHandlerAsyncAction, serviceActionInnerContextNullPrincipal, childParam); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testwithTHAAwithAACwithE() { coreTest(true, taskHandlerAsyncAction, asyncActionInnerContext, childParam); } /** * Test. */ @Test public void testwithTHAAwithSACwithI() { expectValidate(); expectExecuteTaskHandler(); coreTest(false, taskHandlerAsyncAction, serviceActionInnerContext, childParam); } /** * Test. */ @Test public void testwithTHAAwithSACnwithI() { expectValidate(); expectExecuteTaskHandler(); coreTest(false, taskHandlerAsyncAction, serviceActionInnerContextNullPrincipal, childParam); } /** * Test. */ @Test public void testwithTHAAwithAACwithI() { expectValidate(); expectExecuteTaskHandler(); coreTest(false, taskHandlerAsyncAction, asyncActionInnerContext, childParam); } // ========== EXCEPTION TESTS ========== /** * Test. */ @Test(expected = ValidationException.class) public void testValidationException() { mockery.checking(new Expectations() { { oneOf(validationStrategy).validate(with(contextWithPrincipalMatcher)); will(throwException(new ValidationException("BAD!"))); } }); coreTest(true, serviceAction, serviceActionInnerContext, childParam); mockery.assertIsSatisfied(); } /** * Test. */ @Test(expected = AuthorizationException.class) public void testAuthorizationException() { expectValidatePrincipal(true); mockery.checking(new Expectations() { { oneOf(authorizationStrategy).authorize((PrincipalActionContext) with(contextWithPrincipalMatcher)); will(throwException(new AuthorizationException("BAD!"))); } }); coreTest(true, serviceAction, serviceActionInnerContext, childParam); mockery.assertIsSatisfied(); } /** * Test. */ @Test(expected = ExecutionException.class) public void testExecutionException() { expectValidatePrincipal(true); expectAuthorizePrincipal(true); mockery.checking(new Expectations() { { oneOf(executionStrategy).execute(with(contextWithPrincipalMatcher)); will(throwException(new ExecutionException("BAD!"))); } }); coreTest(true, serviceAction, serviceActionInnerContext, childParam); mockery.assertIsSatisfied(); } }