def test_do_task(self):
        self.load_example_data()
        workflow = self.create_workflow('empty_workflow')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()
        details = Box({
            "title": "My New Title",
            "short_title": "My New Short Title",
            "pi": "dhf8r",
            "short_name": "My Short Name",
            "proposal_name": "My Proposal Name"
        })

        script = UpdateStudy()
        # note that we changed where the argument gets evaluated
        # previsously, it took the arguments and then evaluated them within the script
        # now, it evaluates the arugments in the context of the main script so they get
        # evaluated before they are passed to the script -
        # this allows us to do a lot more things like strings, functions, etc.
        # and it makes the arguments less confusing to use.
        script.do_task(task,
                       workflow.study_id,
                       workflow.id,
                       title=details.title,
                       short_title=details.short_title,
                       pi=details.pi,
                       short_name=details.short_name,
                       proposal_name=details.proposal_name)
        self.assertEqual(details.title, workflow.study.title)
        self.assertEqual(details.short_title, workflow.study.short_title)
        self.assertEqual(details.pi, workflow.study.primary_investigator_id)
        self.assertEqual(details.short_name, workflow.study.short_name)
        self.assertEqual(details.proposal_name, workflow.study.proposal_name)
 def test_file_data_set_changes_irb_code(self, mock_get):
     mock_get.return_value.ok = True
     mock_get.return_value.text = self.protocol_builder_response(
         'required_docs.json')
     self.load_example_data()
     study = session.query(StudyModel).first()
     workflow_spec_model = self.load_test_spec("two_forms")
     workflow_model = StudyService._create_workflow_model(
         study, workflow_spec_model)
     irb_code = "UVACompl_PRCAppr"  # The first file referenced in pb required docs.
     file = FileService.add_workflow_file(workflow_id=workflow_model.id,
                                          task_spec_name='TaskSpec01',
                                          name="anything.png",
                                          content_type="text",
                                          binary_data=b'1234',
                                          irb_doc_code=irb_code)
     processor = WorkflowProcessor(workflow_model)
     task = processor.next_task()
     FileDataSet().do_task(task,
                           study.id,
                           workflow_model.id,
                           key="irb_code",
                           value="Study_App_Doc",
                           file_id=file.id)
     docs = StudyInfo().do_task(task, study.id, workflow_model.id,
                                "documents")
     self.assertTrue(isinstance(docs, Box))
     self.assertEqual(1, len(docs.Study_App_Doc.files))
     self.assertEqual("Study_App_Doc",
                      docs.Study_App_Doc.files[0].data_store.irb_code)
 def test_file_data_set_invalid_irb_code_fails(self, mock_get):
     mock_get.return_value.ok = True
     mock_get.return_value.text = self.protocol_builder_response(
         'required_docs.json')
     self.load_example_data()
     study = session.query(StudyModel).first()
     workflow_spec_model = self.load_test_spec("two_forms")
     workflow_model = StudyService._create_workflow_model(
         study, workflow_spec_model)
     irb_code = "UVACompl_PRCAppr"  # The first file referenced in pb required docs.
     file = FileService.add_workflow_file(workflow_id=workflow_model.id,
                                          task_spec_name='Activity01',
                                          name="anything.png",
                                          content_type="text",
                                          binary_data=b'1234',
                                          irb_doc_code=irb_code)
     processor = WorkflowProcessor(workflow_model)
     task = processor.next_task()
     with self.assertRaises(ApiError):
         FileDataSet().do_task(task,
                               study.id,
                               workflow_model.id,
                               key="irb_code",
                               value="My_Pretty_Pony",
                               file_id=file.id)
Esempio n. 4
0
    def test_study_sponsors_script_ensure_delete(self, mock_get):
        mock_get.return_value.ok = True
        mock_get.return_value.text = self.protocol_builder_response(
            'sponsors.json')
        flask.g.user = UserModel(uid='dhf8r')
        app.config['PB_ENABLED'] = True

        self.load_example_data()
        study = session.query(StudyModel).first()
        workflow_spec_model = self.load_test_spec(
            "study_sponsors_associates_delete")
        workflow_model = StudyService._create_workflow_model(
            study, workflow_spec_model)
        WorkflowService.test_spec("study_sponsors_associates_delete")
        processor = WorkflowProcessor(workflow_model)
        processor.do_engine_steps()
        # change user and make sure we can access the study
        flask.g.user = UserModel(uid='lb3dp')
        flask.g.token = 'my spiffy token'
        app.config['PB_ENABLED'] = False
        output = user_studies()
        self.assertEqual(len(output), 0)
        flask.g.token = 'my spiffy token'
        app.config['PB_ENABLED'] = False
        output = user_studies()
        self.assertEqual(len(output), 0)
Esempio n. 5
0
    def test_add_file_from_task_and_form_errors_on_invalid_form_field_name(
            self):
        self.load_example_data()
        self.create_reference_document()
        workflow = self.create_workflow('file_upload_form')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()
        data = {'file': (io.BytesIO(b"abcdef"), 'random_fact.svg')}
        correct_name = task.task_spec.form.fields[0].id

        rv = self.app.post(
            '/v1.0/file?study_id=%i&workflow_id=%s&task_id=%i&form_field_key=%s'
            % (workflow.study_id, workflow.id, task.id, "not_a_known_file"),
            data=data,
            follow_redirects=True,
            content_type='multipart/form-data',
            headers=self.logged_in_headers())
        self.assert_failure(rv, error_code="invalid_form_field_key")

        data = {'file': (io.BytesIO(b"abcdef"), 'random_fact.svg')}
        rv = self.app.post(
            '/v1.0/file?study_id=%i&workflow_id=%s&task_id=%i&form_field_key=%s'
            % (workflow.study_id, workflow.id, task.id, correct_name),
            data=data,
            follow_redirects=True,
            content_type='multipart/form-data',
            headers=self.logged_in_headers())
        self.assert_success(rv)
Esempio n. 6
0
def set_current_task(workflow_id, task_id):
    workflow_model = session.query(WorkflowModel).filter_by(
        id=workflow_id).first()
    processor = WorkflowProcessor(workflow_model)
    task_id = uuid.UUID(task_id)
    spiff_task = processor.bpmn_workflow.get_task(task_id)
    _verify_user_and_role(processor, spiff_task)
    user_uid = g.user.uid
    if spiff_task.state != spiff_task.COMPLETED and spiff_task.state != spiff_task.READY:
        raise ApiError(
            "invalid_state",
            "You may not move the token to a task who's state is not "
            "currently set to COMPLETE or READY.")

    # Only reset the token if the task doesn't already have it.
    if spiff_task.state == spiff_task.COMPLETED:
        spiff_task.reset_token(
            reset_data=True
        )  # Don't try to copy the existing data back into this task.

    processor.save()
    WorkflowService.log_task_action(user_uid, processor, spiff_task,
                                    WorkflowService.TASK_ACTION_TOKEN_RESET)
    WorkflowService.update_task_assignments(processor)

    workflow_api_model = WorkflowService.processor_to_workflow_api(
        processor, spiff_task)
    return WorkflowApiSchema().dump(workflow_api_model)
    def test_get_logs_for_study(self):
        self.load_example_data()
        study = session.query(StudyModel).first()
        workflow = self.create_workflow('hello_world', study=study)
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()

        TaskLog().do_task(task, study.id, workflow.id,
                           level='critical',
                           code='critical_code',
                           message='This is my critical message.')

        TaskLog().do_task(task, study.id, workflow.id,
                           level='debug',
                           code='debug_code',
                           message='This is my debug message.')

        # This workflow adds 3 logs
        # some_text = 'variable'
        # log('info', 'some_code', 'Some longer message')
        # log('info', 'some_other_code', 'Another really long message')
        # log('debug', 'debug_code', f'This message has a { some_text }!')
        workflow = self.create_workflow('get_logging_for_study', study=study)
        workflow_api = self.get_workflow_api(workflow)
        task_api = workflow_api.next_task
        workflow_api = self.complete_form(workflow, task_api, {})
        task_api = workflow_api.next_task
        workflow_logs = task_api.data['workflow_logs']
        study_logs = task_api.data['study_logs']
        self.assertEqual(3, len(workflow_logs))
        self.assertEqual(5, len(study_logs))
Esempio n. 8
0
    def test_documentation_processing_handles_replacements(self):
        self.load_example_data()
        workflow = self.create_workflow('random_fact')
        processor = WorkflowProcessor(workflow)
        processor.do_engine_steps()

        task = processor.next_task()
        task.task_spec.documentation = "Some simple docs"
        docs = WorkflowService._process_documentation(task)
        self.assertEqual("Some simple docs", docs)

        task.data = {"replace_me": "new_thing"}
        task.task_spec.documentation = "{{replace_me}}"
        docs = WorkflowService._process_documentation(task)
        self.assertEqual("new_thing", docs)

        documentation = """
# Bigger Test

  * bullet one
  * bullet two has {{replace_me}}

# other stuff.
        """
        expected = """
# Bigger Test

  * bullet one
  * bullet two has new_thing

# other stuff.
        """
        task.task_spec.documentation = documentation
        result = WorkflowService._process_documentation(task)
        self.assertEqual(expected, result)
Esempio n. 9
0
    def test_get_study_has_details_about_files(self):

        # Set up the study and attach a file to it.
        self.load_example_data()
        self.create_reference_document()
        workflow = self.create_workflow('file_upload_form')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()
        irb_code = "UVACompl_PRCAppr"  # The first file referenced in pb required docs.
        FileService.add_workflow_file(workflow_id=workflow.id,
                                      name="anything.png",
                                      content_type="png",
                                      binary_data=b'1234',
                                      irb_doc_code=irb_code)

        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 = StudySchema().loads(api_response.get_data(as_text=True))
        self.assertEqual(1, len(study.files))
        self.assertEqual("UVA Compliance/PRC Approval",
                         study.files[0]["category"])
        self.assertEqual("Cancer Center's PRC Approval Form",
                         study.files[0]["description"])
        self.assertEqual("UVA Compliance/PRC Approval.png",
                         study.files[0]["download_name"])
Esempio n. 10
0
    def test_add_file_from_task_increments_version_and_replaces_on_subsequent_add(
            self):
        self.load_example_data()
        self.create_reference_document()
        workflow = self.create_workflow('file_upload_form')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()
        irb_code = "UVACompl_PRCAppr"  # The first file referenced in pb required docs.
        FileService.add_workflow_file(workflow_id=workflow.id,
                                      name="anything.png",
                                      content_type="text",
                                      binary_data=b'1234',
                                      irb_doc_code=irb_code)
        # Add the file again with different data
        FileService.add_workflow_file(workflow_id=workflow.id,
                                      name="anything.png",
                                      content_type="text",
                                      binary_data=b'5678',
                                      irb_doc_code=irb_code)

        file_models = FileService.get_workflow_files(workflow_id=workflow.id)
        self.assertEqual(1, len(file_models))

        file_data = FileService.get_workflow_data_files(
            workflow_id=workflow.id)
        self.assertEqual(1, len(file_data))
        self.assertEqual(2, file_data[0].version)
Esempio n. 11
0
    def test_archive_file_no_longer_shows_up(self):
        self.load_example_data()
        self.create_reference_document()
        workflow = self.create_workflow('file_upload_form')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()
        data = {'file': (io.BytesIO(b"abcdef"), 'random_fact.svg')}
        correct_name = task.task_spec.form.fields[0].id

        data = {'file': (io.BytesIO(b"abcdef"), 'random_fact.svg')}
        rv = self.app.post(
            '/v1.0/file?study_id=%i&workflow_id=%s&task_id=%i&form_field_key=%s'
            % (workflow.study_id, workflow.id, task.id, correct_name),
            data=data,
            follow_redirects=True,
            content_type='multipart/form-data',
            headers=self.logged_in_headers())

        self.assert_success(rv)
        rv = self.app.get('/v1.0/file?workflow_id=%s' % workflow.id,
                          headers=self.logged_in_headers())
        self.assert_success(rv)
        self.assertEqual(1, len(json.loads(rv.get_data(as_text=True))))

        file_model = db.session.query(FileModel).filter(
            FileModel.workflow_id == workflow.id).all()
        self.assertEqual(1, len(file_model))
        file_model[0].archived = True
        db.session.commit()

        rv = self.app.get('/v1.0/file?workflow_id=%s' % workflow.id,
                          headers=self.logged_in_headers())
        self.assert_success(rv)
        self.assertEqual(0, len(json.loads(rv.get_data(as_text=True))))
Esempio n. 12
0
    def test_validate_returns_error_if_reference_files_do_not_exist(
            self, mock_get):
        mock_get.return_value.ok = True
        mock_get.return_value.text = self.protocol_builder_response(
            'required_docs.json')

        self.load_example_data()
        self.create_reference_document()
        study = session.query(StudyModel).first()
        workflow_spec_model = self.load_test_spec("two_forms")
        workflow_model = StudyService._create_workflow_model(
            study, workflow_spec_model)
        processor = WorkflowProcessor(workflow_model)
        task = processor.next_task()

        # Remove the reference file.
        file_model = db.session.query(FileModel). \
            filter(FileModel.is_reference == True). \
            filter(FileModel.name == FileService.DOCUMENT_LIST).first()
        if file_model:
            db.session.query(FileDataModel).filter(
                FileDataModel.file_model_id == file_model.id).delete()
            db.session.query(FileModel).filter(
                FileModel.id == file_model.id).delete()
        db.session.commit()
        db.session.flush()

        with self.assertRaises(ApiError):
            StudyInfo().do_task_validate_only(task, study.id, "documents")
Esempio n. 13
0
 def setUp(self):
     self.load_example_data()
     self.study = session.query(StudyModel).first()
     self.workflow_spec_model = self.load_test_spec("two_forms")
     self.workflow_model = StudyService._create_workflow_model(
         self.study, self.workflow_spec_model)
     self.processor = WorkflowProcessor(self.workflow_model)
     self.task = self.processor.next_task()
Esempio n. 14
0
def restart_workflow(workflow_id, clear_data=False, delete_files=False):
    """Restart a workflow with the latest spec.
       Clear data allows user to restart the workflow without previous data."""
    workflow_model: WorkflowModel = session.query(WorkflowModel).filter_by(
        id=workflow_id).first()
    WorkflowProcessor.reset(workflow_model,
                            clear_data=clear_data,
                            delete_files=delete_files)
    return get_workflow(workflow_model.id)
Esempio n. 15
0
 def test_random_data_populate_form_on_auto_complete(self):
     self.load_example_data()
     workflow = self.create_workflow('enum_options_with_search')
     processor = WorkflowProcessor(workflow)
     processor.do_engine_steps()
     task = processor.next_task()
     task_api = WorkflowService.spiff_task_to_api_task(task, add_docs_and_forms=True)
     WorkflowService.populate_form_with_random_data(task, task_api, required_only=False)
     self.assertTrue(isinstance(task.data["sponsor"], dict))
 def test_enum_options_from_file(self):
     self.load_example_data()
     workflow = self.create_workflow('enum_options_from_file')
     processor = WorkflowProcessor(workflow)
     processor.do_engine_steps()
     task = processor.next_task()
     WorkflowService.process_options(task, task.task_spec.form.fields[0])
     options = task.task_spec.form.fields[0].options
     self.assertEqual(29, len(options))
     self.assertEqual('0', options[0].id)
     self.assertEqual("Other", options[0].name)
Esempio n. 17
0
 def test_enum_options_from_file(self):
     self.load_example_data()
     workflow = self.create_workflow('enum_options_from_file')
     processor = WorkflowProcessor(workflow)
     processor.do_engine_steps()
     task = processor.next_task()
     WorkflowService.process_options(task, task.task_spec.form.fields[0])
     options = task.task_spec.form.fields[0].options
     self.assertEqual(28, len(options))
     self.assertEqual('1000', options[0]['id'])
     self.assertEqual("UVA - INTERNAL - GM USE ONLY", options[0]['name'])
Esempio n. 18
0
    def test_get_current_user_details(self):
        self.load_example_data()
        workflow = self.create_workflow('empty_workflow')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()

        script = Ldap()
        g.user = db.session.query(UserModel).filter(
            UserModel.uid == 'dhf8r').first()
        user_details = script.do_task(task, workflow.study_id, workflow.id)
        self.assertEqual(user_details['display_name'], 'Dan Funk')
Esempio n. 19
0
 def test_do_task_with_incorrect_argument(self):
     """This script should raise an error if it can't figure out the approvers."""
     self.load_example_data()
     self.create_reference_document()
     workflow = self.create_workflow('empty_workflow')
     processor = WorkflowProcessor(workflow)
     task = processor.next_task()
     task.data = {"approvals": {'dhf8r':["invalid"], 'lb3dp':"invalid"}}
     script = RequestApproval()
     with self.assertRaises(ApiError):
         script.do_task(task, workflow.study_id, workflow.id, "approvals")
Esempio n. 20
0
    def test_do_task_validate_only(self):
        self.load_example_data()
        self.create_reference_document()
        workflow = self.create_workflow('empty_workflow')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()
        task.data = {"study": {"approval1": "dhf8r", 'approval2':'lb3dp'}}

        script = RequestApproval()
        script.do_task_validate_only(task, workflow.study_id, workflow.id, "study.approval1")
        self.assertEqual(0, db.session.query(ApprovalModel).count())
Esempio n. 21
0
    def test_get_invalid_user_details(self):
        self.load_example_data()
        workflow = self.create_workflow('empty_workflow')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()

        task.data = {'PIComputingID': 'rec3z'}

        script = Ldap()
        user_details = script.do_task(task, workflow.study_id, workflow.id,
                                      "PIComputingID")
        self.assertEqual({}, user_details)
    def setUp(self):
        self.load_example_data()
        self.workflow = self.create_workflow('enum_options_all')
        self.workflow_api = self.get_workflow_api(self.workflow)

        # Assure the form has been loaded at least once.
        processor = WorkflowProcessor(self.workflow)
        processor.do_engine_steps()
        self.task = processor.next_task()
        self.assertEqual(self.task.get_name(), 'myFormTask')

        self.labelScript = EnumLabel()
    def test_jinja_service_element_documentation(self):
        self.load_example_data()
        workflow = self.create_workflow('random_fact')
        processor = WorkflowProcessor(workflow)
        processor.do_engine_steps()

        task = processor.next_task()
        task.data = {"my_template": "Hi {{name}}, This is a jinja template too!",
                     "name": "Dan"}
        task.task_spec.documentation = """{% include 'my_template' %} Cool Right?"""
        docs = WorkflowService._process_documentation(task)
        self.assertEqual("Hi Dan, This is a jinja template too! Cool Right?", docs)
Esempio n. 24
0
 def test_default_values_for_enum_as_checkbox(self):
     self.load_test_spec('enum_results')
     workflow = self.create_workflow('enum_results')
     processor = WorkflowProcessor(workflow)
     processor.do_engine_steps()
     task = processor.next_task()
     service = WorkflowService()
     checkbox_enum_field = task.task_spec.form.fields[0]
     radio_enum_field = task.task_spec.form.fields[1]
     self.assertEqual([],
                      service.get_default_value(checkbox_enum_field, task))
     self.assertEqual(None,
                      service.get_default_value(radio_enum_field, task))
Esempio n. 25
0
    def test_do_task(self):
        self.load_example_data()
        self.create_reference_document()
        workflow = self.create_workflow('empty_workflow')
        processor = WorkflowProcessor(workflow)
        task = processor.next_task()
        task.data = {"details": {"label": "My New Title", "value": "dhf8r"}}

        script = UpdateStudy()
        script.do_task(task, workflow.study_id, workflow.id,
                       "title:details.label", "pi:details.value")
        self.assertEqual("My New Title", workflow.study.title)
        self.assertEqual("dhf8r", workflow.study.primary_investigator_id)
Esempio n. 26
0
def update_task(workflow_id,
                task_id,
                body,
                terminate_loop=None,
                update_all=False):
    workflow_model = session.query(WorkflowModel).filter_by(
        id=workflow_id).first()
    if workflow_model is None:
        raise ApiError("invalid_workflow_id",
                       "The given workflow id is not valid.",
                       status_code=404)

    processor = WorkflowProcessor(workflow_model)
    task_id = uuid.UUID(task_id)
    spiff_task = processor.bpmn_workflow.get_task(task_id)
    _verify_user_and_role(processor, spiff_task)
    user = UserService.current_user(
        allow_admin_impersonate=False)  # Always log as the real user.

    if not spiff_task:
        raise ApiError("empty_task",
                       "Processor failed to obtain task.",
                       status_code=404)
    if spiff_task.state != spiff_task.READY:
        raise ApiError(
            "invalid_state",
            "You may not update a task unless it is in the READY state. "
            "Consider calling a token reset to make this task Ready.")

    if terminate_loop and spiff_task.is_looping():
        spiff_task.terminate_loop()

    # Extract the details specific to the form submitted
    form_data = WorkflowService().extract_form_data(body, spiff_task)

    # Update the task
    __update_task(processor, spiff_task, form_data, user)

    # If we need to update all tasks, then get the next ready task and if it a multi-instance with the same
    # task spec, complete that form as well.
    if update_all:
        last_index = spiff_task.task_info()["mi_index"]
        next_task = processor.next_task()
        while next_task and next_task.task_info()["mi_index"] > last_index:
            __update_task(processor, next_task, form_data, user)
            last_index = next_task.task_info()["mi_index"]
            next_task = processor.next_task()

    WorkflowService.update_task_assignments(processor)
    workflow_api_model = WorkflowService.processor_to_workflow_api(processor)
    return WorkflowApiSchema().dump(workflow_api_model)
Esempio n. 27
0
 def test_do_task_with_blank_second_approver(self):
     self.load_example_data()
     self.create_reference_document()
     workflow = self.create_workflow('empty_workflow')
     processor = WorkflowProcessor(workflow)
     task = processor.next_task()
     task.data = {"study": {"approval1": "dhf8r", 'approval2':''}}
     FileService.add_workflow_file(workflow_id=workflow.id,
                                   irb_doc_code="UVACompl_PRCAppr",
                                   name="anything.png", content_type="text",
                                   binary_data=b'1234')
     script = RequestApproval()
     script.do_task(task, workflow.study_id, workflow.id, "study.approval1", "study.approval2")
     self.assertEqual(1, db.session.query(ApprovalModel).count())
    def test_no_validation_error_when_correct_file_exists(self, mock_get):
        mock_get.return_value.ok = True
        mock_get.return_value.text = self.protocol_builder_response(
            'required_docs.json')

        self.load_example_data()
        study = session.query(StudyModel).first()
        workflow_spec_model = self.load_test_spec("two_forms")
        workflow_model = StudyService._create_workflow_model(
            study, workflow_spec_model)
        processor = WorkflowProcessor(workflow_model)
        task = processor.next_task()
        StudyInfo().do_task_validate_only(task, study.id, workflow_model.id,
                                          "documents")
    def test_find_by_id(self):
        spec = BaseTest.load_test_spec('enum_options_from_file')
        workflow = self.create_workflow('enum_options_from_file')
        processor = WorkflowProcessor(workflow)
        processor.do_engine_steps()

        result = LookupService.lookup(workflow,
                                      "TaskEnumLookup",
                                      "AllTheNames",
                                      None,
                                      value="1000")
        first_result = result[0]
        self.assertEquals(1000, first_result['CUSTOMER_NUMBER'])
        self.assertEquals('UVA - INTERNAL - GM USE ONLY',
                          first_result['CUSTOMER_NAME'])
 def test_timer_event(self):
     workflow = self.create_workflow('timer_event')
     processor = WorkflowProcessor(workflow)
     processor.do_engine_steps()
     task = processor.next_task()
     processor.complete_task(task)
     tasks = processor.get_ready_user_tasks()
     self.assertEqual(tasks, [])
     processor.save()
     time.sleep(.3)  # our timer is at .25 sec so we have to wait for it
     # get done waiting
     WorkflowService.do_waiting()
     wf = db.session.query(WorkflowModel).filter(
         WorkflowModel.id == workflow.id).first()
     self.assertTrue(wf.status != WorkflowStatus.waiting)