Expanding the task events endpoint to accept workflow and study ids as additional filters.

Removing events from the study endpoint, too noisy.
This commit is contained in:
Dan Funk 2020-07-28 10:16:48 -04:00
parent 0cb480801b
commit 300026cbc8
9 changed files with 65 additions and 27 deletions

View File

@ -572,6 +572,18 @@ paths:
description: The type of action the event documents, options include "ASSIGNMENT" for tasks that are waiting on you, "COMPLETE" for things have completed.
schema:
type: string
- name: workflow
in: query
required: false
description: Restrict results to the given workflow.
schema:
type: number
- name: study
in: query
required: false
description: Restrict results to the given study.
schema:
type: number
get:
operationId: crc.api.workflow.get_task_events
summary: Returns a list of task events related to the current user. Can be filtered by type.

View File

@ -103,11 +103,15 @@ def get_workflow(workflow_id, soft_reset=False, hard_reset=False):
return WorkflowApiSchema().dump(workflow_api_model)
def get_task_events(action):
def get_task_events(action = None, workflow = None, study = None):
"""Provides a way to see a history of what has happened, or get a list of tasks that need your attention."""
query = session.query(TaskEventModel).filter(TaskEventModel.user_uid == g.user.uid)
if action:
query = query.filter(TaskEventModel.action == action)
if workflow:
query = query.filter(TaskEventModel.workflow_id == workflow)
if study:
query = query.filter(TaskEventModel.study_id == study)
events = query.all()
# Turn the database records into something a little richer for the UI to use.

View File

@ -159,7 +159,6 @@ 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

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

View File

@ -78,7 +78,8 @@ class FileService(object):
""" Opens a reference file (assumes that it is xls file) and returns the data as a
dictionary, each row keyed on the given index_column name. If there are columns
that should be represented as integers, pass these as an array of int_columns, lest
you get '1.0' rather than '1' """
you get '1.0' rather than '1'
fixme: This is stupid stupid slow. Place it in the database and just check if it is up to date."""
data_model = FileService.get_reference_file_data(reference_file_name)
xls = ExcelFile(data_model.data)
df = xls.parse(xls.sheet_names[0])

View File

@ -61,7 +61,6 @@ 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.
@ -75,14 +74,6 @@ 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 profile import Profile
from tests.base_test import BaseTest
@ -114,21 +115,6 @@ 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()

43
tests/test_events.py Normal file
View File

@ -0,0 +1,43 @@
import json
from tests.base_test import BaseTest
from crc.models.workflow import WorkflowStatus
from crc import db
from crc.api.common import ApiError
from crc.models.task_event import TaskEventModel, TaskEventSchema
from crc.services.workflow_service import WorkflowService
class TestEvents(BaseTest):
def test_list_events_by_workflow(self):
workflow_one = self.create_workflow('exclusive_gateway')
# Start a the workflow.
first_task = self.get_workflow_api(workflow_one).next_task
self.complete_form(workflow_one, first_task, {"has_bananas": True})
workflow_one = self.get_workflow_api(workflow_one)
self.assertEqual('Task_Num_Bananas', workflow_one.next_task.name)
# Start a second workflow
workflow_two = self.create_workflow('subprocess')
workflow_api_two = self.get_workflow_api(workflow_two)
# Get all action events across workflows
rv = self.app.get('/v1.0/task_events?action=ASSIGNMENT',
headers=self.logged_in_headers(),
content_type="application/json")
self.assert_success(rv)
json_data = json.loads(rv.get_data(as_text=True))
tasks = TaskEventSchema(many=True).load(json_data)
self.assertEqual(2, len(tasks))
# Get action events for a single workflow
rv = self.app.get(f'/v1.0/task_events?action=ASSIGNMENT&workflow={workflow_one.id}',
headers=self.logged_in_headers(),
content_type="application/json")
self.assert_success(rv)
json_data = json.loads(rv.get_data(as_text=True))
tasks = TaskEventSchema(many=True).load(json_data)
self.assertEqual(1, len(tasks))

View File

@ -111,6 +111,7 @@ class TestTasksApi(BaseTest):
data['approval'] = True
self.complete_form(workflow, workflow_api.next_task, data, user_uid=supervisor.uid)
def test_navigation_and_current_task_updates_through_workflow(self):
submitter = self.create_user(uid='lje5u')