From cd26654b3a78ec30c8f7f7343eebce3429ad197b Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 2 Jul 2021 15:21:35 -0400 Subject: [PATCH 1/5] Script to call new pb mock api endpoint `check_study` --- crc/scripts/check_study.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 crc/scripts/check_study.py diff --git a/crc/scripts/check_study.py b/crc/scripts/check_study.py new file mode 100644 index 00000000..e0c086ab --- /dev/null +++ b/crc/scripts/check_study.py @@ -0,0 +1,23 @@ +from crc.scripts.script import Script +from crc.api.common import ApiError +from crc.services.protocol_builder import ProtocolBuilderService + + +class CheckStudy(Script): + + pb = ProtocolBuilderService() + + def get_description(self): + pass + + def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs): + pass + + def do_task(self, task, study_id, workflow_id, *args, **kwargs): + check_study = self.pb.check_study(study_id) + if check_study: + return check_study + else: + raise ApiError.from_task(code='missing_check_study', + message='There was a problem checking information for this study.', + task=task) From 9690c69b6cd0b735d9d9ba9df0a2e490112618c0 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 2 Jul 2021 15:25:33 -0400 Subject: [PATCH 2/5] added check_study method to protocol_builder service for new endpoint --- config/default.py | 1 + crc/services/protocol_builder.py | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/config/default.py b/config/default.py index fe96d8f5..47d5e7a0 100644 --- a/config/default.py +++ b/config/default.py @@ -63,6 +63,7 @@ PB_REQUIRED_DOCS_URL = environ.get('PB_REQUIRED_DOCS_URL', default=PB_BASE_URL + PB_STUDY_DETAILS_URL = environ.get('PB_STUDY_DETAILS_URL', default=PB_BASE_URL + "study?studyid=%i") PB_SPONSORS_URL = environ.get('PB_SPONSORS_URL', default=PB_BASE_URL + "sponsors?studyid=%i") PB_IRB_INFO_URL = environ.get('PB_IRB_INFO_URL', default=PB_BASE_URL + "current_irb_info/%i") +PB_CHECK_STUDY_URL = environ.get('PB_CHECK_STUDY_URL', default=PB_BASE_URL + "check_study/%i") # Ldap Configuration LDAP_URL = environ.get('LDAP_URL', default="ldap.virginia.edu").strip('/') # No trailing slash or http:// diff --git a/crc/services/protocol_builder.py b/crc/services/protocol_builder.py index 6107280b..6806204d 100644 --- a/crc/services/protocol_builder.py +++ b/crc/services/protocol_builder.py @@ -15,6 +15,7 @@ class ProtocolBuilderService(object): STUDY_DETAILS_URL = app.config['PB_STUDY_DETAILS_URL'] SPONSORS_URL = app.config['PB_SPONSORS_URL'] IRB_INFO_URL = app.config['PB_IRB_INFO_URL'] + CHECK_STUDY_URL = app.config['PB_CHECK_STUDY_URL'] @staticmethod def is_enabled(): @@ -64,6 +65,10 @@ class ProtocolBuilderService(object): def get_sponsors(study_id) -> {}: return ProtocolBuilderService.__make_request(study_id, ProtocolBuilderService.SPONSORS_URL) + @staticmethod + def check_study(study_id) -> {}: + return ProtocolBuilderService.__make_request(study_id, ProtocolBuilderService.CHECK_STUDY_URL) + @staticmethod def __enabled_or_raise(): if not ProtocolBuilderService.is_enabled(): From 2cb2874a49f7084e11c2da5d96326dcc0e7a1a4f Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 2 Jul 2021 15:26:39 -0400 Subject: [PATCH 3/5] Added test and json data for new check_study pb mock api endpoint --- tests/data/pb_responses/check_study.json | 3 +++ tests/test_protocol_builder.py | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 tests/data/pb_responses/check_study.json diff --git a/tests/data/pb_responses/check_study.json b/tests/data/pb_responses/check_study.json new file mode 100644 index 00000000..eb701b75 --- /dev/null +++ b/tests/data/pb_responses/check_study.json @@ -0,0 +1,3 @@ +[ + {"DETAIL": "Passed validation.", "STATUS": "No Error"} +] \ No newline at end of file diff --git a/tests/test_protocol_builder.py b/tests/test_protocol_builder.py index 8bd1f66f..c64f83e5 100644 --- a/tests/test_protocol_builder.py +++ b/tests/test_protocol_builder.py @@ -72,3 +72,13 @@ class TestProtocolBuilder(BaseTest): self.assertEqual('IRB Event 1', response[0]["IRBEVENT"]) self.assertEqual('IRB Event 2', response[1]["IRBEVENT"]) self.assertEqual('IRB Event 3', response[2]["IRBEVENT"]) + + @patch('crc.services.protocol_builder.requests.get') + def test_check_study(self, mock_get): + app.config['PB_ENABLED'] = True + mock_get.return_value.ok = True + mock_get.return_value.text = self.protocol_builder_response('check_study.json') + response = ProtocolBuilderService.check_study(self.test_study_id) + self.assertIsNotNone(response) + self.assertIn('DETAIL', response[0].keys()) + self.assertIn('STATUS', response[0].keys()) From f647390e1c9139cd7124e2f0790c6022cfec59f0 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 2 Jul 2021 15:51:24 -0400 Subject: [PATCH 4/5] Added description and validate_only --- crc/scripts/check_study.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/crc/scripts/check_study.py b/crc/scripts/check_study.py index e0c086ab..68237421 100644 --- a/crc/scripts/check_study.py +++ b/crc/scripts/check_study.py @@ -1,6 +1,7 @@ from crc.scripts.script import Script from crc.api.common import ApiError from crc.services.protocol_builder import ProtocolBuilderService +from crc.services.study_service import StudyService class CheckStudy(Script): @@ -8,10 +9,16 @@ class CheckStudy(Script): pb = ProtocolBuilderService() def get_description(self): - pass + return """Returns the Check Study data for a Study""" def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs): - pass + study = StudyService.get_study(study_id) + if study: + return {"DETAIL": "Passed validation.", "STATUS": "No Error"} + else: + raise ApiError.from_task(code='bad_study', + message=f'No study for study_id {study_id}', + task=task) def do_task(self, task, study_id, workflow_id, *args, **kwargs): check_study = self.pb.check_study(study_id) From 8145ff9025dcd1267357c954fed495a72a769aa7 Mon Sep 17 00:00:00 2001 From: mike cullerton Date: Fri, 2 Jul 2021 16:14:19 -0400 Subject: [PATCH 5/5] Tests for calling the script --- .../check_study_script.bpmn | 53 +++++++++++++++++++ tests/scripts/test_check_study.py | 25 +++++++++ 2 files changed, 78 insertions(+) create mode 100644 tests/data/check_study_script/check_study_script.bpmn create mode 100644 tests/scripts/test_check_study.py diff --git a/tests/data/check_study_script/check_study_script.bpmn b/tests/data/check_study_script/check_study_script.bpmn new file mode 100644 index 00000000..91cfc790 --- /dev/null +++ b/tests/data/check_study_script/check_study_script.bpmn @@ -0,0 +1,53 @@ + + + + + Flow_17nzcku + + + + Flow_17nzcku + Flow_0oozrfg + check_study = check_study() + + + + # Check Study +<div><span>{{check_study}}</span></div> + Flow_0oozrfg + Flow_10sc31i + + + Flow_10sc31i + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/scripts/test_check_study.py b/tests/scripts/test_check_study.py new file mode 100644 index 00000000..e05afbd2 --- /dev/null +++ b/tests/scripts/test_check_study.py @@ -0,0 +1,25 @@ +from tests.base_test import BaseTest +from crc import app +from unittest.mock import patch + + +class TestCheckStudy(BaseTest): + + def test_check_study_script_validation(self): + self.load_example_data() + spec_model = self.load_test_spec('check_study_script') + rv = self.app.get('/v1.0/workflow-specification/%s/validate' % spec_model.id, headers=self.logged_in_headers()) + self.assertEqual([], rv.json) + + @patch('crc.services.protocol_builder.requests.get') + def test_check_study(self, mock_get): + app.config['PB_ENABLED'] = True + app.config['PB_ENABLED'] = True + mock_get.return_value.ok = True + mock_get.return_value.text = self.protocol_builder_response('check_study.json') + workflow = self.create_workflow('check_study_script') + workflow_api = self.get_workflow_api(workflow) + task = workflow_api.next_task + + self.assertIn('DETAIL', task.documentation) + self.assertIn('STATUS', task.documentation)