2020-04-13 20:23:31 +00:00
|
|
|
from unittest.mock import patch
|
|
|
|
|
2020-04-30 19:39:11 +00:00
|
|
|
from crc import session
|
2020-04-21 15:43:43 +00:00
|
|
|
from crc.models.api_models import MultiInstanceType
|
2020-04-13 20:23:31 +00:00
|
|
|
from crc.models.study import StudyModel
|
2020-04-30 19:39:11 +00:00
|
|
|
from crc.models.workflow import WorkflowStatus
|
2020-04-13 20:23:31 +00:00
|
|
|
from crc.services.study_service import StudyService
|
2020-04-30 19:39:11 +00:00
|
|
|
from crc.services.workflow_processor import WorkflowProcessor
|
2020-04-19 19:14:10 +00:00
|
|
|
from crc.services.workflow_service import WorkflowService
|
2020-04-13 20:23:31 +00:00
|
|
|
from tests.base_test import BaseTest
|
|
|
|
|
|
|
|
|
|
|
|
class TestWorkflowProcessorMultiInstance(BaseTest):
|
|
|
|
"""Tests the Workflow Processor as it deals with a Multi-Instance task"""
|
|
|
|
|
2020-05-07 17:57:24 +00:00
|
|
|
mock_investigator_response = {'PI': {
|
|
|
|
'label': 'Primary Investigator',
|
|
|
|
'display': 'Always',
|
|
|
|
'unique': 'Yes',
|
|
|
|
'user_id': 'dhf8r',
|
|
|
|
'display_name': 'Dan Funk'},
|
|
|
|
'SC_I': {
|
|
|
|
'label': 'Study Coordinator I',
|
|
|
|
'display': 'Always',
|
|
|
|
'unique': 'Yes',
|
|
|
|
'user_id': None},
|
|
|
|
'DC': {
|
|
|
|
'label': 'Department Contact',
|
|
|
|
'display': 'Optional',
|
|
|
|
'unique': 'Yes',
|
|
|
|
'user_id': 'asd3v',
|
|
|
|
'error': 'Unable to locate a user with id asd3v in LDAP'}}
|
2020-04-13 20:23:31 +00:00
|
|
|
|
|
|
|
def _populate_form_with_random_data(self, task):
|
|
|
|
WorkflowProcessor.populate_form_with_random_data(task)
|
|
|
|
|
|
|
|
def get_processor(self, study_model, spec_model):
|
|
|
|
workflow_model = StudyService._create_workflow_model(study_model, spec_model)
|
|
|
|
return WorkflowProcessor(workflow_model)
|
|
|
|
|
2020-05-07 17:57:24 +00:00
|
|
|
@patch('crc.services.study_service.StudyService.get_investigators')
|
|
|
|
def test_create_and_complete_workflow(self, mock_study_service):
|
2020-04-13 20:23:31 +00:00
|
|
|
# This depends on getting a list of investigators back from the protocol builder.
|
2020-05-07 17:57:24 +00:00
|
|
|
mock_study_service.return_value = self.mock_investigator_response
|
2020-04-13 20:23:31 +00:00
|
|
|
|
|
|
|
self.load_example_data()
|
|
|
|
workflow_spec_model = self.load_test_spec("multi_instance")
|
|
|
|
study = session.query(StudyModel).first()
|
|
|
|
processor = self.get_processor(study, workflow_spec_model)
|
|
|
|
self.assertEqual(study.id, processor.bpmn_workflow.data[WorkflowProcessor.STUDY_ID_KEY])
|
|
|
|
self.assertIsNotNone(processor)
|
|
|
|
self.assertEqual(WorkflowStatus.user_input_required, processor.get_status())
|
2020-04-19 19:14:10 +00:00
|
|
|
processor.bpmn_workflow.do_engine_steps()
|
2020-04-13 20:23:31 +00:00
|
|
|
next_user_tasks = processor.next_user_tasks()
|
|
|
|
self.assertEqual(1, len(next_user_tasks))
|
2020-04-15 20:32:29 +00:00
|
|
|
|
2020-04-13 20:23:31 +00:00
|
|
|
task = next_user_tasks[0]
|
2020-04-15 20:32:29 +00:00
|
|
|
|
2020-04-13 20:23:31 +00:00
|
|
|
self.assertEqual(WorkflowStatus.user_input_required, processor.get_status())
|
2020-05-07 17:57:24 +00:00
|
|
|
self.assertEquals("dhf8r", task.data["investigator"]["user_id"])
|
2020-04-15 20:32:29 +00:00
|
|
|
|
|
|
|
self.assertEqual("MutiInstanceTask", task.get_name())
|
2020-04-19 19:14:10 +00:00
|
|
|
api_task = WorkflowService.spiff_task_to_api_task(task)
|
2020-05-15 19:54:53 +00:00
|
|
|
self.assertEquals(MultiInstanceType.sequential, api_task.multiInstanceType)
|
|
|
|
self.assertEquals(3, api_task.multiInstanceCount)
|
|
|
|
self.assertEquals(1, api_task.multiInstanceIndex)
|
2020-05-06 14:59:49 +00:00
|
|
|
task.update_data({"investigator":{"email":"asd3v@virginia.edu"}})
|
2020-04-13 20:23:31 +00:00
|
|
|
processor.complete_task(task)
|
2020-04-15 20:32:29 +00:00
|
|
|
processor.do_engine_steps()
|
2020-04-13 20:23:31 +00:00
|
|
|
|
2020-04-15 20:32:29 +00:00
|
|
|
task = next_user_tasks[0]
|
2020-04-19 19:14:10 +00:00
|
|
|
api_task = WorkflowService.spiff_task_to_api_task(task)
|
|
|
|
self.assertEqual("MutiInstanceTask", api_task.name)
|
2020-05-06 14:59:49 +00:00
|
|
|
task.update_data({"investigator":{"email":"asdf32@virginia.edu"}})
|
2020-05-15 19:54:53 +00:00
|
|
|
self.assertEquals(3, api_task.multiInstanceCount)
|
|
|
|
self.assertEquals(2, api_task.multiInstanceIndex)
|
2020-04-15 20:32:29 +00:00
|
|
|
processor.complete_task(task)
|
|
|
|
processor.do_engine_steps()
|
2020-04-13 20:23:31 +00:00
|
|
|
|
2020-04-15 20:32:29 +00:00
|
|
|
task = next_user_tasks[0]
|
2020-04-19 19:14:10 +00:00
|
|
|
api_task = WorkflowService.spiff_task_to_api_task(task)
|
2020-04-15 20:32:29 +00:00
|
|
|
self.assertEqual("MutiInstanceTask", task.get_name())
|
2020-05-06 14:59:49 +00:00
|
|
|
task.update_data({"investigator":{"email":"dhf8r@virginia.edu"}})
|
2020-05-15 19:54:53 +00:00
|
|
|
self.assertEquals(3, api_task.multiInstanceCount)
|
|
|
|
self.assertEquals(3, api_task.multiInstanceIndex)
|
2020-04-15 20:32:29 +00:00
|
|
|
processor.complete_task(task)
|
2020-04-13 20:23:31 +00:00
|
|
|
processor.do_engine_steps()
|
2020-05-06 14:59:49 +00:00
|
|
|
task = processor.bpmn_workflow.last_task
|
2020-04-15 20:32:29 +00:00
|
|
|
|
2020-05-07 17:57:24 +00:00
|
|
|
expected = self.mock_investigator_response
|
|
|
|
expected['PI']['email'] = "asd3v@virginia.edu"
|
|
|
|
expected['SC_I']['email'] = "asdf32@virginia.edu"
|
|
|
|
expected['DC']['email'] = "dhf8r@virginia.edu"
|
|
|
|
self.assertEquals(expected,
|
2020-04-15 20:32:29 +00:00
|
|
|
task.data['StudyInfo']['investigators'])
|
|
|
|
|
2020-04-13 20:23:31 +00:00
|
|
|
self.assertEqual(WorkflowStatus.complete, processor.get_status())
|
2020-04-30 19:39:11 +00:00
|
|
|
|
2020-05-07 17:57:24 +00:00
|
|
|
@patch('crc.services.study_service.StudyService.get_investigators')
|
|
|
|
def test_create_and_complete_workflow_parallel(self, mock_study_service):
|
2020-04-30 19:39:11 +00:00
|
|
|
"""Unlike the test above, the parallel task allows us to complete the items in any order."""
|
|
|
|
|
2020-05-07 17:57:24 +00:00
|
|
|
# This depends on getting a list of investigators back from the protocol builder.
|
|
|
|
mock_study_service.return_value = self.mock_investigator_response
|
2020-04-30 19:39:11 +00:00
|
|
|
|
|
|
|
self.load_example_data()
|
|
|
|
workflow_spec_model = self.load_test_spec("multi_instance_parallel")
|
|
|
|
study = session.query(StudyModel).first()
|
|
|
|
processor = self.get_processor(study, workflow_spec_model)
|
|
|
|
processor.bpmn_workflow.do_engine_steps()
|
|
|
|
|
|
|
|
# In the Parallel instance, there should be three tasks, all of them in the ready state.
|
|
|
|
next_user_tasks = processor.next_user_tasks()
|
|
|
|
self.assertEqual(3, len(next_user_tasks))
|
|
|
|
|
|
|
|
# We can complete the tasks out of order.
|
|
|
|
task = next_user_tasks[2]
|
|
|
|
|
|
|
|
self.assertEqual(WorkflowStatus.user_input_required, processor.get_status())
|
2020-05-07 17:57:24 +00:00
|
|
|
self.assertEquals("asd3v", task.data["investigator"]["user_id"]) # The last of the tasks
|
2020-04-30 19:39:11 +00:00
|
|
|
|
|
|
|
api_task = WorkflowService.spiff_task_to_api_task(task)
|
2020-05-15 19:54:53 +00:00
|
|
|
self.assertEquals(MultiInstanceType.parallel, api_task.multiInstanceType)
|
2020-05-06 14:59:49 +00:00
|
|
|
task.update_data({"investigator":{"email":"dhf8r@virginia.edu"}})
|
2020-04-30 19:39:11 +00:00
|
|
|
processor.complete_task(task)
|
|
|
|
processor.do_engine_steps()
|
|
|
|
|
|
|
|
task = next_user_tasks[0]
|
|
|
|
api_task = WorkflowService.spiff_task_to_api_task(task)
|
|
|
|
self.assertEqual("MutiInstanceTask", api_task.name)
|
2020-05-06 14:59:49 +00:00
|
|
|
task.update_data({"investigator":{"email":"asd3v@virginia.edu"}})
|
2020-04-30 19:39:11 +00:00
|
|
|
processor.complete_task(task)
|
|
|
|
processor.do_engine_steps()
|
|
|
|
|
|
|
|
task = next_user_tasks[1]
|
|
|
|
api_task = WorkflowService.spiff_task_to_api_task(task)
|
|
|
|
self.assertEqual("MutiInstanceTask", task.get_name())
|
2020-05-06 14:59:49 +00:00
|
|
|
task.update_data({"investigator":{"email":"asdf32@virginia.edu"}})
|
2020-04-30 19:39:11 +00:00
|
|
|
processor.complete_task(task)
|
|
|
|
processor.do_engine_steps()
|
|
|
|
|
|
|
|
# Completing the tasks out of order, still provides the correct information.
|
2020-05-07 17:57:24 +00:00
|
|
|
expected = self.mock_investigator_response
|
|
|
|
expected['PI']['email'] = "asd3v@virginia.edu"
|
|
|
|
expected['SC_I']['email'] = "asdf32@virginia.edu"
|
|
|
|
expected['DC']['email'] = "dhf8r@virginia.edu"
|
|
|
|
self.assertEquals(expected,
|
2020-04-30 19:39:11 +00:00
|
|
|
task.data['StudyInfo']['investigators'])
|
|
|
|
|
|
|
|
self.assertEqual(WorkflowStatus.complete, processor.get_status())
|