You must all "do engine steps" when completing a task so that it will kick off any automatic tasks/decisions/etc... this will update remaining tasks. Added some tests for parallel, since I wrote them trying to debug this.

This commit is contained in:
Dan Funk 2020-02-03 15:15:36 -05:00
parent 8cc04aaad2
commit 8fbbed4feb
5 changed files with 100 additions and 3 deletions

View File

@ -109,6 +109,7 @@ def update_task(workflow_id, task_id, body):
task = processor.bpmn_workflow.get_task(task_id)
task.data = body
processor.complete_task(task)
processor.do_engine_steps()
workflow.bpmn_workflow_json = processor.serialize()
session.add(workflow)
session.commit()

View File

@ -11,6 +11,7 @@ class FileType(enum.Enum):
bpmn = "bpmm"
svg = "svg"
dmn = "dmn"
# docx = "docx"
class FileDataModel(db.Model):
@ -31,6 +32,7 @@ class FileModel(db.Model):
primary = db.Column(db.Boolean)
content_type = db.Column(db.String)
workflow_spec_id = db.Column(db.String, db.ForeignKey('workflow_spec.id'))
# workflow_id = db.Column(db.String, db.ForeignKey('workflow.id'))
class FileModelSchema(ModelSchema):

View File

@ -51,7 +51,11 @@ class ExampleDataLoader:
name="parallel_tasks",
display_name="Parallel tasks",
description='Four tasks that can happen simultaneously')
# workflow_specifications += \
# self.create_spec(id="docx",
# name="docx",
# display_name="Form with document generation",
# description='the name says it all')
all_data = studies + workflow_specifications
return all_data
@ -73,11 +77,13 @@ class ExampleDataLoader:
noise, file_extension = os.path.splitext(file_path)
filename = os.path.basename(file_path)
if file_extension.lower() == '.bpmn':
type=FileType.bpmn
type = FileType.bpmn
elif file_extension.lower() == '.dmn':
type=FileType.dmn
type = FileType.dmn
elif file_extension.lower() == '.svg':
type = FileType.svg
# elif file_extension.lower() == '.docx':
# type = FileType.docx
else:
raise Exception("Unsupported file type:" + file_path)
continue

View File

@ -240,3 +240,28 @@ class TestStudy(BaseTest):
self.assertIsNotNone(task.data)
for val in task.data.values():
self.assertIsNotNone(val)
# def test_workflow_with_parallel_forms(self):
# self.load_example_data()
# study = session.query(StudyModel).first()
# spec = session.query(WorkflowSpecModel).filter_by(id='parallel_forms').first()
# rv = self.app.post('/v1.0/study/%i/workflows' % study.id, content_type="application/json",
# data=json.dumps(WorkflowSpecModelSchema().dump(spec)))
# json_data = json.loads(rv.get_data(as_text=True))
# workflow = WorkflowModelSchema().load(json_data, session=session)
#
# # get the first form in the two form workflow.
# rv = self.app.get('/v1.0/workflow/%i/tasks' % workflow.id, content_type="application/json")
# json_data = json.loads(rv.get_data(as_text=True))
# tasks = TaskSchema(many=True).load(json_data)
# rv = self.app.put('/v1.0/workflow/%i/task/%s/data' % (workflow.id, tasks[0].id),
# content_type="application/json",
# data=json.dumps({"color": "blue"}))
# self.assert_success(rv)
#
# # Get the next Task
# rv = self.app.get('/v1.0/workflow/%i/tasks' % study.id, content_type="application/json")
# self.assert_success(rv)
# json_data = json.loads(rv.get_data(as_text=True))
# tasks = TaskSchema(many=True).load(json_data)
# self.assertEqual("StepTwo", tasks[0].name)

View File

@ -1,3 +1,6 @@
import string
import random
from crc import session
from crc.models.file import FileModel
from crc.models.workflow import WorkflowSpecModel, WorkflowStatus
@ -52,3 +55,63 @@ class TestWorkflowProcessor(BaseTest):
self.assertIsNotNone(data)
self.assertIn("message", data)
self.assertEqual("Oh, Ginger.", data.get('message'))
def test_workflow_with_parallel_forms(self):
self.load_example_data()
workflow_spec_model = session.query(WorkflowSpecModel).filter_by(id="parallel_tasks").first()
processor = WorkflowProcessor.create(workflow_spec_model.id)
self.assertEqual(WorkflowStatus.user_input_required, processor.get_status())
next_user_tasks = processor.next_user_tasks()
self.assertEqual(4, len(next_user_tasks))
self._complete_form_with_random_data(next_user_tasks[0])
self._complete_form_with_random_data(next_user_tasks[1])
self._complete_form_with_random_data(next_user_tasks[2])
self._complete_form_with_random_data(next_user_tasks[3])
processor.complete_task(next_user_tasks[0])
processor.complete_task(next_user_tasks[1])
processor.complete_task(next_user_tasks[2])
processor.complete_task(next_user_tasks[3])
# There are another 4 tasks to complete (each task, had a follow up task in the parallel list)
next_user_tasks = processor.next_user_tasks()
self.assertEqual(4, len(next_user_tasks))
self._complete_form_with_random_data(next_user_tasks[0])
self._complete_form_with_random_data(next_user_tasks[1])
self._complete_form_with_random_data(next_user_tasks[2])
self._complete_form_with_random_data(next_user_tasks[3])
processor.complete_task(next_user_tasks[0])
processor.complete_task(next_user_tasks[1])
processor.complete_task(next_user_tasks[2])
processor.complete_task(next_user_tasks[3])
processor.do_engine_steps()
self.assertTrue(processor.bpmn_workflow.is_completed())
# def test_workflow_with_docx_template(self):
# self.load_example_data()
# files = session.query(FileModel).filter_by(workflow_spec_id='docx').all()
# self.assertEquals(2, len(files))
# workflow_spec_model = session.query(WorkflowSpecModel).filter_by(id="docx").first()
# processor = WorkflowProcessor.create(workflow_spec_model.id)
# self.assertEqual(WorkflowStatus.user_input_required, processor.get_status())
# next_user_tasks = processor.next_user_tasks()
# self.assertEqual(1, len(next_user_tasks))
# task = next_user_tasks[0]
# self.assertEqual("task_gather_information", task.get_name())
# self._complete_form_with_random_data(task)
# processor.complete_task(task)
# processor.do_engine_steps()
# workflow_files = session.query(FileModel).filter_by(workflow_id=).all()
def _randomString(self, stringLength=10):
"""Generate a random string of fixed length """
letters = string.ascii_lowercase
return ''.join(random.choice(letters) for i in range(stringLength))
def _complete_form_with_random_data(self,task):
form_data = {}
for field in task.task_spec.form.fields:
form_data[field.id] = self._randomString()
if task.data is None:
task.data = {}
task.data.update(form_data)