/*
* Copyright 2016 Red Hat, Inc. and/or its affiliates.
*
* 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.jbpm.casemgmt.impl;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.assertj.core.api.Assertions;
import org.drools.compiler.kie.builder.impl.InternalKieModule;
import org.jbpm.casemgmt.api.AdHocFragmentNotFoundException;
import org.jbpm.casemgmt.api.CaseActiveException;
import org.jbpm.casemgmt.api.CaseCommentNotFoundException;
import org.jbpm.casemgmt.api.CaseNotFoundException;
import org.jbpm.casemgmt.api.model.AdHocFragment;
import org.jbpm.casemgmt.api.model.CaseDefinition;
import org.jbpm.casemgmt.api.model.CaseFileItem;
import org.jbpm.casemgmt.api.model.CaseStage;
import org.jbpm.casemgmt.api.model.CaseStatus;
import org.jbpm.casemgmt.api.model.instance.CaseFileInstance;
import org.jbpm.casemgmt.api.model.instance.CaseInstance;
import org.jbpm.casemgmt.api.model.instance.CaseMilestoneInstance;
import org.jbpm.casemgmt.api.model.instance.CaseStageInstance;
import org.jbpm.casemgmt.api.model.instance.CommentInstance;
import org.jbpm.casemgmt.api.model.instance.CommentSortBy;
import org.jbpm.casemgmt.api.model.instance.MilestoneStatus;
import org.jbpm.casemgmt.api.model.instance.StageStatus;
import org.jbpm.casemgmt.impl.model.instance.CaseInstanceImpl;
import org.jbpm.casemgmt.impl.objects.EchoService;
import org.jbpm.casemgmt.impl.util.AbstractCaseServicesBaseTest;
import org.jbpm.document.Document;
import org.jbpm.document.service.impl.DocumentImpl;
import org.jbpm.kie.services.impl.KModuleDeploymentUnit;
import org.jbpm.runtime.manager.impl.deploy.DeploymentDescriptorImpl;
import org.jbpm.services.api.TaskNotFoundException;
import org.jbpm.services.api.model.NodeInstanceDesc;
import org.jbpm.services.api.model.ProcessInstanceDesc;
import org.jbpm.services.api.model.VariableDesc;
import org.jbpm.services.task.impl.model.GroupImpl;
import org.jbpm.services.task.impl.model.UserImpl;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.kie.api.KieServices;
import org.kie.api.builder.ReleaseId;
import org.kie.api.runtime.query.QueryContext;
import org.kie.api.task.model.OrganizationalEntity;
import org.kie.api.task.model.Status;
import org.kie.api.task.model.TaskSummary;
import org.kie.internal.KieInternalServices;
import org.kie.internal.process.CorrelationKey;
import org.kie.internal.query.QueryFilter;
import org.kie.internal.runtime.conf.DeploymentDescriptor;
import org.kie.internal.runtime.conf.NamedObjectModel;
import org.kie.internal.runtime.conf.RuntimeStrategy;
import org.kie.scanner.MavenRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static java.util.stream.Collectors.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.*;
import static org.junit.Assert.*;
import static org.junit.Assert.fail;
import static org.kie.scanner.MavenRepository.*;
public class CaseServiceImplTest extends AbstractCaseServicesBaseTest {
private static final Logger logger = LoggerFactory.getLogger(CaseServiceImplTest.class);
private static final String TEST_DOC_STORAGE = "target/docs";
private KModuleDeploymentUnit deploymentUnit;
@Before
public void prepare() {
System.setProperty("org.jbpm.document.storage", TEST_DOC_STORAGE);
deleteFolder(TEST_DOC_STORAGE);
configureServices();
KieServices ks = KieServices.Factory.get();
ReleaseId releaseId = ks.newReleaseId(GROUP_ID, ARTIFACT_ID, VERSION);
List<String> processes = new ArrayList<String>();
processes.add("cases/EmptyCase.bpmn2");
processes.add("cases/UserTaskCase.bpmn2");
processes.add("cases/UserTaskWithStageCase.bpmn2");
processes.add("cases/UserTaskWithStageCaseAutoStart.bpmn2");
processes.add("cases/UserStageAdhocCase.bpmn2");
processes.add("cases/ScriptRoleAssignmentCase.bpmn2");
processes.add("cases/NoStartNodeAdhocCase.bpmn2");
processes.add("cases/CaseFileConditionalEvent.bpmn2");
processes.add("cases/CaseWithRolesDefinition.bpmn2");
processes.add("cases/CaseWithTwoStagesConditions.bpmn2");
// add processes that can be used by cases but are not cases themselves
processes.add("processes/DataVerificationProcess.bpmn2");
InternalKieModule kJar1 = createKieJar(ks, releaseId, processes);
File pom = new File("target/kmodule", "pom.xml");
pom.getParentFile().mkdir();
try {
FileOutputStream fs = new FileOutputStream(pom);
fs.write(getPom(releaseId).getBytes());
fs.close();
} catch (Exception e) {
}
MavenRepository repository = getMavenRepository();
repository.deployArtifact(releaseId, kJar1, pom);
// use user name who is part of the case roles assignment
// so (s)he will be authorized to access case instance
identityProvider.setName("john");
assertNotNull(deploymentService);
deploymentUnit = new KModuleDeploymentUnit(GROUP_ID, ARTIFACT_ID, VERSION);
final DeploymentDescriptor descriptor = new DeploymentDescriptorImpl();
descriptor.getBuilder().addEventListener(new NamedObjectModel(
"mvel",
"processIdentity",
"new org.jbpm.kie.services.impl.IdentityProviderAwareProcessListener(ksession)"
));
deploymentUnit.setDeploymentDescriptor(descriptor);
deploymentUnit.setStrategy(RuntimeStrategy.PER_CASE);
deploymentService.deploy(deploymentUnit);
}
@After
public void cleanup() {
identityProvider.reset();
identityProvider.setRoles(new ArrayList<>());
System.clearProperty("org.jbpm.document.storage");
cleanupSingletonSessionId();
if (deploymentUnit != null) {
deploymentService.undeploy(deploymentUnit);
}
close();
}
@Test
public void testStartEmptyCase() {
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseAndDestroy() {
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
caseService.destroyCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseWithCaseFile() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId, true, false, false, false);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertNotNull(cInstance.getCaseFile());
assertEquals("my first case", cInstance.getCaseFile().getData("name"));
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
Collection<VariableDesc> vars = runtimeDataService.getVariablesCurrentState(((CaseInstanceImpl) cInstance).getProcessInstanceId());
assertNotNull(vars);
assertEquals(3, vars.size());
Map<String, Object> mappedVars = vars.stream().collect(toMap(v -> v.getVariableId(), v -> v.getNewValue()));
assertEquals("my first case", mappedVars.get("caseFile_name"));
assertEquals(FIRST_CASE_ID, mappedVars.get("CaseId"));
assertEquals("john", mappedVars.get("initiator"));
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseWithCaseFileAndDocument() {
byte[] docContent = "first case document".getBytes();
DocumentImpl document = new DocumentImpl(UUID.randomUUID().toString(), "test case doc", docContent.length, new Date());
document.setContent(docContent);
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
data.put("document", document);
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId, true, false, false, false);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertNotNull(cInstance.getCaseFile());
assertEquals("my first case", cInstance.getCaseFile().getData("name"));
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
Object doc = cInstance.getCaseFile().getData("document");
assertNotNull(doc);
assertTrue(doc instanceof Document);
Document caseDoc = (Document) doc;
assertEquals("test case doc", caseDoc.getName());
assertEquals(docContent.length, caseDoc.getSize());
assertEquals(new String(docContent), new String(caseDoc.getContent()));
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testAddUserTaskToEmptyCase() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
// add dynamic user task to empty case instance - first by case id
Map<String, Object> parameters = new HashMap<>();
parameters.put("variable", "#{name}");
caseService.addDynamicTask(FIRST_CASE_ID, caseService.newHumanTaskSpec("First task", "test", "john", null, parameters));
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
TaskSummary task = tasks.get(0);
assertTask(task, "john", "First task", Status.Reserved);
assertEquals("test", task.getDescription());
Map<String, Object> inputs = userTaskService.getTaskInputContentByTaskId(task.getId());
assertNotNull(inputs);
assertEquals("my first case", inputs.get("variable"));
String nameVar = (String) processService.getProcessInstanceVariable(task.getProcessInstanceId(), "name");
assertNotNull(nameVar);
assertEquals("my first case", nameVar);
userTaskService.start(task.getId(), "john");
Map<String, Object> outcome = new HashMap<>();
outcome.put("name", "updated by dynamic task");
userTaskService.complete(task.getId(), "john", outcome);
nameVar = (String) processService.getProcessInstanceVariable(task.getProcessInstanceId(), "name");
assertNotNull(nameVar);
assertEquals("updated by dynamic task", nameVar);
// second task add by process instance id
Collection<ProcessInstanceDesc> caseProcessInstances = caseRuntimeDataService.getProcessInstancesForCase(caseId, new QueryContext());
assertNotNull(caseProcessInstances);
assertEquals(1, caseProcessInstances.size());
ProcessInstanceDesc casePI = caseProcessInstances.iterator().next();
assertNotNull(casePI);
assertEquals(FIRST_CASE_ID, casePI.getCorrelationKey());
caseService.addDynamicTask(casePI.getId(), caseService.newHumanTaskSpec("Second task", "another test", "mary", null, parameters));
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("mary", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
task = tasks.get(0);
assertTask(task, "mary", "Second task", Status.Reserved);
assertEquals("another test", task.getDescription());
// User john cannot work with task assigned to mary
try {
userTaskService.start(task.getId(), "john");
} catch (TaskNotFoundException e) {
// expected
}
userTaskService.start(task.getId(), "mary");
userTaskService.complete(task.getId(), "mary", null);
Collection<NodeInstanceDesc> nodes = runtimeDataService.getProcessInstanceHistoryCompleted(casePI.getId(), new QueryContext());
assertNotNull(nodes);
assertEquals(4, nodes.size());
Map<String, String> nodesByName = nodes.stream().collect(toMap(NodeInstanceDesc::getName, NodeInstanceDesc::getNodeType));
assertTrue(nodesByName.containsKey("StartProcess"));
assertTrue(nodesByName.containsKey("EndProcess"));
assertTrue(nodesByName.containsKey("[Dynamic] First task"));
assertTrue(nodesByName.containsKey("[Dynamic] Second task"));
assertEquals("StartNode", nodesByName.get("StartProcess"));
assertEquals("EndNode", nodesByName.get("EndProcess"));
assertEquals("Human Task", nodesByName.get("[Dynamic] First task"));
assertEquals("Human Task", nodesByName.get("[Dynamic] Second task"));
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testAddUserTaskToCaseWithStage() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
CaseDefinition caseDef = caseRuntimeDataService.getCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_CASE_P_ID);
assertNotNull(caseDef);
assertEquals(1, caseDef.getCaseStages().size());
assertEquals(deploymentUnit.getIdentifier(), caseDef.getDeploymentId());
CaseStage stage = caseDef.getCaseStages().iterator().next();
// add dynamic user task to empty case instance - first by case id
Map<String, Object> parameters = new HashMap<>();
caseService.addDynamicTaskToStage(FIRST_CASE_ID, stage.getId(), caseService.newHumanTaskSpec("First task", "test", "john", null, parameters));
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
TaskSummary task = tasks.get(0);
assertTask(task, "john", "First task", Status.Reserved);
assertEquals("test", task.getDescription());
// second task add by process instance id
Collection<ProcessInstanceDesc> caseProcessInstances = caseRuntimeDataService.getProcessInstancesForCase(caseId, new QueryContext());
assertNotNull(caseProcessInstances);
assertEquals(1, caseProcessInstances.size());
ProcessInstanceDesc casePI = caseProcessInstances.iterator().next();
assertNotNull(casePI);
assertEquals(FIRST_CASE_ID, casePI.getCorrelationKey());
caseService.addDynamicTaskToStage(casePI.getId(), stage.getId(), caseService.newHumanTaskSpec("Second task", "another test", "mary", null, parameters));
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("mary", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
task = tasks.get(0);
assertTask(task, "mary", "Second task", Status.Reserved);
assertEquals("another test", task.getDescription());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testAddServiceTaskToEmptyCase() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
Collection<ProcessInstanceDesc> caseProcessInstances = caseRuntimeDataService.getProcessInstancesForCase(caseId, new QueryContext());
assertNotNull(caseProcessInstances);
assertEquals(1, caseProcessInstances.size());
ProcessInstanceDesc casePI = caseProcessInstances.iterator().next();
assertNotNull(casePI);
assertEquals(FIRST_CASE_ID, casePI.getCorrelationKey());
String nameVar = (String) processService.getProcessInstanceVariable(casePI.getId(), "name");
assertNotNull(nameVar);
assertEquals("my first case", nameVar);
// add dynamic service task to empty case instance - first by case id
Map<String, Object> parameters = new HashMap<>();
parameters.put("Interface", EchoService.class.getName());
parameters.put("Operation", "echo");
parameters.put("ParameterType", String.class.getName());
parameters.put("Parameter", "testing dynamic service task");
caseService.addDynamicTask(FIRST_CASE_ID, caseService.newTaskSpec("Service Task", "task 1", parameters));
nameVar = (String) processService.getProcessInstanceVariable(casePI.getId(), "name");
assertNotNull(nameVar);
assertEquals("testing dynamic service task echoed by service", nameVar);
// second dynamic service task add by process instance id
parameters.put("Parameter", "testing dynamic service task 2");
caseService.addDynamicTask(casePI.getId(), caseService.newTaskSpec("Service Task", "task 2", parameters));
nameVar = (String) processService.getProcessInstanceVariable(casePI.getId(), "name");
assertNotNull(nameVar);
assertEquals("testing dynamic service task 2 echoed by service", nameVar);
Collection<NodeInstanceDesc> nodes = runtimeDataService.getProcessInstanceHistoryCompleted(casePI.getId(), new QueryContext());
assertNotNull(nodes);
assertEquals(4, nodes.size());
Map<String, String> nodesByName = nodes.stream().collect(toMap(NodeInstanceDesc::getName, NodeInstanceDesc::getNodeType));
assertTrue(nodesByName.containsKey("StartProcess"));
assertTrue(nodesByName.containsKey("EndProcess"));
assertTrue(nodesByName.containsKey("[Dynamic] task 1"));
assertTrue(nodesByName.containsKey("[Dynamic] task 2"));
assertEquals("StartNode", nodesByName.get("StartProcess"));
assertEquals("EndNode", nodesByName.get("EndProcess"));
assertEquals("Service Task", nodesByName.get("[Dynamic] task 1"));
assertEquals("Service Task", nodesByName.get("[Dynamic] task 2"));
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testAddSubprocessToEmptyCase() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
// add dynamic user task to empty case instance - first by case id
Map<String, Object> parameters = new HashMap<>();
caseService.addDynamicSubprocess(FIRST_CASE_ID, SUBPROCESS_P_ID, parameters);
// second task add by process instance id
Collection<ProcessInstanceDesc> caseProcessInstances = caseRuntimeDataService.getProcessInstancesForCase(caseId, new QueryContext());
assertNotNull(caseProcessInstances);
assertEquals(2, caseProcessInstances.size());
ProcessInstanceDesc casePI = caseProcessInstances.iterator().next();
assertNotNull(casePI);
assertEquals(FIRST_CASE_ID, casePI.getCorrelationKey());
Collection<NodeInstanceDesc> nodes = runtimeDataService.getProcessInstanceHistoryCompleted(casePI.getId(), new QueryContext());
assertNotNull(nodes);
assertEquals(3, nodes.size());
Map<String, String> nodesByName = nodes.stream().collect(toMap(NodeInstanceDesc::getName, NodeInstanceDesc::getNodeType));
assertTrue(nodesByName.containsKey("StartProcess"));
assertTrue(nodesByName.containsKey("EndProcess"));
assertTrue(nodesByName.containsKey("[Dynamic] Sub Process"));
assertEquals("StartNode", nodesByName.get("StartProcess"));
assertEquals("EndNode", nodesByName.get("EndProcess"));
assertEquals("SubProcessNode", nodesByName.get("[Dynamic] Sub Process"));
caseService.addDynamicSubprocess(casePI.getId(), SUBPROCESS_P_ID, parameters);
// let's verify that there are three process instances related to this case
caseProcessInstances = caseRuntimeDataService.getProcessInstancesForCase(caseId, new QueryContext());
assertNotNull(caseProcessInstances);
assertEquals(3, caseProcessInstances.size());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testAddSubprocessToCaseWithStage() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
CaseDefinition caseDef = caseRuntimeDataService.getCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_CASE_P_ID);
assertNotNull(caseDef);
assertEquals(1, caseDef.getCaseStages().size());
assertEquals(deploymentUnit.getIdentifier(), caseDef.getDeploymentId());
CaseStage stage = caseDef.getCaseStages().iterator().next();
// add dynamic user task to empty case instance - first by case id
Map<String, Object> parameters = new HashMap<>();
caseService.addDynamicSubprocessToStage(FIRST_CASE_ID, stage.getId(), SUBPROCESS_P_ID, parameters);
// second task add by process instance id
Collection<ProcessInstanceDesc> caseProcessInstances = caseRuntimeDataService.getProcessInstancesForCase(caseId, new QueryContext());
assertNotNull(caseProcessInstances);
assertEquals(2, caseProcessInstances.size());
ProcessInstanceDesc casePI = caseProcessInstances.iterator().next();
assertNotNull(casePI);
assertEquals(FIRST_CASE_ID, casePI.getCorrelationKey());
caseService.addDynamicSubprocessToStage(casePI.getId(), stage.getId(), SUBPROCESS_P_ID, parameters);
// let's verify that there are three process instances related to this case
caseProcessInstances = caseRuntimeDataService.getProcessInstancesForCase(caseId, new QueryContext());
assertNotNull(caseProcessInstances);
assertEquals(3, caseProcessInstances.size());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testTriggerTaskAndMilestoneInCase() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
data.put("s", "description");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
CaseDefinition caseDef = caseRuntimeDataService.getCase(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID);
assertNotNull(caseDef);
assertEquals(deploymentUnit.getIdentifier(), caseDef.getDeploymentId());
assertEquals(3, caseDef.getAdHocFragments().size());
Map<String, AdHocFragment> mappedFragments = mapAdHocFragments(caseDef.getAdHocFragments());
assertTrue(mappedFragments.containsKey("Hello2"));
assertTrue(mappedFragments.containsKey("Milestone1"));
assertTrue(mappedFragments.containsKey("Milestone2"));
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(HR_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(HR_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
TaskSummary task = tasks.get(0);
assertNotNull(task);
assertEquals("Hello1", task.getName());
assertEquals("john", task.getActualOwnerId());
assertEquals(Status.Reserved, task.getStatus());
// now let's trigger one (human task) fragment
Map<String, Object> taskData = new HashMap<>();
taskData.put("test", "value");
taskData.put("fromVar", "#{s}");
caseService.triggerAdHocFragment(HR_CASE_ID, "Hello2", taskData);
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(2, tasks.size());
task = tasks.get(0);
assertNotNull(task);
assertEquals("Hello2", task.getName());
assertEquals("john", task.getActualOwnerId());
assertEquals(Status.Reserved, task.getStatus());
Map<String, Object> taskInputs = userTaskService.getTaskInputContentByTaskId(task.getId());
assertNotNull(taskInputs);
assertTrue(taskInputs.containsKey("test"));
assertTrue(taskInputs.containsKey("fromVar"));
assertEquals("value", taskInputs.get("test"));
assertEquals("description", taskInputs.get("fromVar"));
task = tasks.get(1);
assertNotNull(task);
assertEquals("Hello1", task.getName());
assertEquals("john", task.getActualOwnerId());
assertEquals(Status.Reserved, task.getStatus());
Collection<CaseMilestoneInstance> milestones = caseRuntimeDataService.getCaseInstanceMilestones(HR_CASE_ID, true, new QueryContext());
assertNotNull(milestones);
assertEquals(0, milestones.size());
milestones = caseRuntimeDataService.getCaseInstanceMilestones(HR_CASE_ID, false, new QueryContext());
assertNotNull(milestones);
assertEquals(2, milestones.size());
List<String> expectedMilestones = Arrays.asList("Milestone1", "Milestone2");
for (CaseMilestoneInstance mi : milestones) {
assertTrue("Expected mile stopne not found", expectedMilestones.contains(mi.getName()));
assertEquals("Wrong milestone status", MilestoneStatus.Available, mi.getStatus());
assertFalse("Should not be achieved", mi.isAchieved());
assertNull("Achieved date should be null", mi.getAchievedAt());
}
// trigger milestone node
caseService.triggerAdHocFragment(HR_CASE_ID, "Milestone1", null);
milestones = caseRuntimeDataService.getCaseInstanceMilestones(HR_CASE_ID, true, new QueryContext());
assertNotNull(milestones);
assertEquals(1, milestones.size());
CaseMilestoneInstance msInstance = milestones.iterator().next();
assertNotNull(msInstance);
assertEquals("Milestone1", msInstance.getName());
assertEquals(true, msInstance.isAchieved());
assertNotNull(msInstance.getAchievedAt());
// trigger another milestone node that has condition so it should not be achieved
caseService.triggerAdHocFragment(HR_CASE_ID, "Milestone2", null);
milestones = caseRuntimeDataService.getCaseInstanceMilestones(HR_CASE_ID, true, new QueryContext());
assertNotNull(milestones);
assertEquals(1, milestones.size());
milestones = caseRuntimeDataService.getCaseInstanceMilestones(HR_CASE_ID, false, new QueryContext());
assertNotNull(milestones);
assertEquals(2, milestones.size());
// add dataComplete to case file to achieve milestone
caseService.addDataToCaseFile(HR_CASE_ID, "dataComplete", true);
milestones = caseRuntimeDataService.getCaseInstanceMilestones(HR_CASE_ID, true, new QueryContext());
assertNotNull(milestones);
assertEquals(2, milestones.size());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testCaseRolesWithDynamicTask() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
data.put("s", "description");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
CaseDefinition caseDef = caseRuntimeDataService.getCase(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID);
assertNotNull(caseDef);
assertEquals(deploymentUnit.getIdentifier(), caseDef.getDeploymentId());
assertEquals(3, caseDef.getAdHocFragments().size());
Map<String, AdHocFragment> mappedFragments = mapAdHocFragments(caseDef.getAdHocFragments());
assertTrue(mappedFragments.containsKey("Hello2"));
assertEquals("HumanTaskNode", mappedFragments.get("Hello2").getType());
assertTrue(mappedFragments.containsKey("Milestone1"));
assertEquals("MilestoneNode", mappedFragments.get("Milestone1").getType());
assertTrue(mappedFragments.containsKey("Milestone2"));
assertEquals("MilestoneNode", mappedFragments.get("Milestone2").getType());
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(HR_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(HR_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
caseService.assignToCaseRole(HR_CASE_ID, "contact", new UserImpl("mary"));
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
assertTask(tasks.get(0), "john", "Hello1", Status.Reserved);
caseService.addDynamicTask(HR_CASE_ID, caseService.newHumanTaskSpec("Second task", "another test", "contact", null, new HashMap<>()));
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("mary", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
assertTask(tasks.get(0), "mary", "Second task", Status.Reserved);
// now let's another user to contact role
caseService.assignToCaseRole(HR_CASE_ID, "contact", new UserImpl("john"));
caseService.addDynamicTask(HR_CASE_ID, caseService.newHumanTaskSpec("Third task", "another test", "contact", null, new HashMap<>()));
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("mary", new QueryFilter());
assertNotNull(tasks);
assertEquals(2, tasks.size());
assertTask(tasks.get(0), null, "Third task", Status.Ready);
assertTask(tasks.get(1), "mary", "Second task", Status.Reserved);
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testCaseWithStageAutoStartNodes() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_STAGE_AUTO_START_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_AUTO_START_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(2, tasks.size());
assertTask(tasks.get(0), "john", "Ask for input", Status.Reserved);
assertTask(tasks.get(1), "john", "Missing data", Status.Reserved);
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testCaseWithComments() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_STAGE_AUTO_START_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_AUTO_START_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
Collection<CommentInstance> caseComments = caseService.getCaseComments(FIRST_CASE_ID, new QueryContext());
assertNotNull(caseComments);
assertEquals(0, caseComments.size());
caseService.addCaseComment(FIRST_CASE_ID, "poul", "just a tiny comment");
caseComments = caseService.getCaseComments(FIRST_CASE_ID, new QueryContext());
assertNotNull(caseComments);
assertEquals(1, caseComments.size());
CommentInstance comment = caseComments.iterator().next();
assertComment(comment, "poul", "just a tiny comment");
caseService.updateCaseComment(FIRST_CASE_ID, comment.getId(), comment.getAuthor(), "Updated " + comment.getComment());
caseComments = caseService.getCaseComments(FIRST_CASE_ID, new QueryContext());
assertNotNull(caseComments);
assertEquals(1, caseComments.size());
comment = caseComments.iterator().next();
assertComment(comment, "poul", "Updated just a tiny comment");
caseService.addCaseComment(FIRST_CASE_ID, "mary", "another comment");
caseService.addCaseComment(FIRST_CASE_ID, "john", "third comment");
caseComments = caseService.getCaseComments(FIRST_CASE_ID, new QueryContext());
assertNotNull(caseComments);
assertEquals(3, caseComments.size());
Iterator<CommentInstance> it = caseComments.iterator();
assertComment(it.next(), "poul", "Updated just a tiny comment");
assertComment(it.next(), "mary", "another comment");
assertComment(it.next(), "john", "third comment");
caseComments = caseService.getCaseComments(FIRST_CASE_ID, CommentSortBy.Author, new QueryContext());
assertNotNull(caseComments);
assertEquals(3, caseComments.size());
it = caseComments.iterator();
assertComment(it.next(), "john", "third comment");
assertComment(it.next(), "mary", "another comment");
assertComment(it.next(), "poul", "Updated just a tiny comment");
caseService.removeCaseComment(FIRST_CASE_ID, comment.getId());
caseComments = caseService.getCaseComments(FIRST_CASE_ID, CommentSortBy.Author, new QueryContext());
assertEquals(2, caseComments.size());
it = caseComments.iterator();
assertComment(it.next(), "john", "third comment");
assertComment(it.next(), "mary", "another comment");
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testUpdateNotExistingCaseComment() {
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_STAGE_AUTO_START_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_AUTO_START_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
caseService.updateCaseComment(FIRST_CASE_ID, "not-existing-comment", "poul", "just a tiny comment");
fail("Updating non-existent case comment should throw CaseCommentNotFoundException.");
} catch (CaseCommentNotFoundException e) {
// expected
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testRemoveNotExistingCaseComment() {
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_STAGE_AUTO_START_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_AUTO_START_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
caseService.removeCaseComment(FIRST_CASE_ID, "not-existing-comment");
fail("Removing non-existent case comment should throw CaseCommentNotFoundException.");
} catch (CaseCommentNotFoundException e) {
// expected
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartCaseWithStageAndAdHocFragments() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_STAGE_ADHOC_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_ADHOC_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
assertCaseInstance(caseId, "my first case");
Collection<AdHocFragment> availableFragments = caseRuntimeDataService.getAdHocFragmentsForCase(caseId);
assertEquals(2, availableFragments.size());
Map<String, AdHocFragment> mapped = mapAdHocFragments(availableFragments);
assertEquals("HumanTaskNode", mapped.get("Adhoc 1").getType());
assertEquals("HumanTaskNode", mapped.get("Adhoc 2").getType());
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
assertTask(tasks.get(0), "john", "Initial step", Status.Reserved);
userTaskService.completeAutoProgress(tasks.get(0).getId(), "john", null);
availableFragments = caseRuntimeDataService.getAdHocFragmentsForCase(caseId);
assertEquals(4, availableFragments.size());
mapped = mapAdHocFragments(availableFragments);
assertEquals("HumanTaskNode", mapped.get("Adhoc 1").getType());
assertEquals("HumanTaskNode", mapped.get("Adhoc 2").getType());
assertEquals("HumanTaskNode", mapped.get("First").getType());
assertEquals("HumanTaskNode", mapped.get("Second").getType());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartThenReopenEmptyCase() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals("my first case", cInstance.getCaseDescription());
long firstCaseProcessInstanceId = ((CaseInstanceImpl) cInstance).getProcessInstanceId();
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseService.reopenCase(caseId, deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID);
cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals("my first case", cInstance.getCaseDescription());
long secondCaseProcessInstanceId = ((CaseInstanceImpl) cInstance).getProcessInstanceId();
assertTrue(secondCaseProcessInstanceId > firstCaseProcessInstanceId);
caseService.destroyCase(caseId);
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartThenReopenEmptyCaseUpdateDescription() {
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals("#{name}", cInstance.getCaseDescription());
long firstCaseProcessInstanceId = ((CaseInstanceImpl) cInstance).getProcessInstanceId();
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
caseService.reopenCase(caseId, deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals("my first case", cInstance.getCaseDescription());
long secondCaseProcessInstanceId = ((CaseInstanceImpl) cInstance).getProcessInstanceId();
assertTrue(secondCaseProcessInstanceId > firstCaseProcessInstanceId);
caseService.destroyCase(caseId);
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartThenReopenActiveCase() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals("my first case", cInstance.getCaseDescription());
try {
caseService.reopenCase(caseId, deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID);
fail("Not allowed to reopen active case");
} catch (CaseActiveException e) {
// expected
}
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartThenReopenDestroyedCase() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals("my first case", cInstance.getCaseDescription());
caseService.destroyCase(caseId);
try {
caseService.reopenCase(caseId, deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID);
fail("Not allowed to reopen destroyed case");
} catch (CaseNotFoundException e) {
// expected
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartScriptRoleAssignmentCase() {
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), "ScriptRoleAssignmentCase");
assertNotNull(caseId);
assertEquals(HR_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
TaskSummary task = tasks.get(0);
assertEquals("User Task 1", task.getName());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartCaseWithoutStartNode() {
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), NO_START_NODE_CASE_P_ID);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
Collection<NodeInstanceDesc> activeNodes = runtimeDataService.getProcessInstanceHistoryActive(((CaseInstanceImpl) cInstance).getProcessInstanceId(), new org.kie.api.runtime.query.QueryContext());
assertNotNull(activeNodes);
assertEquals(1, activeNodes.size());
NodeInstanceDesc active = activeNodes.iterator().next();
assertEquals("Initial step", active.getName());
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertNotNull(tasks);
assertEquals(1, tasks.size());
TaskSummary task = tasks.get(0);
userTaskService.completeAutoProgress(task.getId(), "john", new HashMap<>());
activeNodes = runtimeDataService.getProcessInstanceHistoryActive(((CaseInstanceImpl) cInstance).getProcessInstanceId(), new org.kie.api.runtime.query.QueryContext());
assertNotNull(activeNodes);
assertEquals(1, activeNodes.size());
active = activeNodes.iterator().next();
assertEquals("stage", active.getName());
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseViaProcessService() {
String caseId = FIRST_CASE_ID;
CorrelationKey correlationKey = KieInternalServices.Factory.get().newCorrelationKeyFactory().newCorrelationKey(caseId);
Map<String, Object> params = new HashMap<>();
params.put("name", "my case via process service");
Long processInstanceId = processService.startProcess(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, correlationKey, params);
assertNotNull(processInstanceId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals(caseId, cInstance.getCaseId());
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseViaProcessServiceWithoutCorrelationKey() {
Map<String, Object> params = new HashMap<>();
params.put("name", "my case via process service");
Long processInstanceId = processService.startProcess(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, params);
assertNotNull(processInstanceId);
String caseId = processInstanceId.toString();
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals(caseId, cInstance.getCaseId());
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseViaProcessServiceWithoutCorrelationKeyWithMilestones() {
Map<String, Object> params = new HashMap<>();
params.put("s", "my case via process service");
Long processInstanceId = processService.startProcess(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, params);
assertNotNull(processInstanceId);
String caseId = processInstanceId.toString();
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals(caseId, cInstance.getCaseId());
Collection<CaseMilestoneInstance> milestones = caseRuntimeDataService.getCaseInstanceMilestones(caseId, true, new QueryContext());
assertNotNull(milestones);
assertEquals(0, milestones.size());
// trigger milestone node
caseService.triggerAdHocFragment(caseId, "Milestone1", null);
milestones = caseRuntimeDataService.getCaseInstanceMilestones(caseId, true, new QueryContext());
assertNotNull(milestones);
assertEquals(1, milestones.size());
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartThenCancelRetrieveCaseFile() {
try {
caseService.getCaseFileInstance(FIRST_CASE_ID);
fail("There is no case yet started");
} catch (CaseNotFoundException e) {
// expected
}
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
assertEquals("my first case", cInstance.getCaseDescription());
CaseFileInstance caseFileFromCase = caseService.getCaseFileInstance(FIRST_CASE_ID);
assertNotNull(caseFileFromCase);
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseFileFromCase = caseService.getCaseFileInstance(FIRST_CASE_ID);
assertNotNull(caseFileFromCase);
caseService.destroyCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
try {
caseService.getCaseFileInstance(FIRST_CASE_ID);
fail("There is no case yet started");
} catch (CaseNotFoundException e) {
// expected
}
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testUserTaskToCaseWithStageComplete() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
CaseDefinition caseDef = caseRuntimeDataService.getCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_CASE_P_ID);
assertNotNull(caseDef);
assertEquals(1, caseDef.getCaseStages().size());
assertEquals(deploymentUnit.getIdentifier(), caseDef.getDeploymentId());
Collection<CaseStageInstance> activeStages = caseRuntimeDataService.getCaseInstanceStages(caseId, true, new QueryContext());
assertNotNull(activeStages);
assertEquals(1, activeStages.size());
caseService.addDataToCaseFile(caseId, "dataComplete", true);
activeStages = caseRuntimeDataService.getCaseInstanceStages(caseId, true, new QueryContext());
assertNotNull(activeStages);
assertEquals(0, activeStages.size());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartCaseWithConditionalEvent() {
Map<String, Object> data = new HashMap<>();
data.put("Documents", new ArrayList<>());
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), COND_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), COND_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartCaseWithConditionalEventCompleteCase() {
List<String> docs = new ArrayList<>();
docs.add("First doc");
Map<String, Object> data = new HashMap<>();
data.put("Documents", docs);
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), COND_CASE_P_ID, data);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), COND_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
try {
caseService.getCaseInstance(caseId);
fail("Case instance should already be completed");
} catch (CaseNotFoundException e) {
// case is already completed as the docs where given at the start
caseId = null;
}
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testCaseRolesWithQueries() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
roleAssignments.put("contact", new GroupImpl("HR"));
Map<String, Object> data = new HashMap<>();
data.put("s", "description");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(HR_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(HR_CASE_ID, cInstance.getCaseId());
assertEquals(CaseStatus.OPEN.getId(), cInstance.getStatus().intValue());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
// only john is now included in case roles
Collection<CaseInstance> instances = caseRuntimeDataService.getCaseInstancesAnyRole(null, new QueryContext());
assertNotNull(instances);
assertEquals(0, instances.size());
List<CaseStatus> status = Arrays.asList(CaseStatus.CANCELLED);
instances = caseRuntimeDataService.getCaseInstancesAnyRole(status, new QueryContext());
assertNotNull(instances);
assertFalse("Opened case was returned when searching for cancelled case instances.", instances.stream().anyMatch(n -> n.getCaseId().equals(caseId)));
status = Arrays.asList(CaseStatus.OPEN);
instances = caseRuntimeDataService.getCaseInstancesAnyRole(status, new QueryContext());
assertNotNull(instances);
assertEquals(1, instances.size());
instances = caseRuntimeDataService.getCaseInstancesByRole(null, status, new QueryContext());
assertNotNull(instances);
assertEquals(0, instances.size());
instances = caseRuntimeDataService.getCaseInstancesByRole("owner", status, new QueryContext());
assertNotNull(instances);
assertEquals(1, instances.size());
identityProvider.setName("mary");
instances = caseRuntimeDataService.getCaseInstancesByRole("owner", status, new QueryContext());
assertNotNull(instances);
assertEquals("Mary shouldn't be owner of any opened case instance.", 0, instances.size());
identityProvider.setRoles(Arrays.asList("HR"));
instances = caseRuntimeDataService.getCaseInstancesByRole("contact", status, new QueryContext());
assertNotNull(instances);
assertEquals(1, instances.size());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
identityProvider.setName("john");
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testCaseAuthorization() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
roleAssignments.put("contact", new GroupImpl("HR"));
Map<String, Object> data = new HashMap<>();
data.put("s", "description");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(HR_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(HR_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
identityProvider.setName("mary");
try {
caseService.cancelCase(caseId);
fail("Mary is not owner of the case so should not be allowed to cancel the case");
} catch (SecurityException e) {
// expected
}
try {
caseService.destroyCase(caseId);
fail("Mary is not owner of the case so should not be allowed to destroy the case");
} catch (SecurityException e) {
// expected
}
identityProvider.setName("john");
caseService.cancelCase(caseId);
identityProvider.setName("mary");
try {
caseService.reopenCase(caseId, deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID);
fail("Mary is not owner of the case so should not be allowed to reopen the case");
} catch (SecurityException e) {
// expected
}
identityProvider.setName("john");
caseService.reopenCase(caseId, deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID);
cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(HR_CASE_ID, cInstance.getCaseId());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testCaseAuthorizationImplicitOwner() {
String expectedCaseId = "UniqueID-0000000001";
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("patient", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
data.put("s", "description");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), "CaseWithRolesDefinition", data, roleAssignments);
identityProvider.setName("mary");
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), "CaseWithRolesDefinition", caseFile);
assertNotNull(caseId);
assertEquals(expectedCaseId, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(expectedCaseId, cInstance.getCaseId());
assertEquals("mary", cInstance.getOwner());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
identityProvider.setName("john");
List<TaskSummary> tasks = caseRuntimeDataService.getCaseTasksAssignedAsPotentialOwner(expectedCaseId, "john", Arrays.asList(Status.Reserved), new QueryContext());
assertEquals(1, tasks.size());
userTaskService.completeAutoProgress(tasks.get(0).getId(), "john", null);
identityProvider.setName("mary");
caseService.triggerAdHocFragment(expectedCaseId, "task2", null);
tasks = caseRuntimeDataService.getCaseTasksAssignedAsPotentialOwner(expectedCaseId, "mary", Arrays.asList(Status.Reserved), new QueryContext());
assertEquals(1, tasks.size());
userTaskService.completeAutoProgress(tasks.get(0).getId(), "mary", null);
caseService.triggerAdHocFragment(expectedCaseId, "task3", null);
tasks = caseRuntimeDataService.getCaseTasksAssignedAsPotentialOwner(expectedCaseId, "mary", Arrays.asList(Status.Ready), new QueryContext());
assertEquals(1, tasks.size());
userTaskService.completeAutoProgress(tasks.get(0).getId(), "mary", null);
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
identityProvider.setName("mary");
caseService.cancelCase(caseId);
}
}
}
@Test
public void testTriggerNotExistingAdHocFragment() {
String expectedCaseId = "UniqueID-0000000001";
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("patient", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
data.put("s", "description");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), "CaseWithRolesDefinition", data, roleAssignments);
identityProvider.setName("mary");
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), "CaseWithRolesDefinition", caseFile);
assertNotNull(caseId);
assertEquals(expectedCaseId, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(expectedCaseId, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
identityProvider.setName("john");
List<TaskSummary> tasks = caseRuntimeDataService.getCaseTasksAssignedAsPotentialOwner(expectedCaseId, "john", Arrays.asList(Status.Reserved), new QueryContext());
assertEquals(1, tasks.size());
userTaskService.completeAutoProgress(tasks.get(0).getId(), "john", null);
identityProvider.setName("mary");
try {
caseService.triggerAdHocFragment(expectedCaseId, "not existing", null);
fail("There is no ad hoc fragment with name 'not existing'");
} catch (AdHocFragmentNotFoundException e) {
// expected
}
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
identityProvider.setName("mary");
caseService.cancelCase(caseId);
}
}
}
@Test
public void testTriggerAdHocTasksFromCurrentAndNextStage() {
identityProvider.setName("john");
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
data.put("customData", "none");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), TWO_STAGES_CONDITIONS_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), TWO_STAGES_CONDITIONS_CASE_P_ID, caseFile);
assertNotNull(caseId);
try {
Collection<CaseStageInstance> stages = caseRuntimeDataService.getCaseInstanceStages(caseId, false, null);
assertThat(stages).isNotNull().hasSize(2);
Iterator<CaseStageInstance> iterator = stages.iterator();
CaseStageInstance stage1 = iterator.next();
assertThat(stage1.getName()).isEqualTo("Stage One");
assertThat(stage1.getStatus()).isEqualTo(StageStatus.Active);
CaseStageInstance stage2 = iterator.next();
assertThat(stage2.getName()).isEqualTo("Stage Two");
assertThat(stage2.getStatus()).isEqualTo(StageStatus.Available);
List<TaskSummary> tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertThat(tasks).isNotNull().isEmpty();
caseService.triggerAdHocFragment(caseId, "Task 1", null);
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertThat(tasks).isNotNull().hasSize(1);
assertTask(tasks.get(0), "john", "Task 1", Status.Reserved);
caseService.triggerAdHocFragment(caseId, "Task 2", null);
// the task from the next stage should not be triggered
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertThat(tasks).isNotNull().hasSize(1);
assertTask(tasks.get(0), "john", "Task 1", Status.Reserved);
Map<String, Object> params = Collections.singletonMap("myData", "nextStage");
userTaskService.completeAutoProgress(tasks.get(0).getId(), "john", params);
stages = caseRuntimeDataService.getCaseInstanceStages(caseId, false, null);
assertThat(stages).isNotNull().hasSize(2);
iterator = stages.iterator();
stage1 = iterator.next();
assertThat(stage1.getName()).isEqualTo("Stage One");
assertThat(stage1.getStatus()).isEqualTo(StageStatus.Completed);
stage2 = iterator.next();
assertThat(stage2.getName()).isEqualTo("Stage Two");
assertThat(stage2.getStatus()).isEqualTo(StageStatus.Active);
caseService.triggerAdHocFragment(caseId, "Task 2", null);
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertThat(tasks).isNotNull().hasSize(1);
assertTask(tasks.get(0), "john", "Task 2", Status.Reserved);
caseService.triggerAdHocFragment(caseId, "Task 1", null);
// the task from the previous stage should not be triggered
tasks = runtimeDataService.getTasksAssignedAsPotentialOwner("john", new QueryFilter());
assertThat(tasks).isNotNull().hasSize(1);
assertTask(tasks.get(0), "john", "Task 2", Status.Reserved);
params = Collections.singletonMap("myData", "none");
userTaskService.completeAutoProgress(tasks.get(0).getId(), "john", params);
assertThatThrownBy(() -> caseService.getCaseInstance(caseId)).isInstanceOf(CaseNotFoundException.class);
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
caseService.cancelCase(caseId);
fail("Unexpected exception " + e.getMessage());
}
}
@Test
public void testTriggerMultipleAdHocTasks() {
identityProvider.setName("john");
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
data.put("customData", "none");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), TWO_STAGES_CONDITIONS_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), TWO_STAGES_CONDITIONS_CASE_P_ID, caseFile);
assertThat(caseId).isNotNull();
try {
List<TaskSummary> tasks = caseRuntimeDataService.getCaseTasksAssignedAsPotentialOwner(caseId, "john", null, new QueryContext());
assertThat(tasks).isNotNull().isEmpty();
caseService.triggerAdHocFragment(caseId, "Task 1", null);
tasks = caseRuntimeDataService.getCaseTasksAssignedAsPotentialOwner(caseId, "john", null, new QueryContext());
assertThat(tasks).isNotNull().hasSize(1);
assertThat(tasks).extracting(TaskSummary::getName).containsOnly("Task 1");
caseService.triggerAdHocFragment(caseId, "Task 1", null);
tasks = caseRuntimeDataService.getCaseTasksAssignedAsPotentialOwner(caseId, "john", null, new QueryContext());
assertThat(tasks).isNotNull().hasSize(2);
assertThat(tasks).extracting(TaskSummary::getName).containsOnly("Task 1");
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
caseService.cancelCase(caseId);
}
}
@Test
public void testStartEmptyCaseUsingLoggedInOwner() {
identityProvider.setName("mary");
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals("mary", cInstance.getOwner());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
String initiator = (String) processService.getProcessInstanceVariable(((CaseInstanceImpl) cInstance).getProcessInstanceId(), "initiator");
assertEquals("mary", initiator);
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseChangeOwner() {
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data, new HashMap<>());
identityProvider.setName("mary");
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals("mary", cInstance.getOwner());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
String initiator = (String) processService.getProcessInstanceVariable(((CaseInstanceImpl) cInstance).getProcessInstanceId(), "initiator");
assertEquals("mary", initiator);
caseService.removeFromCaseRole(caseId, "owner", new UserImpl("mary"));
caseService.assignToCaseRole(caseId, "owner", new UserImpl("john"));
identityProvider.setName("john");
cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals("john", cInstance.getOwner());
initiator = (String) processService.getProcessInstanceVariable(((CaseInstanceImpl) cInstance).getProcessInstanceId(), "initiator");
assertEquals("mary", initiator);
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseUsingCaseFileOwner() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data, roleAssignments);
identityProvider.setName("mary");
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
identityProvider.setName("john");
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals("john", cInstance.getOwner());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
String initiator = (String) processService.getProcessInstanceVariable(((CaseInstanceImpl) cInstance).getProcessInstanceId(), "initiator");
assertEquals("mary", initiator);
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testStartEmptyCaseUsingCaseFileOwnerAsLoggedInUser() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("mary"));
Map<String, Object> data = new HashMap<>();
data.put("name", "my first case");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, data, roleAssignments);
identityProvider.setName("mary");
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), EMPTY_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals("mary", cInstance.getOwner());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
String initiator = (String) processService.getProcessInstanceVariable(((CaseInstanceImpl) cInstance).getProcessInstanceId(), "initiator");
assertEquals("mary", initiator);
caseService.cancelCase(caseId);
try {
caseService.getCaseInstance(caseId);
fail("Case was aborted so it should not be found any more");
} catch (CaseNotFoundException e) {
// expected as it was aborted
}
caseId = null;
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testUserTaskToCaseWithStageCompleteCaseDataItem() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
Collection<CaseFileItem> caseFileItems = caseRuntimeDataService.getCaseInstanceDataItems(caseId, new QueryContext());
assertNotNull(caseFileItems);
assertEquals(0, caseFileItems.size());
Collection<CaseStageInstance> activeStages = caseRuntimeDataService.getCaseInstanceStages(caseId, true, new QueryContext());
assertNotNull(activeStages);
assertEquals(1, activeStages.size());
caseService.addDataToCaseFile(caseId, "dataComplete", true);
activeStages = caseRuntimeDataService.getCaseInstanceStages(caseId, true, new QueryContext());
assertNotNull(activeStages);
assertEquals(0, activeStages.size());
caseFileItems = caseRuntimeDataService.getCaseInstanceDataItems(caseId, new QueryContext());
assertNotNull(caseFileItems);
assertEquals(1, caseFileItems.size());
CaseFileItem dataItem = caseFileItems.iterator().next();
assertNotNull(dataItem);
assertEquals(caseId, dataItem.getCaseId());
assertEquals("dataComplete", dataItem.getName());
assertEquals("true", dataItem.getValue());
assertEquals(Boolean.class.getName(), dataItem.getType());
assertEquals(identityProvider.getName(), dataItem.getLastModifiedBy());
assertNotNull(dataItem.getLastModified());
caseService.addDataToCaseFile(caseId, "anotherDataItem", "first version");
caseFileItems = caseRuntimeDataService.getCaseInstanceDataItems(caseId, new QueryContext());
assertNotNull(caseFileItems);
assertEquals(2, caseFileItems.size());
dataItem = caseFileItems.iterator().next();
assertNotNull(dataItem);
assertEquals(caseId, dataItem.getCaseId());
assertEquals("anotherDataItem", dataItem.getName());
assertEquals("first version", dataItem.getValue());
assertEquals(String.class.getName(), dataItem.getType());
assertEquals(identityProvider.getName(), dataItem.getLastModifiedBy());
assertNotNull(dataItem.getLastModified());
caseService.addDataToCaseFile(caseId, "anotherDataItem", "second version");
caseFileItems = caseRuntimeDataService.getCaseInstanceDataItems(caseId, new QueryContext());
assertNotNull(caseFileItems);
assertEquals(2, caseFileItems.size());
dataItem = caseFileItems.iterator().next();
assertNotNull(dataItem);
assertEquals(caseId, dataItem.getCaseId());
assertEquals("anotherDataItem", dataItem.getName());
assertEquals("second version", dataItem.getValue());
assertEquals(String.class.getName(), dataItem.getType());
assertEquals(identityProvider.getName(), dataItem.getLastModifiedBy());
assertNotNull(dataItem.getLastModified());
caseService.removeDataFromCaseFile(caseId, "anotherDataItem");
caseFileItems = caseRuntimeDataService.getCaseInstanceDataItems(caseId, new QueryContext());
assertNotNull(caseFileItems);
assertEquals(1, caseFileItems.size());
identityProvider.setName("mary");
caseFileItems = caseRuntimeDataService.getCaseInstanceDataItems(caseId, new QueryContext());
assertNotNull(caseFileItems);
// mary is not involved in case isntance
assertEquals(0, caseFileItems.size());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
identityProvider.setName("john");
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testUserTaskToCaseSearchByCaseFileData() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_STAGE_CASE_P_ID, caseFile);
assertNotNull(caseId);
assertEquals(FIRST_CASE_ID, caseId);
try {
CaseInstance cInstance = caseService.getCaseInstance(caseId);
assertNotNull(cInstance);
assertEquals(FIRST_CASE_ID, cInstance.getCaseId());
assertEquals(deploymentUnit.getIdentifier(), cInstance.getDeploymentId());
caseService.addDataToCaseFile(caseId, "dataComplete", true);
Collection<CaseInstance> byCaseData = caseRuntimeDataService.getCaseInstancesByDateItem("dataComplete", Arrays.asList(CaseStatus.OPEN), new QueryContext());
assertNotNull(byCaseData);
assertEquals(1, byCaseData.size());
byCaseData = caseRuntimeDataService.getCaseInstancesByDateItemAndValue("dataComplete", "false", Arrays.asList(CaseStatus.OPEN), new QueryContext());
assertNotNull(byCaseData);
assertEquals(0, byCaseData.size());
byCaseData = caseRuntimeDataService.getCaseInstancesByDateItemAndValue("dataComplete", "true", Arrays.asList(CaseStatus.OPEN), new QueryContext());
assertNotNull(byCaseData);
assertEquals(1, byCaseData.size());
identityProvider.setName("mary");
byCaseData = caseRuntimeDataService.getCaseInstancesByDateItem("dataComplete", Arrays.asList(CaseStatus.OPEN), new QueryContext());
assertNotNull(byCaseData);
// mary is not part of the case instance
assertEquals(0, byCaseData.size());
} catch (Exception e) {
logger.error("Unexpected error {}", e.getMessage(), e);
fail("Unexpected exception " + e.getMessage());
} finally {
identityProvider.setName("john");
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
@Test
public void testCaseRolesCardinality() {
Map<String, OrganizationalEntity> roleAssignments = new HashMap<>();
roleAssignments.put("owner", new UserImpl("john"));
Map<String, Object> data = new HashMap<>();
data.put("s", "description");
CaseFileInstance caseFile = caseService.newCaseFileInstance(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, data, roleAssignments);
String caseId = caseService.startCase(deploymentUnit.getIdentifier(), USER_TASK_CASE_P_ID, caseFile);
try {
caseService.assignToCaseRole(caseId, "contact", new UserImpl("mary"));
caseService.assignToCaseRole(caseId, "contact", new UserImpl("steve"));
Throwable error = Assertions.catchThrowable(() -> caseService.assignToCaseRole(caseId, "contact", new UserImpl("jack")));
assertThat(error).isInstanceOf(IllegalArgumentException.class).hasMessageContaining("Cannot add more users for role contact, maximum cardinality 2 already reached");
} finally {
if (caseId != null) {
caseService.cancelCase(caseId);
}
}
}
}