@@ -380,6 +380,95 @@ public void testSetCurrentParentExecutionOfParallelMultiInstanceTask() {
380380
381381 assertProcessEnded (processInstance .getId ());
382382 }
383+
384+ @ Test
385+ @ Deployment (resources = "org/flowable/engine/test/api/multiInstanceTwoParallelTasks.bpmn20.xml" )
386+ public void testSetCurrentActivityToOtherParallelMultiInstanceTask () {
387+ ProcessInstance processInstance = runtimeService .createProcessInstanceBuilder ().processDefinitionKey ("parallelMultiInstance" )
388+ .variable ("nrOfLoops" , 3 )
389+ .start ();
390+
391+ Task task = taskService .createTaskQuery ().processInstanceId (processInstance .getId ()).singleResult ();
392+ assertThat (task .getTaskDefinitionKey ()).isEqualTo ("beforeMultiInstance" );
393+ taskService .complete (task .getId ());
394+
395+ List <Execution > executions = runtimeService .createExecutionQuery ().processInstanceId (processInstance .getId ()).onlyChildExecutions ().list ();
396+ assertThat (executions ).hasSize (4 );
397+ List <Task > tasks = taskService .createTaskQuery ().processInstanceId (processInstance .getId ()).list ();
398+ assertThat (tasks ).hasSize (3 );
399+
400+ runtimeService .createChangeActivityStateBuilder ()
401+ .processInstanceId (processInstance .getId ())
402+ .moveActivityIdTo ("parallelTasks1" , "parallelTasks2" )
403+ .changeState ();
404+
405+ // First in the loop
406+ executions = runtimeService .createExecutionQuery ().processInstanceId (processInstance .getId ()).onlyChildExecutions ().list ();
407+ // One MI root and 3 parallel Executions
408+ assertThat (executions )
409+ .extracting (Execution ::getActivityId )
410+ .containsExactly ("parallelTasks2" , "parallelTasks2" , "parallelTasks2" , "parallelTasks2" );
411+
412+ Execution miRoot = executions .stream ().filter (e -> ((ExecutionEntity ) e ).isMultiInstanceRoot ()).findFirst ().get ();
413+ Map <String , Object > miRootVars = runtimeService .getVariables (miRoot .getId ());
414+ assertThat (miRootVars )
415+ .extracting ("nrOfActiveInstances" , "nrOfCompletedInstances" , "nrOfLoops" )
416+ .containsExactly (3 , 0 , 3 );
417+
418+ tasks = taskService .createTaskQuery ().processInstanceId (processInstance .getId ()).active ().list ();
419+ assertThat (tasks )
420+ .extracting (Task ::getTaskDefinitionKey )
421+ .containsExactly ("parallelTasks2" , "parallelTasks2" , "parallelTasks2" );
422+ assertThat (tasks )
423+ .extracting (taskEntity -> taskService .getVariable (taskEntity .getId (), "loopCounter" ))
424+ .isNotNull ();
425+
426+ // Complete one execution
427+ taskService .complete (tasks .get (0 ).getId ());
428+
429+ // Confirm new state
430+ executions = runtimeService .createExecutionQuery ().processInstanceId (processInstance .getId ()).onlyChildExecutions ().list ();
431+ assertThat (executions )
432+ .extracting (Execution ::getActivityId )
433+ .containsExactly ("parallelTasks2" , "parallelTasks2" , "parallelTasks2" , "parallelTasks2" );
434+
435+ miRoot = executions .stream ().filter (e -> ((ExecutionEntity ) e ).isMultiInstanceRoot ()).findFirst ().get ();
436+ miRootVars = runtimeService .getVariables (miRoot .getId ());
437+ assertThat (miRootVars )
438+ .extracting ("nrOfActiveInstances" , "nrOfCompletedInstances" , "nrOfLoops" )
439+ .containsExactly (2 , 1 , 3 );
440+
441+ // Two executions are inactive, the completed before and the MI root
442+ assertThat (executions )
443+ .haveExactly (2 , new Condition <>((Execution execution ) -> !((ExecutionEntity ) execution ).isActive (), "inactive" ));
444+
445+ tasks = taskService .createTaskQuery ().processInstanceId (processInstance .getId ()).active ().list ();
446+ assertThat (tasks )
447+ .extracting (Task ::getTaskDefinitionKey )
448+ .containsExactly ("parallelTasks2" , "parallelTasks2" );
449+ assertThat (taskService .getVariable (tasks .get (0 ).getId (), "loopCounter" )).isEqualTo (1 );
450+
451+ // Complete the rest of the Tasks
452+ tasks .forEach (this ::completeTask );
453+
454+ // After the MI
455+ executions = runtimeService .createExecutionQuery ().processInstanceId (processInstance .getId ()).onlyChildExecutions ().list ();
456+ assertThat (executions )
457+ .extracting (Execution ::getActivityId )
458+ .containsExactly ("nextTask" );
459+ assertThat ((ExecutionEntity ) executions .get (0 ))
460+ .extracting (ExecutionEntity ::isMultiInstanceRoot ).isEqualTo (false );
461+
462+ task = taskService .createTaskQuery ().processInstanceId (processInstance .getId ()).active ().singleResult ();
463+ assertThat (task )
464+ .extracting (Task ::getTaskDefinitionKey )
465+ .isEqualTo ("nextTask" );
466+ assertThat (taskService .getVariable (task .getId (), "loopCounter" )).isNull ();
467+
468+ //Complete the process
469+ taskService .complete (task .getId ());
470+ assertProcessEnded (processInstance .getId ());
471+ }
383472
384473 @ Test
385474 @ Deployment (resources = "org/flowable/engine/test/api/multiInstanceParallelSubProcess.bpmn20.xml" )
0 commit comments