/* * Copyright (c) 2010-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.server.service; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import org.eurekastreams.commons.actions.AuthorizationStrategy; import org.eurekastreams.commons.actions.ExecutionStrategy; import org.eurekastreams.commons.actions.TaskHandlerAction; import org.eurekastreams.commons.actions.TaskHandlerExecutionStrategy; import org.eurekastreams.commons.actions.ValidationStrategy; 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.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.GeneralException; import org.eurekastreams.commons.exceptions.InvalidActionException; import org.eurekastreams.commons.exceptions.ValidationException; import org.eurekastreams.commons.server.TransactionManagerFake; import org.eurekastreams.commons.server.UserActionRequest; import org.eurekastreams.commons.task.TaskHandler; import org.jmock.Expectations; import org.jmock.Mockery; import org.jmock.integration.junit4.JUnit4Mockery; import org.jmock.lib.legacy.ClassImposteriser; import org.junit.Before; import org.junit.Test; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; /** * Test class for the ServiceActionController. */ @SuppressWarnings("unchecked") public class ServiceActionControllerTest { /** * Instance of {@link ServiceAction} System Under Test. */ private ServiceActionController sut; /** * Context for building mock objects. */ private final Mockery mockery = new JUnit4Mockery() { { setImposteriser(ClassImposteriser.INSTANCE); } }; /** * Mock of the TransactionManagerFake for testing. */ private final TransactionManagerFake transMgrMock = mockery.mock(TransactionManagerFake.class); /** * instance of a TransactionDefinition. */ private DefaultTransactionDefinition transDef = null; /** * Mocked instance of a TransactionStatus. */ private final TransactionStatus transStatus = mockery.mock(TransactionStatus.class); /** * Mocked instance of the ValidationStrategy for testing. */ private final ValidationStrategy<ServiceActionContext> validationStrategy = mockery.mock(ValidationStrategy.class); /** * Mocked instance of the {@link AuthorizationStrategy for testing. */ private final AuthorizationStrategy<PrincipalActionContext> authorizationStrategy = mockery .mock(AuthorizationStrategy.class); /** * Mocked instance of the {@link ExecutionStrategy} for testing. */ private final ExecutionStrategy<ServiceActionContext> executionStrategy = mockery.mock(ExecutionStrategy.class); /** * Mocked instance of the {@link TaskHandlerExecutionStrategy} for testing. */ private final TaskHandlerExecutionStrategy<ActionContext> taskHandlerExecutionStrategy = mockery .mock(TaskHandlerExecutionStrategy.class); /** * Mocked instance of the {@link ServiceAction} class for testing. */ private final ServiceAction serviceActionMock = mockery.mock(ServiceAction.class); /** * Mocked instance of the {@link TaskHandlerAction} class for testing. */ private final TaskHandlerAction queueSubmitterActionMock = mockery.mock(TaskHandlerAction.class); /** * Mocked instance of the {@link TaskHandler} class. */ private final TaskHandler taskHandlerMock = mockery.mock(TaskHandler.class); /** * Mocked instance of the {@link Principal} class for testing. */ private final Principal principalMock = mockery.mock(Principal.class); /** * Mocked instance of the {@link UserActionRequest} class for testing. */ private final UserActionRequest userActionRequest = mockery.mock(UserActionRequest.class); /** * Setup the test fixture. */ @Before public void setUp() { sut = new ServiceActionController(transMgrMock); transDef = new DefaultTransactionDefinition(); mockery.checking(new Expectations() { { allowing(principalMock).getAccountId(); will(returnValue("someuser")); } }); } /** * Sets up expectations for service actions. */ private void expectServiceAction() { mockery.checking(new Expectations() { { allowing(serviceActionMock).getValidationStrategy(); will(returnValue(validationStrategy)); allowing(serviceActionMock).getAuthorizationStrategy(); will(returnValue(authorizationStrategy)); allowing(serviceActionMock).getExecutionStrategy(); will(returnValue(executionStrategy)); } }); } /** * Sets up expectations for task handler service actions. */ private void expectTaskHandlerServiceAction() { mockery.checking(new Expectations() { { allowing(queueSubmitterActionMock).getValidationStrategy(); will(returnValue(validationStrategy)); allowing(queueSubmitterActionMock).getAuthorizationStrategy(); will(returnValue(authorizationStrategy)); allowing(queueSubmitterActionMock).getExecutionStrategy(); will(returnValue(taskHandlerExecutionStrategy)); allowing(queueSubmitterActionMock).getTaskHandler(); will(returnValue(taskHandlerMock)); } }); } /** * Test the execution of the ServiceActionController with just a service Action. */ @Test public void testExecuteWithServiceAction() { Serializable params = null; final ServiceActionContext serviceActionContext = new ServiceActionContext(params, principalMock); transDef.setReadOnly(true); setupTransactionContext(true, serviceActionContext, false); sut.execute(serviceActionContext, serviceActionMock); mockery.assertIsSatisfied(); } /** * Test the execution of the ServiceActionController with just a service Action. */ @Test(expected = GeneralException.class) public void testExecuteWithServiceActionFailure() { Serializable params = null; final ServiceActionContext serviceActionContext = new ServiceActionContext(params, principalMock); transDef.setReadOnly(true); setupTransactionContext(true, serviceActionContext, true); mockery.checking(new Expectations() { { oneOf(transStatus).isCompleted(); will(returnValue(false)); oneOf(transMgrMock).rollback(transStatus); } }); sut.execute(serviceActionContext, serviceActionMock); mockery.assertIsSatisfied(); } /** * Test the execution of the ServiceActionController with just a service Action and fail on validation. */ @Test(expected = ValidationException.class) public void testExecuteWithServiceActionValidationFailure() { Serializable params = null; final ServiceActionContext serviceActionContext = new ServiceActionContext(params, principalMock); transDef.setReadOnly(true); expectServiceAction(); mockery.checking(new Expectations() { { allowing(serviceActionMock).isReadOnly(); will(returnValue(true)); oneOf(transMgrMock).getTransaction(transDef); will(returnValue(transStatus)); oneOf(validationStrategy).validate(serviceActionContext); will(throwException(new ValidationException())); oneOf(transStatus).isCompleted(); will(returnValue(false)); oneOf(transMgrMock).rollback(transStatus); } }); sut.execute(serviceActionContext, serviceActionMock); mockery.assertIsSatisfied(); } /** * Test the execution of the ServiceActionController with just a service Action and fail on authorization. */ @Test(expected = AuthorizationException.class) public void testExecuteWithServiceActionAuthorizationFailure() { Serializable params = null; final ServiceActionContext serviceActionContext = new ServiceActionContext(params, principalMock); transDef.setReadOnly(true); expectServiceAction(); mockery.checking(new Expectations() { { allowing(serviceActionMock).isReadOnly(); will(returnValue(true)); oneOf(transMgrMock).getTransaction(transDef); will(returnValue(transStatus)); oneOf(validationStrategy).validate(serviceActionContext); oneOf(authorizationStrategy).authorize(serviceActionContext); will(throwException(new AuthorizationException())); oneOf(transStatus).isCompleted(); will(returnValue(false)); oneOf(transMgrMock).rollback(transStatus); } }); sut.execute(serviceActionContext, serviceActionMock); mockery.assertIsSatisfied(); } /** * Test the execution of the ServiceActionController with just a service Action and fail on execution. */ @Test(expected = ExecutionException.class) public void testExecuteWithServiceActionExecutionFailure() { Serializable params = null; final ServiceActionContext serviceActionContext = new ServiceActionContext(params, principalMock); transDef.setReadOnly(true); expectServiceAction(); mockery.checking(new Expectations() { { allowing(serviceActionMock).isReadOnly(); will(returnValue(true)); oneOf(transMgrMock).getTransaction(transDef); will(returnValue(transStatus)); oneOf(validationStrategy).validate(serviceActionContext); oneOf(authorizationStrategy).authorize(serviceActionContext); oneOf(executionStrategy).execute(serviceActionContext); will(throwException(new ExecutionException())); oneOf(transStatus).isCompleted(); will(returnValue(false)); oneOf(transMgrMock).rollback(transStatus); } }); sut.execute(serviceActionContext, serviceActionMock); mockery.assertIsSatisfied(); } /** * Test the failure path of the {@link TaskHandlerAction}. * * @throws Exception * on error. */ @Test(expected = GeneralException.class) public void testExecuteWithQueueServiceActionFailure() throws Exception { final ServiceActionContext serviceActionContext = mockery.mock(ServiceActionContext.class); transDef.setReadOnly(false); final List<UserActionRequest> requests = new ArrayList<UserActionRequest>(); requests.add(userActionRequest); final TaskHandlerActionContext<ServiceActionContext> taskHandlerActionContextMock = mockery .mock(TaskHandlerActionContext.class); setupTaskHandlerTransactionContext(false, taskHandlerActionContextMock, true); mockery.checking(new Expectations() { { oneOf(transStatus).isCompleted(); will(returnValue(false)); oneOf(transMgrMock).rollback(transStatus); } }); sut.execute(serviceActionContext, queueSubmitterActionMock); mockery.assertIsSatisfied(); } /** * Test the validation failure path of the {@link TaskHandlerAction}. * * @throws Exception * on error. */ @Test(expected = ValidationException.class) public void testExecuteWithQueueServiceActionValidationFailure() throws Exception { final ServiceActionContext serviceActionContext = mockery.mock(ServiceActionContext.class); transDef.setReadOnly(false); final List<UserActionRequest> requests = new ArrayList<UserActionRequest>(); requests.add(userActionRequest); expectTaskHandlerServiceAction(); mockery.checking(new Expectations() { { allowing(queueSubmitterActionMock).isReadOnly(); will(returnValue(false)); oneOf(transMgrMock).getTransaction(transDef); will(returnValue(transStatus)); oneOf(validationStrategy).validate(with(any(ServiceActionContext.class))); will(throwException(new ValidationException())); oneOf(transStatus).isCompleted(); will(returnValue(false)); oneOf(transMgrMock).rollback(transStatus); } }); sut.execute(serviceActionContext, queueSubmitterActionMock); mockery.assertIsSatisfied(); } /** * Test the validation failure path of the {@link TaskHandlerAction}. * * @throws Exception * on error. */ @Test(expected = AuthorizationException.class) public void testExecuteWithQueueServiceActionAuthorizationFailure() throws Exception { final ServiceActionContext serviceActionContext = mockery.mock(ServiceActionContext.class); transDef.setReadOnly(false); final List<UserActionRequest> requests = new ArrayList<UserActionRequest>(); requests.add(userActionRequest); expectTaskHandlerServiceAction(); mockery.checking(new Expectations() { { allowing(queueSubmitterActionMock).isReadOnly(); will(returnValue(false)); oneOf(transMgrMock).getTransaction(transDef); will(returnValue(transStatus)); oneOf(validationStrategy).validate(with(any(ServiceActionContext.class))); oneOf(authorizationStrategy).authorize(with(any(ServiceActionContext.class))); will(throwException(new AuthorizationException())); oneOf(transStatus).isCompleted(); will(returnValue(false)); oneOf(transMgrMock).rollback(transStatus); } }); sut.execute(serviceActionContext, queueSubmitterActionMock); mockery.assertIsSatisfied(); } /** * Test the validation failure path of the {@link TaskHandlerAction}. * * @throws Exception * on error. */ @Test(expected = ExecutionException.class) public void testExecuteWithQueueServiceActionExecutionFailure() throws Exception { final ServiceActionContext serviceActionContext = mockery.mock(ServiceActionContext.class); transDef.setReadOnly(false); final List<UserActionRequest> requests = new ArrayList<UserActionRequest>(); requests.add(userActionRequest); expectTaskHandlerServiceAction(); mockery.checking(new Expectations() { { allowing(queueSubmitterActionMock).isReadOnly(); will(returnValue(false)); oneOf(transMgrMock).getTransaction(transDef); will(returnValue(transStatus)); oneOf(validationStrategy).validate(with(any(ServiceActionContext.class))); oneOf(authorizationStrategy).authorize(with(any(ServiceActionContext.class))); oneOf(taskHandlerExecutionStrategy).execute(with(any(TaskHandlerActionContext.class))); will(throwException(new ExecutionException())); oneOf(transStatus).isCompleted(); will(returnValue(false)); oneOf(transMgrMock).rollback(transStatus); } }); sut.execute(serviceActionContext, queueSubmitterActionMock); mockery.assertIsSatisfied(); } /** * Test the sucessful path of the {@link TaskHandlerAction}. * * @throws Exception * on error. */ @Test public void testExecuteWithQueueServiceAction() throws Exception { final ServiceActionContext serviceActionContext = mockery.mock(ServiceActionContext.class); transDef.setReadOnly(false); final List<UserActionRequest> requests = new ArrayList<UserActionRequest>(); requests.add(userActionRequest); final TaskHandlerActionContext<ServiceActionContext> taskHandlerActionContextMock = mockery .mock(TaskHandlerActionContext.class); setupTaskHandlerTransactionContext(false, taskHandlerActionContextMock, false); sut.execute(serviceActionContext, queueSubmitterActionMock); mockery.assertIsSatisfied(); } /** * Helper method. * * @param isReadOnlyTransaction * - flag for setting the readonly transaction * @param inContext * - {@link ServiceActionContext} for the current test. * @param throwsException * - flag for whether or not to throw an exception within the trans. */ private void setupTransactionContext(final boolean isReadOnlyTransaction, final ServiceActionContext inContext, final boolean throwsException) { expectServiceAction(); mockery.checking(new Expectations() { { allowing(serviceActionMock).isReadOnly(); will(returnValue(isReadOnlyTransaction)); oneOf(transMgrMock).getTransaction(transDef); will(returnValue(transStatus)); oneOf(validationStrategy).validate(inContext); oneOf(authorizationStrategy).authorize(inContext); oneOf(executionStrategy).execute(inContext); if (throwsException) { oneOf(transMgrMock).commit(transStatus); will(throwException(new Exception())); } else { oneOf(transMgrMock).commit(transStatus); } } }); } /** * Helper method. * * @param isReadOnlyTransaction * - flag for setting the readonly transaction * @param inContext * - {@link TaskHandlerActionContext} for the current test. * @param throwsException * - flag for whether or not to throw an exception within the trans. */ private void setupTaskHandlerTransactionContext(final boolean isReadOnlyTransaction, final TaskHandlerActionContext inContext, final boolean throwsException) { expectTaskHandlerServiceAction(); mockery.checking(new Expectations() { { allowing(queueSubmitterActionMock).isReadOnly(); will(returnValue(isReadOnlyTransaction)); oneOf(transMgrMock).getTransaction(transDef); will(returnValue(transStatus)); oneOf(validationStrategy).validate(with(any(ServiceActionContext.class))); oneOf(authorizationStrategy).authorize(with(any(ServiceActionContext.class))); oneOf(taskHandlerExecutionStrategy).execute(with(any(TaskHandlerActionContext.class))); if (throwsException) { oneOf(transMgrMock).commit(transStatus); will(throwException(new Exception())); } else { oneOf(transMgrMock).commit(transStatus); } } }); } // ===== Missing strategy tests ===== /** * Test. */ @Test(expected = InvalidActionException.class) public void testExecuteMissingValidation() { ServiceAction action = new ServiceAction(null, authorizationStrategy, executionStrategy, false); final ServiceActionContext context = new ServiceActionContext(null, principalMock); sut.execute(context, action); mockery.assertIsSatisfied(); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testExecuteMissingAuthorization() { ServiceAction action = new ServiceAction(validationStrategy, null, executionStrategy, false); final ServiceActionContext context = new ServiceActionContext(null, principalMock); sut.execute(context, action); mockery.assertIsSatisfied(); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testExecuteMissingExecution() { ServiceAction action = new ServiceAction(validationStrategy, authorizationStrategy, null, false); final ServiceActionContext context = new ServiceActionContext(null, principalMock); sut.execute(context, action); mockery.assertIsSatisfied(); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testExecuteTHMissingValidation() { TaskHandlerAction action = new TaskHandlerServiceAction(null, authorizationStrategy, taskHandlerExecutionStrategy, taskHandlerMock, false); sut.execute(new ServiceActionContext(null, principalMock), action); mockery.assertIsSatisfied(); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testExecuteTHMissingAuthorization() { TaskHandlerAction action = new TaskHandlerServiceAction(validationStrategy, null, taskHandlerExecutionStrategy, taskHandlerMock, false); sut.execute(new ServiceActionContext(null, principalMock), action); mockery.assertIsSatisfied(); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testExecuteTHMissingExecution() { TaskHandlerAction action = new TaskHandlerServiceAction(validationStrategy, authorizationStrategy, null, taskHandlerMock, false); sut.execute(new ServiceActionContext(null, principalMock), action); mockery.assertIsSatisfied(); } /** * Test. */ @Test(expected = InvalidActionException.class) public void testExecuteTHMissingTaskHandler() { TaskHandlerAction action = new TaskHandlerServiceAction(validationStrategy, authorizationStrategy, taskHandlerExecutionStrategy, null, false); sut.execute(new ServiceActionContext(null, principalMock), action); mockery.assertIsSatisfied(); } }