package org.bonitasoft.console.common.server.form;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.bonitasoft.console.common.server.utils.SessionUtil;
import org.bonitasoft.engine.api.CommandAPI;
import org.bonitasoft.engine.api.ProcessAPI;
import org.bonitasoft.engine.bpm.flownode.ActivityInstance;
import org.bonitasoft.engine.bpm.flownode.ActivityInstanceNotFoundException;
import org.bonitasoft.engine.bpm.flownode.ArchivedActivityInstance;
import org.bonitasoft.engine.bpm.flownode.ArchivedHumanTaskInstance;
import org.bonitasoft.engine.bpm.flownode.HumanTaskInstance;
import org.bonitasoft.engine.bpm.process.ActivationState;
import org.bonitasoft.engine.bpm.process.ArchivedProcessInstance;
import org.bonitasoft.engine.bpm.process.ProcessDeploymentInfo;
import org.bonitasoft.engine.bpm.process.ProcessInstance;
import org.bonitasoft.engine.bpm.process.ProcessInstanceNotFoundException;
import org.bonitasoft.engine.search.SearchOptions;
import org.bonitasoft.engine.search.SearchResult;
import org.bonitasoft.engine.session.APISession;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Spy;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ProcessFormServiceTest {
@Spy
ProcessFormService processFormService;
@Mock
ProcessAPI processAPI;
@Mock
CommandAPI commandAPI;
@Mock
HttpServletRequest hsRequest;
@Mock
HttpSession httpSession;
@Mock
APISession apiSession;
@Before
public void beforeEach() throws Exception {
when(hsRequest.getSession()).thenReturn(httpSession);
doReturn(processAPI).when(processFormService).getProcessAPI(apiSession);
doReturn(commandAPI).when(processFormService).getCommandAPI(apiSession);
when(apiSession.getUserId()).thenReturn(1L);
}
@Test
public void ensureProcessDefinitionId_with_processDefinitionId() throws Exception {
assertEquals(42L, processFormService.ensureProcessDefinitionId(apiSession, 42L, -1L, -1L));
}
@Test
public void ensureProcessDefinitionId_with_processInstanceId() throws Exception {
final ProcessInstance processInstance = mock(ProcessInstance.class);
when(processInstance.getProcessDefinitionId()).thenReturn(1L);
when(processAPI.getProcessInstance(42L)).thenReturn(processInstance);
assertEquals(1L, processFormService.ensureProcessDefinitionId(apiSession, -1L, 42L, -1L));
}
@Test
public void ensureProcessDefinitionId_with_processInstanceId_on_archived_instance() throws Exception {
final ArchivedProcessInstance archivedProcessInstance = mock(ArchivedProcessInstance.class);
when(archivedProcessInstance.getProcessDefinitionId()).thenReturn(1L);
when(processAPI.getProcessInstance(42L)).thenThrow(ProcessInstanceNotFoundException.class);
final List<ArchivedProcessInstance> result = new ArrayList<ArchivedProcessInstance>();
result.add(archivedProcessInstance);
final SearchResult<ArchivedProcessInstance> searchResult = mock(SearchResult.class);
when(searchResult.getCount()).thenReturn(1L);
when(searchResult.getResult()).thenReturn(result);
when(processAPI.searchArchivedProcessInstancesInAllStates(any(SearchOptions.class))).thenReturn(searchResult);
assertEquals(1L, processFormService.ensureProcessDefinitionId(apiSession, -1L, 42L, -1L));
}
@Test
public void ensureProcessDefinitionId_with_taskInstanceId() throws Exception {
final ActivityInstance activityInstance = mock(ActivityInstance.class);
when(activityInstance.getProcessDefinitionId()).thenReturn(1L);
when(processAPI.getActivityInstance(42L)).thenReturn(activityInstance);
assertEquals(1L, processFormService.ensureProcessDefinitionId(apiSession, -1L, -1L, 42L));
}
@Test
public void ensureProcessDefinitionId_with_taskInstanceId_on_archived_instance() throws Exception {
final ArchivedActivityInstance archivedActivityInstance = mock(ArchivedActivityInstance.class);
when(archivedActivityInstance.getProcessDefinitionId()).thenReturn(1L);
when(processAPI.getActivityInstance(42L)).thenThrow(ActivityInstanceNotFoundException.class);
when(processAPI.getArchivedActivityInstance(42L)).thenReturn(archivedActivityInstance);
assertEquals(1L, processFormService.ensureProcessDefinitionId(apiSession, -1L, -1L, 42L));
}
@Test
public void getTaskName_with_taskInstanceId() throws Exception {
final ActivityInstance activityInstance = mock(ActivityInstance.class);
when(activityInstance.getName()).thenReturn("myTask");
when(processAPI.getActivityInstance(42L)).thenReturn(activityInstance);
assertEquals("myTask", processFormService.getTaskName(apiSession, 42L));
}
@Test
public void getTaskName_with_taskInstanceId_on_archived_instance() throws Exception {
final ArchivedActivityInstance archivedActivityInstance = mock(ArchivedActivityInstance.class);
when(archivedActivityInstance.getName()).thenReturn("myTask");
when(processAPI.getActivityInstance(42L)).thenThrow(ActivityInstanceNotFoundException.class);
when(processAPI.getArchivedActivityInstance(42L)).thenReturn(archivedActivityInstance);
assertEquals("myTask", processFormService.getTaskName(apiSession, 42L));
}
@Test
public void getTaskInstanceId_with_taskInstanceId() throws Exception {
final HumanTaskInstance humanTaskInstance = mock(HumanTaskInstance.class);
when(humanTaskInstance.getId()).thenReturn(1L);
final List<HumanTaskInstance> result = new ArrayList<HumanTaskInstance>();
result.add(humanTaskInstance);
final SearchResult<HumanTaskInstance> searchResult = mock(SearchResult.class);
when(searchResult.getCount()).thenReturn(1L);
when(searchResult.getResult()).thenReturn(result);
when(processAPI.searchMyAvailableHumanTasks(anyLong(), any(SearchOptions.class))).thenReturn(searchResult);
assertEquals(1L, processFormService.getTaskInstanceId(apiSession, 42L, "myTask", -1L));
}
@Test
public void getTaskInstanceId_with_taskInstanceId_on_archived_instance() throws Exception {
when(processAPI.searchMyAvailableHumanTasks(anyLong(), any(SearchOptions.class))).thenReturn(mock(SearchResult.class));
final ArchivedHumanTaskInstance archivedHumanTaskInstance = mock(ArchivedHumanTaskInstance.class);
when(archivedHumanTaskInstance.getSourceObjectId()).thenReturn(1L);
final List<ArchivedHumanTaskInstance> result = new ArrayList<ArchivedHumanTaskInstance>();
result.add(archivedHumanTaskInstance);
final SearchResult<ArchivedHumanTaskInstance> searchResult = mock(SearchResult.class);
when(searchResult.getCount()).thenReturn(1L);
when(searchResult.getResult()).thenReturn(result);
when(processAPI.searchArchivedHumanTasks(any(SearchOptions.class))).thenReturn(searchResult);
assertEquals(1L, processFormService.getTaskInstanceId(apiSession, 42L, "myTask", -1L));
}
@Test
public void getProcessDefinitionId_with_no_version() throws Exception {
assertEquals(-1L, processFormService.getProcessDefinitionId(apiSession, "myProcess", null));
}
@Test
public void getProcessDefinitionId_with_no_name_and_version() throws Exception {
assertEquals(-1L, processFormService.getProcessDefinitionId(apiSession, null, null));
}
@Test
public void isAllowedToSeeTask_should_return_true() throws Exception {
when(processAPI.isInvolvedInHumanTaskInstance(1L, 42L)).thenReturn(true);
when(processAPI.getHumanTaskInstance(42L)).thenReturn(mock(HumanTaskInstance.class));
final boolean isAllowedToSeeTask = processFormService.isAllowedToSeeTask(apiSession, 42L, 1L, false);
assertTrue(isAllowedToSeeTask);
}
@Test
public void isAllowedToSeeTask_should_return_false() throws Exception {
when(processAPI.isInvolvedInHumanTaskInstance(1L, 42L)).thenReturn(false);
when(processAPI.getHumanTaskInstance(42L)).thenReturn(mock(HumanTaskInstance.class));
final boolean isAllowedToSeeTask = processFormService.isAllowedToSeeTask(apiSession, 42L, 1L, false);
assertFalse(isAllowedToSeeTask);
}
@Test
public void isAllowedToSeeTask_should_assign_task() throws Exception {
when(processAPI.isInvolvedInHumanTaskInstance(1L, 42L)).thenReturn(true);
when(processAPI.getHumanTaskInstance(42L)).thenReturn(mock(HumanTaskInstance.class));
final boolean isAllowedToSeeTask = processFormService.isAllowedToSeeTask(apiSession, 42L, 1L, true);
assertTrue(isAllowedToSeeTask);
verify(processAPI).assignUserTask(42L, 1L);
}
@Test
public void isAllowedToSeeTask_should_return_true_for_archived_task() throws Exception {
doThrow(ActivityInstanceNotFoundException.class).when(processAPI).isInvolvedInHumanTaskInstance(1L, 42L);
final ArchivedActivityInstance archivedActivityInstance = mock(ArchivedActivityInstance.class);
when(archivedActivityInstance.getExecutedBy()).thenReturn(1L);
when(processAPI.getArchivedActivityInstance(42L)).thenReturn(archivedActivityInstance);
final boolean isAllowedToSeeTask = processFormService.isAllowedToSeeTask(apiSession, 42L, 1L, false);
assertTrue(isAllowedToSeeTask);
}
@Test
public void isAllowedToSeeTask_should_return_false_for_archived_task() throws Exception {
doThrow(ActivityInstanceNotFoundException.class).when(processAPI).isInvolvedInHumanTaskInstance(1L, 42L);
final ArchivedActivityInstance archivedActivityInstance = mock(ArchivedActivityInstance.class);
when(archivedActivityInstance.getExecutedBy()).thenReturn(2L);
when(processAPI.getArchivedActivityInstance(42L)).thenReturn(archivedActivityInstance);
final boolean isAllowedToSeeTask = processFormService.isAllowedToSeeTask(apiSession, 42L, 1L, false);
assertFalse(isAllowedToSeeTask);
}
@Test
public void isAllowedToSeeProcessInstance_should_return_true() throws Exception {
when(processAPI.isInvolvedInProcessInstance(1L, 42L)).thenReturn(true);
final boolean isAllowedToSeeProcessInstance = processFormService.isAllowedToSeeProcessInstance(apiSession, 42L, 1L);
assertTrue(isAllowedToSeeProcessInstance);
}
@Test
public void isAllowedToSeeProcessInstance_should_return_false() throws Exception {
when(processAPI.isInvolvedInProcessInstance(1L, 42L)).thenReturn(false);
final boolean isAllowedToSeeProcessInstance = processFormService.isAllowedToSeeProcessInstance(apiSession, 42L, 1L);
assertFalse(isAllowedToSeeProcessInstance);
}
@Test
public void isAllowedToStartProcess_should_return_true() throws Exception {
final Map<String, Serializable> parameters = new HashMap<String, Serializable>();
parameters.put("USER_ID_KEY", 1L);
parameters.put("PROCESS_DEFINITION_ID_KEY", 42L);
when(commandAPI.execute("canStartProcessDefinition", parameters)).thenReturn(true);
final ProcessDeploymentInfo processDeploymentInfo = mock(ProcessDeploymentInfo.class);
when(processDeploymentInfo.getActivationState()).thenReturn(ActivationState.ENABLED);
when(processAPI.getProcessDeploymentInfo(42L)).thenReturn(processDeploymentInfo);
final boolean isAllowedToStartProcess = processFormService.isAllowedToStartProcess(apiSession, 42L, 1L);
assertTrue(isAllowedToStartProcess);
}
@Test
public void isAllowedToStartProcess_should_return_false() throws Exception {
final Map<String, Serializable> parameters = new HashMap<String, Serializable>();
parameters.put("USER_ID_KEY", 1L);
parameters.put("PROCESS_DEFINITION_ID_KEY", 42L);
when(commandAPI.execute("canStartProcessDefinition", parameters)).thenReturn(false);
final ProcessDeploymentInfo processDeploymentInfo = mock(ProcessDeploymentInfo.class);
when(processDeploymentInfo.getActivationState()).thenReturn(ActivationState.ENABLED);
when(processAPI.getProcessDeploymentInfo(42L)).thenReturn(processDeploymentInfo);
final boolean isAllowedToStartProcess = processFormService.isAllowedToStartProcess(apiSession, 42L, 1L);
assertFalse(isAllowedToStartProcess);
}
@Test
public void isAllowedToStartProcess_should_return_false_if_process_not_enabled() throws Exception {
final ProcessDeploymentInfo processDeploymentInfo = mock(ProcessDeploymentInfo.class);
when(processDeploymentInfo.getActivationState()).thenReturn(ActivationState.DISABLED);
when(processAPI.getProcessDeploymentInfo(42L)).thenReturn(processDeploymentInfo);
final boolean isAllowedToStartProcess = processFormService.isAllowedToStartProcess(apiSession, 42L, 1L);
assertFalse(isAllowedToStartProcess);
}
@Test
public void isAllowedAsAdminOrProcessSupervisor_should_return_false() throws Exception {
final long processDefinitionId = 2L;
final Set<String> userPermissions = new HashSet<String>();
when(httpSession.getAttribute(SessionUtil.PERMISSIONS_SESSION_PARAM_KEY)).thenReturn(userPermissions);
when(processAPI.isUserProcessSupervisor(processDefinitionId, 1L)).thenReturn(false);
final boolean isAllowedAsAdminOrProcessSupervisor = processFormService.isAllowedAsAdminOrProcessSupervisor(hsRequest, apiSession, processDefinitionId,
42L, -1L, false);
assertFalse(isAllowedAsAdminOrProcessSupervisor);
}
@Test
public void isAllowedAsAdminOrProcessSupervisor_should_return_true_if_process_supervisor() throws Exception {
final long processDefinitionId = 2L;
final Set<String> userPermissions = new HashSet<String>();
when(httpSession.getAttribute(SessionUtil.PERMISSIONS_SESSION_PARAM_KEY)).thenReturn(userPermissions);
when(processAPI.isUserProcessSupervisor(processDefinitionId, 1L)).thenReturn(true);
final boolean isAllowedAsAdminOrProcessSupervisor = processFormService.isAllowedAsAdminOrProcessSupervisor(hsRequest, apiSession, processDefinitionId,
42L, -1L, false);
assertTrue(isAllowedAsAdminOrProcessSupervisor);
}
@Test
public void isAllowedAsAdminOrProcessSupervisor_should_return_true_if_admin() throws Exception {
final long processDefinitionId = 2L;
final Set<String> userPermissions = new HashSet<String>();
userPermissions.add(ProcessFormService.PROCESS_DEPLOY);
when(httpSession.getAttribute(SessionUtil.PERMISSIONS_SESSION_PARAM_KEY)).thenReturn(userPermissions);
when(processAPI.isUserProcessSupervisor(processDefinitionId, 1L)).thenReturn(false);
final boolean isAllowedAsAdminOrProcessSupervisor = processFormService.isAllowedAsAdminOrProcessSupervisor(hsRequest, apiSession, processDefinitionId,
42L, -1L, false);
assertTrue(isAllowedAsAdminOrProcessSupervisor);
}
@Test
public void isAllowedAsAdminOrProcessSupervisor_should_assign_task() throws Exception {
final long processDefinitionId = 2L;
final long doForUser = 5L;
final long taskId = 42L;
final Set<String> userPermissions = new HashSet<String>();
when(httpSession.getAttribute(SessionUtil.PERMISSIONS_SESSION_PARAM_KEY)).thenReturn(userPermissions);
when(processAPI.isUserProcessSupervisor(processDefinitionId, 1L)).thenReturn(true);
when(processAPI.getHumanTaskInstance(taskId)).thenReturn(mock(HumanTaskInstance.class));
final boolean isAllowedAsAdminOrProcessSupervisor = processFormService.isAllowedAsAdminOrProcessSupervisor(hsRequest, apiSession, processDefinitionId,
taskId, doForUser, true);
assertTrue(isAllowedAsAdminOrProcessSupervisor);
verify(processAPI).assignUserTask(taskId, doForUser);
}
@Test
public void getProcessDefinitionUUID_should_return_valid_UUID() throws Exception {
final ProcessDeploymentInfo processDeploymentInfo = mock(ProcessDeploymentInfo.class);
when(processDeploymentInfo.getName()).thenReturn("processName");
when(processDeploymentInfo.getVersion()).thenReturn("processVersion");
when(processAPI.getProcessDeploymentInfo(1L)).thenReturn(processDeploymentInfo);
final String uuid = processFormService.getProcessPath(apiSession, 1L);
assertEquals("processName/processVersion", uuid);
}
@Test
public void getProcessDefinitionUUID_should_return_valid_UUID_with_special_characters() throws Exception {
final ProcessDeploymentInfo processDeploymentInfo = mock(ProcessDeploymentInfo.class);
when(processDeploymentInfo.getName()).thenReturn("process Name/é");
when(processDeploymentInfo.getVersion()).thenReturn("process Version ø");
when(processAPI.getProcessDeploymentInfo(1L)).thenReturn(processDeploymentInfo);
final String uuid = processFormService.getProcessPath(apiSession, 1L);
assertEquals("process%20Name/%C3%A9/process%20Version%20%C3%B8", uuid);
}
}