Merge pull request #163 from sartography/feature/improved_task_event_api

Add a few more details to the workflow metadata model.
This commit is contained in:
Dan Funk 2020-07-30 11:33:06 -04:00 committed by GitHub
commit 2a5f36254e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 25 additions and 15 deletions

View File

@ -40,7 +40,7 @@ class StudyModel(db.Model):
class WorkflowMetadata(object): class WorkflowMetadata(object):
def __init__(self, id, name, display_name, description, spec_version, category_id, state: WorkflowState, status: WorkflowStatus, def __init__(self, id, name, display_name, description, spec_version, category_id, category_display_name, state: WorkflowState, status: WorkflowStatus,
total_tasks, completed_tasks, display_order): total_tasks, completed_tasks, display_order):
self.id = id self.id = id
self.name = name self.name = name
@ -48,6 +48,7 @@ class WorkflowMetadata(object):
self.description = description self.description = description
self.spec_version = spec_version self.spec_version = spec_version
self.category_id = category_id self.category_id = category_id
self.category_display_name = category_display_name
self.state = state self.state = state
self.status = status self.status = status
self.total_tasks = total_tasks self.total_tasks = total_tasks
@ -64,6 +65,7 @@ class WorkflowMetadata(object):
description=workflow.workflow_spec.description, description=workflow.workflow_spec.description,
spec_version=workflow.spec_version(), spec_version=workflow.spec_version(),
category_id=workflow.workflow_spec.category_id, category_id=workflow.workflow_spec.category_id,
category_display_name=workflow.workflow_spec.category.display_name,
state=WorkflowState.optional, state=WorkflowState.optional,
status=workflow.status, status=workflow.status,
total_tasks=workflow.total_tasks, total_tasks=workflow.total_tasks,
@ -79,7 +81,8 @@ class WorkflowMetadataSchema(ma.Schema):
class Meta: class Meta:
model = WorkflowMetadata model = WorkflowMetadata
additional = ["id", "name", "display_name", "description", additional = ["id", "name", "display_name", "description",
"total_tasks", "completed_tasks", "display_order"] "total_tasks", "completed_tasks", "display_order",
"category_id", "category_display_name"]
unknown = INCLUDE unknown = INCLUDE

View File

@ -56,7 +56,6 @@ class TaskEventSchema(ma.Schema):
study = fields.Nested(StudySchema, dump_only=True) study = fields.Nested(StudySchema, dump_only=True)
workflow = fields.Nested(WorkflowMetadataSchema, dump_only=True) workflow = fields.Nested(WorkflowMetadataSchema, dump_only=True)
class Meta: class Meta:
model = TaskEvent model = TaskEvent
additional = ["id", "user_uid", "action", "task_id", "task_title", additional = ["id", "user_uid", "action", "task_id", "task_title",

View File

@ -251,7 +251,6 @@ class ExampleDataLoader:
master_spec=False, master_spec=False,
from_tests=True) from_tests=True)
def create_spec(self, id, name, display_name="", description="", filepath=None, master_spec=False, def create_spec(self, id, name, display_name="", description="", filepath=None, master_spec=False,
category_id=None, display_order=None, from_tests=False): category_id=None, display_order=None, from_tests=False):
"""Assumes that a directory exists in static/bpmn with the same name as the given id. """Assumes that a directory exists in static/bpmn with the same name as the given id.

View File

@ -19,7 +19,7 @@ from crc.models.protocol_builder import ProtocolBuilderStatus
from crc.models.task_event import TaskEventModel from crc.models.task_event import TaskEventModel
from crc.models.study import StudyModel from crc.models.study import StudyModel
from crc.models.user import UserModel from crc.models.user import UserModel
from crc.models.workflow import WorkflowSpecModel, WorkflowSpecModelSchema, WorkflowModel from crc.models.workflow import WorkflowSpecModel, WorkflowSpecModelSchema, WorkflowModel, WorkflowSpecCategoryModel
from crc.services.file_service import FileService from crc.services.file_service import FileService
from crc.services.study_service import StudyService from crc.services.study_service import StudyService
from crc.services.workflow_service import WorkflowService from crc.services.workflow_service import WorkflowService
@ -164,14 +164,21 @@ class BaseTest(unittest.TestCase):
self.assertGreater(len(file_data), 0) self.assertGreater(len(file_data), 0)
@staticmethod @staticmethod
def load_test_spec(dir_name, master_spec=False, category_id=None): def load_test_spec(dir_name, display_name=None, master_spec=False, category_id=None):
"""Loads a spec into the database based on a directory in /tests/data""" """Loads a spec into the database based on a directory in /tests/data"""
if category_id is None:
category = WorkflowSpecCategoryModel(name="test", display_name="Test Workflows", display_order=0)
db.session.add(category)
db.session.commit()
category_id = category.id
if session.query(WorkflowSpecModel).filter_by(id=dir_name).count() > 0: if session.query(WorkflowSpecModel).filter_by(id=dir_name).count() > 0:
return session.query(WorkflowSpecModel).filter_by(id=dir_name).first() return session.query(WorkflowSpecModel).filter_by(id=dir_name).first()
filepath = os.path.join(app.root_path, '..', 'tests', 'data', dir_name, "*") filepath = os.path.join(app.root_path, '..', 'tests', 'data', dir_name, "*")
if display_name is None:
display_name = dir_name
return ExampleDataLoader().create_spec(id=dir_name, name=dir_name, filepath=filepath, master_spec=master_spec, return ExampleDataLoader().create_spec(id=dir_name, name=dir_name, filepath=filepath, master_spec=master_spec,
category_id=category_id) display_name=display_name, category_id=category_id)
@staticmethod @staticmethod
def protocol_builder_response(file_name): def protocol_builder_response(file_name):
@ -263,11 +270,13 @@ class BaseTest(unittest.TestCase):
return full_study return full_study
def create_workflow(self, workflow_name, study=None, category_id=None, as_user="dhf8r"): def create_workflow(self, workflow_name, display_name=None, study=None, category_id=None, as_user="dhf8r"):
db.session.flush() db.session.flush()
spec = db.session.query(WorkflowSpecModel).filter(WorkflowSpecModel.name == workflow_name).first() spec = db.session.query(WorkflowSpecModel).filter(WorkflowSpecModel.name == workflow_name).first()
if spec is None: if spec is None:
spec = self.load_test_spec(workflow_name, category_id=category_id) if display_name is None:
display_name = workflow_name
spec = self.load_test_spec(workflow_name, display_name, category_id=category_id)
if study is None: if study is None:
study = self.create_study(uid=as_user) study = self.create_study(uid=as_user)
workflow_model = StudyService._create_workflow_model(study, spec) workflow_model = StudyService._create_workflow_model(study, spec)

View File

@ -27,7 +27,10 @@ class TestStudyService(BaseTest):
# Assure some basic models are in place, This is a damn mess. Our database models need an overhaul to make # Assure some basic models are in place, This is a damn mess. Our database models need an overhaul to make
# this easier - better relationship modeling is now critical. # this easier - better relationship modeling is now critical.
self.load_test_spec("top_level_workflow", master_spec=True) cat = WorkflowSpecCategoryModel(name="approvals", display_name="Approvals", display_order=0)
db.session.add(cat)
db.session.commit()
self.load_test_spec("top_level_workflow", master_spec=True, category_id=cat.id)
user = db.session.query(UserModel).filter(UserModel.uid == "dhf8r").first() user = db.session.query(UserModel).filter(UserModel.uid == "dhf8r").first()
if not user: if not user:
user = UserModel(uid="dhf8r", email_address="whatever@stuff.com", display_name="Stayathome Smellalots") user = UserModel(uid="dhf8r", email_address="whatever@stuff.com", display_name="Stayathome Smellalots")
@ -39,11 +42,7 @@ class TestStudyService(BaseTest):
study = StudyModel(title="My title", protocol_builder_status=ProtocolBuilderStatus.ACTIVE, user_uid=user.uid) study = StudyModel(title="My title", protocol_builder_status=ProtocolBuilderStatus.ACTIVE, user_uid=user.uid)
db.session.add(study) db.session.add(study)
cat = WorkflowSpecCategoryModel(name="approvals", display_name="Approvals", display_order=0)
db.session.add(cat)
db.session.commit()
self.assertIsNotNone(cat.id)
self.load_test_spec("random_fact", category_id=cat.id) self.load_test_spec("random_fact", category_id=cat.id)
self.assertIsNotNone(study.id) self.assertIsNotNone(study.id)

View File

@ -68,7 +68,7 @@ class TestTasksApi(BaseTest):
def test_get_outstanding_tasks_awaiting_current_user(self): def test_get_outstanding_tasks_awaiting_current_user(self):
submitter = self.create_user(uid='lje5u') submitter = self.create_user(uid='lje5u')
supervisor = self.create_user(uid='lb3dp') supervisor = self.create_user(uid='lb3dp')
workflow = self.create_workflow('roles', as_user=submitter.uid) workflow = self.create_workflow('roles', display_name="Roles", as_user=submitter.uid)
workflow_api = self.get_workflow_api(workflow, user_uid=submitter.uid) workflow_api = self.get_workflow_api(workflow, user_uid=submitter.uid)
# User lje5u can complete the first task, and set her supervisor # User lje5u can complete the first task, and set her supervisor
@ -94,6 +94,7 @@ class TestTasksApi(BaseTest):
self.assertEquals(1, len(tasks)) self.assertEquals(1, len(tasks))
self.assertEquals(workflow.id, tasks[0]['workflow']['id']) self.assertEquals(workflow.id, tasks[0]['workflow']['id'])
self.assertEquals(workflow.study.id, tasks[0]['study']['id']) self.assertEquals(workflow.study.id, tasks[0]['study']['id'])
self.assertEquals("Test Workflows", tasks[0]['workflow']['category_display_name'])
# Assure we can say something sensible like: # Assure we can say something sensible like:
# You have a task called "Approval" to be completed in the "Supervisor Approval" workflow # You have a task called "Approval" to be completed in the "Supervisor Approval" workflow