Provide event data on the Study api endpoint.

Speed up the tests a little, because that got out of hand.  Need to dig into what is causing this problem.
This commit is contained in:
Dan Funk 2020-07-27 17:05:01 -04:00
parent 5ecd77655c
commit 0cb480801b
4 changed files with 33 additions and 27 deletions

View File

@ -41,8 +41,10 @@ class StudyModel(db.Model):
class WorkflowMetadata(object):
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):
def __init__(self, id, name = None, display_name = None, description = None, spec_version = None,
category_id = None, category_display_name = None, state: WorkflowState = None,
status: WorkflowStatus = None, total_tasks = None, completed_tasks = None,
display_order = None):
self.id = id
self.name = name
self.display_name = display_name
@ -157,6 +159,7 @@ class StudySchema(ma.Schema):
files = fields.List(fields.Nested(FileSchema), dump_only=True)
approvals = fields.List(fields.Nested('ApprovalSchema'), dump_only=True)
enrollment_date = fields.Date(allow_none=True)
events = fields.List(fields.Nested('TaskEventSchema'), dump_only=True)
class Meta:
model = Study

View File

@ -1,6 +1,5 @@
from copy import copy
from datetime import datetime
import json
from typing import List
import requests
@ -13,16 +12,15 @@ from crc.api.common import ApiError
from crc.models.file import FileModel, FileModelSchema, File
from crc.models.ldap import LdapSchema
from crc.models.protocol_builder import ProtocolBuilderStudy, ProtocolBuilderStatus
from crc.models.task_event import TaskEventModel
from crc.models.study import StudyModel, Study, Category, WorkflowMetadata
from crc.models.task_event import TaskEventModel, TaskEvent
from crc.models.workflow import WorkflowSpecCategoryModel, WorkflowModel, WorkflowSpecModel, WorkflowState, \
WorkflowStatus
from crc.services.approval_service import ApprovalService
from crc.services.file_service import FileService
from crc.services.ldap_service import LdapService
from crc.services.protocol_builder import ProtocolBuilderService
from crc.services.workflow_processor import WorkflowProcessor
from crc.services.approval_service import ApprovalService
from crc.models.approval import Approval
class StudyService(object):
@ -63,7 +61,7 @@ class StudyService(object):
files = (File.from_models(model, FileService.get_file_data(model.id),
FileService.get_doc_dictionary()) for model in files)
study.files = list(files)
study.events = StudyService.get_events(study_id)
# Calling this line repeatedly is very very slow. It creates the
# master spec and runs it. Don't execute this for Abandoned studies, as
# we don't have the information to process them.
@ -77,6 +75,14 @@ class StudyService(object):
return study
@staticmethod
def get_events(study_id):
event_models = db.session.query(TaskEventModel).filter(TaskEventModel.study_id == study_id).all()
events = []
for event_model in event_models:
events.append(TaskEvent(event_model, None, WorkflowMetadata(id=event_model.workflow_id)))
return events
@staticmethod
def delete_study(study_id):
session.query(TaskEventModel).filter_by(study_id=study_id).delete()

View File

@ -1,4 +1,5 @@
import json
from tests.base_test import BaseTest
from datetime import datetime, timezone
@ -13,6 +14,7 @@ from crc.models.study import StudyModel, StudySchema
from crc.models.workflow import WorkflowSpecModel, WorkflowModel
from crc.services.file_service import FileService
from crc.services.workflow_processor import WorkflowProcessor
from crc.services.workflow_service import WorkflowService
class TestStudyApi(BaseTest):
@ -112,6 +114,21 @@ class TestStudyApi(BaseTest):
for approval in study.approvals:
self.assertEqual(full_study['study'].title, approval['title'])
def test_get_study_has_details_about_events(self):
# Set up the study and attach a file to it.
self.load_example_data()
workflow = self.create_workflow('file_upload_form')
processor = WorkflowProcessor(workflow)
task = processor.next_task()
WorkflowService.log_task_action('dhf8r', processor, task, 'my_action')
api_response = self.app.get('/v1.0/study/%i' % workflow.study_id,
headers=self.logged_in_headers(),
content_type="application/json")
self.assert_success(api_response)
study = json.loads(api_response.get_data(as_text=True))
self.assertEqual(1, len(study['events']))
self.assertEqual('my_action', study['events'][0]['action'])
def test_add_study(self):
self.load_example_data()
study = self.add_test_study()

View File

@ -69,7 +69,6 @@ class TestTasksApi(BaseTest):
self.assertIsNotNone(val)
def test_error_message_on_bad_gateway_expression(self):
self.load_example_data()
workflow = self.create_workflow('exclusive_gateway')
# get the first form in the two form workflow.
@ -77,7 +76,6 @@ class TestTasksApi(BaseTest):
self.complete_form(workflow, task, {"has_bananas": True})
def test_workflow_with_parallel_forms(self):
self.load_example_data()
workflow = self.create_workflow('exclusive_gateway')
# get the first form in the two form workflow.
@ -89,7 +87,6 @@ class TestTasksApi(BaseTest):
self.assertEqual("Task_Num_Bananas", workflow_api.next_task.name)
def test_navigation_with_parallel_forms(self):
self.load_example_data()
workflow = self.create_workflow('exclusive_gateway')
# get the first form in the two form workflow.
@ -107,7 +104,6 @@ class TestTasksApi(BaseTest):
self.assertEqual("NOOP", nav[3]['state'])
def test_navigation_with_exclusive_gateway(self):
self.load_example_data()
workflow = self.create_workflow('exclusive_gateway_2')
# get the first form in the two form workflow.
@ -124,7 +120,6 @@ class TestTasksApi(BaseTest):
self.assertEqual("Task 3", nav[6]['title'])
def test_document_added_to_workflow_shows_up_in_file_list(self):
self.load_example_data()
self.create_reference_document()
workflow = self.create_workflow('docx')
@ -153,7 +148,6 @@ class TestTasksApi(BaseTest):
def test_get_documentation_populated_in_end(self):
self.load_example_data()
workflow = self.create_workflow('random_fact')
workflow_api = self.get_workflow_api(workflow)
task = workflow_api.next_task
@ -167,9 +161,7 @@ class TestTasksApi(BaseTest):
self.assertTrue("norris" in workflow_api.next_task.documentation)
def test_load_workflow_from_outdated_spec(self):
# Start the basic two_forms workflow and complete a task.
self.load_example_data()
workflow = self.create_workflow('two_forms')
workflow_api = self.get_workflow_api(workflow)
self.complete_form(workflow, workflow_api.next_task, {"color": "blue"})
@ -194,9 +186,7 @@ class TestTasksApi(BaseTest):
self.assertTrue(workflow_api.is_latest_spec)
def test_soft_reset_errors_out_and_next_result_is_on_original_version(self):
# Start the basic two_forms workflow and complete a task.
self.load_example_data()
workflow = self.create_workflow('two_forms')
workflow_api = self.get_workflow_api(workflow)
self.complete_form(workflow, workflow_api.next_task, {"color": "blue"})
@ -221,7 +211,6 @@ class TestTasksApi(BaseTest):
def test_manual_task_with_external_documentation(self):
self.load_example_data()
workflow = self.create_workflow('manual_task_with_external_documentation')
# get the first form in the two form workflow.
@ -235,7 +224,6 @@ class TestTasksApi(BaseTest):
self.assertTrue('Dan' in workflow_api.next_task.documentation)
def test_bpmn_extension_properties_are_populated(self):
self.load_example_data()
workflow = self.create_workflow('manual_task_with_external_documentation')
# get the first form in the two form workflow.
@ -268,9 +256,7 @@ class TestTasksApi(BaseTest):
# Assure that the names for each task are properly updated, so they aren't all the same.
self.assertEqual("Primary Investigator", workflow.next_task.properties['display_name'])
def test_lookup_endpoint_for_task_field_enumerations(self):
self.load_example_data()
workflow = self.create_workflow('enum_options_with_search')
# get the first form in the two form workflow.
workflow = self.get_workflow_api(workflow)
@ -286,7 +272,6 @@ class TestTasksApi(BaseTest):
self.assert_options_populated(results, ['CUSTOMER_NUMBER', 'CUSTOMER_NAME', 'CUSTOMER_CLASS_MEANING'])
def test_lookup_endpoint_for_task_field_using_lookup_entry_id(self):
self.load_example_data()
workflow = self.create_workflow('enum_options_with_search')
# get the first form in the two form workflow.
workflow = self.get_workflow_api(workflow)
@ -316,7 +301,6 @@ class TestTasksApi(BaseTest):
# the key/values from the spreadsheet are added directly to the form and it shows up as
# a dropdown. This tests the case of wanting to get additional data when a user selects
# something from a dropdown.
self.load_example_data()
workflow = self.create_workflow('enum_options_from_file')
# get the first form in the two form workflow.
workflow = self.get_workflow_api(workflow)
@ -334,7 +318,6 @@ class TestTasksApi(BaseTest):
self.assertIsInstance(results[0]['data'], dict)
def test_enum_from_task_data(self):
self.load_example_data()
workflow = self.create_workflow('enum_options_from_task_data')
# get the first form in the two form workflow.
workflow_api = self.get_workflow_api(workflow)
@ -359,7 +342,6 @@ class TestTasksApi(BaseTest):
self.assertEqual('Chesterfield', options[2]['data']['first_name'])
def test_lookup_endpoint_for_task_ldap_field_lookup(self):
self.load_example_data()
workflow = self.create_workflow('ldap_lookup')
# get the first form
workflow = self.get_workflow_api(workflow)
@ -378,7 +360,6 @@ class TestTasksApi(BaseTest):
self.assertEqual(1, len(results))
def test_sub_process(self):
self.load_example_data()
workflow = self.create_workflow('subprocess')
workflow_api = self.get_workflow_api(workflow)
@ -399,7 +380,6 @@ class TestTasksApi(BaseTest):
self.assertEqual(WorkflowStatus.complete, workflow_api.status)
def test_update_task_resets_token(self):
self.load_example_data()
workflow = self.create_workflow('exclusive_gateway')
# Start the workflow.