From ef5a0a7e4581d09bd2bd83e6ad8e5503fedf677e Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 24 Sep 2021 11:05:33 -0400 Subject: [PATCH 1/2] Check whether a workflow spec is disabled by the master workflow before validating. Return the master workflow message to the user --- crc/services/workflow_service.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/crc/services/workflow_service.py b/crc/services/workflow_service.py index 47ce69bf..60a0630e 100755 --- a/crc/services/workflow_service.py +++ b/crc/services/workflow_service.py @@ -132,6 +132,13 @@ class WorkflowService(object): spec, only completing the required fields, rather than everything. """ + # Get workflow state dictionary, make sure workflow is not disabled. + if validate_study_id is not None: + study_model = session.query(StudyModel).filter(StudyModel.id == validate_study_id).first() + spec_model = session.query(WorkflowSpecModel).filter(WorkflowSpecModel.id == spec_id).first() + status = StudyService._get_study_status(study_model) + if status[spec_model.name]['status'] == 'disabled': + raise ApiError(code='disabled_workflow', message=f"This workflow is disabled. {status[spec_model.name]['message']}") workflow_model = WorkflowService.make_test_workflow(spec_id, validate_study_id) try: processor = WorkflowProcessor(workflow_model, validate_only=True) From fb9c3e96ac1564c66d1d8ca72b7e0b9c2948c68d Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 24 Sep 2021 11:08:54 -0400 Subject: [PATCH 2/2] Test and mocked status data for adding master workflow into validation. Make sure we see ApiError for disabled workflow spec --- .../data/pb_responses/_get_study_status.json | 5 +++ .../test_workflow_spec_validation_api.py | 33 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 tests/data/pb_responses/_get_study_status.json diff --git a/tests/data/pb_responses/_get_study_status.json b/tests/data/pb_responses/_get_study_status.json new file mode 100644 index 00000000..ec5d5033 --- /dev/null +++ b/tests/data/pb_responses/_get_study_status.json @@ -0,0 +1,5 @@ +[{ + "core_info": {"status": "required", "message": "This workflow is always required and recommended that it is completed after your Protocol Builder entries are done and the Personnel workflow completed"}, + "protocol": {"status": "required", "message": "required"}, + "data_security_plan": {"status": "disabled", "message": "This is my mocked disable message."} +}] diff --git a/tests/workflow/test_workflow_spec_validation_api.py b/tests/workflow/test_workflow_spec_validation_api.py index 3c144d39..2aa16e99 100644 --- a/tests/workflow/test_workflow_spec_validation_api.py +++ b/tests/workflow/test_workflow_spec_validation_api.py @@ -9,6 +9,7 @@ from tests.base_test import BaseTest from crc import session, app from crc.api.common import ApiErrorSchema from crc.models.protocol_builder import ProtocolBuilderStudySchema +from crc.models.study import StudyModel from crc.models.workflow import WorkflowSpecModel, WorkflowModel from crc.services.workflow_service import WorkflowService @@ -147,3 +148,35 @@ class TestWorkflowSpecValidation(BaseTest): self.assertIn('enum_with_default', final_data) self.assertEqual('maybe', final_data['enum_with_default']['value']) + @patch('crc.services.study_service.StudyService._get_study_status') + def test_disabled_spec_validation(self, mock_status): + """A disabled workflow spec should fail validation""" + app.config['PB_ENABLED'] = True + self.load_example_data() + study_model = session.query(StudyModel).first() + + # workflow spec to validate + spec_model = WorkflowSpecModel(id='data_security_plan', + name='data_security_plan', + display_name='Data Security Plan', + description='Data Security Plan', + is_master_spec=False, + category_id=0, + display_order=0, + standalone=False, + library=False) + session.add(spec_model) + session.commit() + + # This response sets the status for data_security_plan to disabled + status_response = self.protocol_builder_response('_get_study_status.json') + mock_status.return_value = json.loads(status_response)[0] + + # This should raise an ApiError which we can see in the json data + rv = self.app.get('/v1.0/workflow-specification/%s/validate?study_id=%s' % (spec_model.id, study_model.id), headers=self.logged_in_headers()) + self.assert_success(rv) + json_data = json.loads(rv.get_data()) + self.assertEqual(1, len(json_data)) + api_error = json_data[0] + self.assertEqual('disabled_workflow', api_error['code']) + self.assertEqual('This workflow is disabled. This is my mocked disable message.', api_error['message'])