def test_archive_file_no_longer_shows_up(self): self.load_example_data() workflow = self.create_workflow('file_upload_form') processor = WorkflowProcessor(workflow) processor.do_engine_steps() 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_spec_name=%s&form_field_key=%s' % (workflow.study_id, workflow.id, task.get_name(), 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))))
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)
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)
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 get_workflow_from_spec(spec_id): workflow_model = WorkflowService.get_workflow_from_spec(spec_id, g.user) processor = WorkflowProcessor(workflow_model) processor.do_engine_steps() processor.save() WorkflowService.update_task_assignments(processor) workflow_api_model = WorkflowService.processor_to_workflow_api(processor) return WorkflowApiSchema().dump(workflow_api_model)
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)
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'])
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)
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))
def test_lookup_with_two_spreadsheets_with_the_same_field_name_in_different_forms( self): spec = BaseTest.load_test_spec('enum_options_competing_files') workflow = self.create_workflow('enum_options_competing_files') processor = WorkflowProcessor(workflow) processor.do_engine_steps() task = processor.get_ready_user_tasks()[0] task.data = {"type": "animals"} processor.complete_task(task) processor.do_engine_steps() task = processor.get_ready_user_tasks()[0] results = LookupService.lookup(workflow, task.task_spec.name, "selectedItem", "", value="pigs", limit=10) self.assertEqual( 1, len(results), "It is possible to find an item based on the id, rather than as a search" ) self.assertIsNotNone(results[0]) results = LookupService.lookup(workflow, task.task_spec.name, "selectedItem", "", value="apples", limit=10) self.assertEqual( 0, len(results), "We shouldn't find our fruits mixed in with our animals.") processor = WorkflowProcessor.reset(workflow, clear_data=True) processor.do_engine_steps() task = processor.get_ready_user_tasks()[0] task.data = {"type": "fruits"} processor.complete_task(task) processor.do_engine_steps() task = processor.get_ready_user_tasks()[0] results = LookupService.lookup(workflow, task.task_spec.name, "selectedItem", "", value="apples", limit=10) self.assertEqual( 1, len(results), "It is possible to find an item based on the id, rather than as a search" ) self.assertIsNotNone(results[0]) results = LookupService.lookup(workflow, task.task_spec.name, "selectedItem", "", value="pigs", limit=10) self.assertEqual( 0, len(results), "We shouldn't find our animals mixed in with our fruits.")
def get_workflow(workflow_id, do_engine_steps=True): """Retrieve workflow based on workflow_id, and return it in the last saved State. If do_engine_steps is False, return the workflow without running any engine tasks or logging any events. """ workflow_model: WorkflowModel = session.query(WorkflowModel).filter_by( id=workflow_id).first() processor = WorkflowProcessor(workflow_model) if do_engine_steps: processor.do_engine_steps() processor.save() WorkflowService.update_task_assignments(processor) workflow_api_model = WorkflowService.processor_to_workflow_api(processor) return WorkflowApiSchema().dump(workflow_api_model)
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)
def test_documentation_processing_handles_conditionals(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 = "This test {% if works == 'yes' %}works{% endif %}" docs = WorkflowService._process_documentation(task) self.assertEqual("This test ", docs) task.data = {"works": 'yes'} docs = WorkflowService._process_documentation(task) self.assertEqual("This test works", docs)
def test_total_tasks_updated(self, mock_docs, mock_details): """Assure that as a users progress is available when getting a list of studies for that user.""" app.config['PB_ENABLED'] = True docs_response = self.protocol_builder_response('required_docs.json') mock_docs.return_value = json.loads(docs_response) details_response = self.protocol_builder_response('study_details.json') mock_details.return_value = json.loads(details_response) user = self.create_user_with_study_and_workflow() # The load example data script should set us up a user and at least one study, one category, and one workflow. studies = StudyService().get_studies_for_user(user) self.assertTrue(len(studies) == 1) self.assertTrue(len(studies[0].categories) == 1) self.assertTrue(len(studies[0].categories[0].workflows) == 1) workflow = next(iter( studies[0].categories[0].workflows)) # Workflows is a set. # workflow should not be started, and it should have 0 completed tasks, and 0 total tasks. self.assertEqual(WorkflowStatus.not_started, workflow.status) self.assertEqual(0, workflow.total_tasks) self.assertEqual(0, workflow.completed_tasks) # Initialize the Workflow with the workflow processor. workflow_model = db.session.query(WorkflowModel).filter( WorkflowModel.id == workflow.id).first() processor = WorkflowProcessor(workflow_model) processor.do_engine_steps() # Assure the workflow is now started, and knows the total and completed tasks. studies = StudyService().get_studies_for_user(user) workflow = next(iter( studies[0].categories[0].workflows)) # Workflows is a set. # self.assertEqual(WorkflowStatus.user_input_required, workflow.status) self.assertTrue(workflow.total_tasks > 0) self.assertEqual(0, workflow.completed_tasks) # Complete a task task = processor.next_task() processor.complete_task(task) processor.save() # Assure the workflow has moved on to the next task. studies = StudyService().get_studies_for_user(user) workflow = next(iter( studies[0].categories[0].workflows)) # Workflows is a set. self.assertEqual(1, workflow.completed_tasks)
def test_lookup_based_on_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() results = LookupService.lookup(workflow, "AllTheNames", "", value="1000", limit=10) self.assertEqual( 1, len(results), "It is possible to find an item based on the id, rather than as a search" ) self.assertIsNotNone(results[0].data) self.assertIsInstance(results[0].data, dict)
def test_waiting_event_error(self): workflow = self.create_workflow('timer_event_error') processor = WorkflowProcessor(workflow) processor.do_engine_steps() processor.save() time.sleep(.3) # our timer is at .25 sec so we have to wait for it # get done waiting wf = db.session.query(WorkflowModel).filter( WorkflowModel.id == workflow.id).first() self.assertTrue(wf.status == WorkflowStatus.waiting) with self.assertLogs('crc', level='ERROR') as cm: WorkflowService.do_waiting() self.assertEqual(1, len(cm.output)) self.assertRegex(cm.output[0], f"workflow #%i" % workflow.id) self.assertRegex(cm.output[0], f"study #%i" % workflow.study_id) self.assertTrue(wf.status == WorkflowStatus.erroring)
def test_study_sponsors_script_fail(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_associate_fail") workflow_model = StudyService._create_workflow_model( study, workflow_spec_model) WorkflowService.test_spec("study_sponsors_associate_fail") processor = WorkflowProcessor(workflow_model) with self.assertRaises(ApiError): processor.do_engine_steps()
def test_load_irb_from_db(self, mock_study_service): # This depends on getting a list of investigators back from the protocol builder. mock_study_service.return_value = self.mock_investigator_response self.load_example_data() workflow_spec_model = self.create_workflow("irb_api_personnel") study = session.query(StudyModel).first() processor = WorkflowProcessor(workflow_spec_model) processor.do_engine_steps() task_list = processor.get_ready_user_tasks() processor.complete_task(task_list[0]) processor.do_engine_steps() nav_list = processor.bpmn_workflow.get_flat_nav_list() processor.save() # reload after save processor = WorkflowProcessor(workflow_spec_model) nav_list2 = processor.bpmn_workflow.get_flat_nav_list() self.assertEqual(nav_list, nav_list2)
def test_get_files_for_form_field_returns_only_those_files(self): self.create_reference_document() workflow = self.create_workflow('file_upload_form') processor = WorkflowProcessor(workflow) processor.do_engine_steps() task = processor.next_task() 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_spec_name=%s&form_field_key=%s' % (workflow.study_id, workflow.id, task.get_name(), correct_name), data=data, follow_redirects=True, content_type='multipart/form-data', headers=self.logged_in_headers()) self.assert_success(rv) # Note: this call can be made WITHOUT the task id. rv = self.app.get( '/v1.0/file?study_id=%i&workflow_id=%s&form_field_key=%s' % (workflow.study_id, workflow.id, correct_name), follow_redirects=True, content_type='multipart/form-data', headers=self.logged_in_headers()) self.assert_success(rv) json_data = json.loads(rv.get_data(as_text=True)) self.assertEqual(len(json_data), 1) # Add another file for a different document type FileService().add_workflow_file(workflow.id, 'Study_App_Doc', task.get_name(), 'otherdoc.docx', 'application/xcode', b"asdfasdf") # Note: this call can be made WITHOUT the task spec name. rv = self.app.get( '/v1.0/file?study_id=%i&workflow_id=%s&form_field_key=%s' % (workflow.study_id, workflow.id, correct_name), follow_redirects=True, content_type='multipart/form-data', headers=self.logged_in_headers()) self.assert_success(rv) json_data = json.loads(rv.get_data(as_text=True)) self.assertEqual(len(json_data), 1)
def test_study_sponsors_script(self, mock_get): mock_get.return_value.ok = True mock_get.return_value.text = self.protocol_builder_response( 'sponsors.json') app.config['PB_ENABLED'] = True self.load_example_data() study = session.query(StudyModel).first() workflow_spec_model = self.load_test_spec("study_sponsors") workflow_model = StudyService._create_workflow_model( study, workflow_spec_model) WorkflowService.test_spec("study_sponsors") processor = WorkflowProcessor(workflow_model) processor.do_engine_steps() self.assertTrue(processor.bpmn_workflow.is_completed()) data = processor.next_task().data self.assertIn('sponsors', data) self.assertEqual(3, len(data['sponsors']))
def test_add_file_from_task_and_form_errors_on_invalid_form_field_name( self): self.create_reference_document() workflow = self.create_workflow('file_upload_form') processor = WorkflowProcessor(workflow) processor.do_engine_steps() 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_spec_name=%s&form_field_key=%s' % (workflow.study_id, workflow.id, task.get_name(), correct_name), data=data, follow_redirects=True, content_type='multipart/form-data', headers=self.logged_in_headers()) self.assert_success(rv)
def test_file_datastore_workflow(self): self.load_example_data() # we need to create a file with an IRB code # for this study workflow = self.create_workflow('file_data_store') irb_code = "UVACompl_PRCAppr" # The first file referenced in pb required docs. FileService.add_workflow_file(workflow_id=workflow.id, task_spec_name='task1', name="anything.png", content_type="text", binary_data=b'1234', irb_doc_code=irb_code) processor = WorkflowProcessor(workflow) processor.do_engine_steps() task_data = processor.bpmn_workflow.last_task.data self.assertTrue(str(task_data['fileid']) in task_data['fileurl']) self.assertEqual(task_data['filename'], 'anything.png') self.assertEqual(task_data['output'], 'me') self.assertEqual(task_data['output2'], 'nope')
def update_task(workflow_id, task_id, body, terminate_loop=None): 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) elif workflow_model.study is None: raise ApiError("invalid_study", "There is no study associated with the given workflow.", 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) 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: spiff_task.terminate_loop() spiff_task.update_data(body) processor.complete_task(spiff_task) processor.do_engine_steps() processor.save() # Log the action, and any pending task assignments in the event of lanes in the workflow. WorkflowService.log_task_action(g.user.uid, processor, spiff_task, WorkflowService.TASK_ACTION_COMPLETE) WorkflowService.update_task_assignments(processor) workflow_api_model = WorkflowService.processor_to_workflow_api(processor) return WorkflowApiSchema().dump(workflow_api_model)
def test_add_file_returns_document_metadata(self): self.create_reference_document() workflow = self.create_workflow('file_upload_form_single') processor = WorkflowProcessor(workflow) processor.do_engine_steps() task = processor.next_task() 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_spec_name=%s&form_field_key=%s' % (workflow.study_id, workflow.id, task.get_name(), correct_name), data=data, follow_redirects=True, content_type='multipart/form-data', headers=self.logged_in_headers()) self.assert_success(rv) json_data = json.loads(rv.get_data(as_text=True)) self.assertEqual('Ancillary Document', json_data['document']['category1']) self.assertEqual('Study Team', json_data['document']['who_uploads?'])
def test_study_sponsors_script_primary_user(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_associate_switch_user") workflow_model = StudyService._create_workflow_model( study, workflow_spec_model) WorkflowService.test_spec("study_sponsors_associate_switch_user") processor = WorkflowProcessor(workflow_model) processor.do_engine_steps() tasks = processor.next_user_tasks() self.assertEqual(len(tasks), 1) processor.complete_task(tasks[0]) processor.do_engine_steps() self.assertTrue(processor.bpmn_workflow.is_completed())
def test_study_sponsors_script_valid_users(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_associate_switch_user") workflow_model = StudyService._create_workflow_model( study, workflow_spec_model) WorkflowService.test_spec("study_sponsors_associate_switch_user") processor = WorkflowProcessor(workflow_model) processor.do_engine_steps() tasks = processor.next_user_tasks() self.assertEqual(len(tasks), 1) users = WorkflowService.get_users_assigned_to_task(processor, tasks[0]) self.assertFalse('cah3us' in users) self.assertFalse('lje5u' in users) self.assertTrue('lb3dp' in users) self.assertTrue('dhf8r' in users)
def test_hard_reset(self): self.load_example_data() # Start the two_forms workflow, and enter some data in the first form. study = session.query(StudyModel).first() workflow_spec_model = self.load_test_spec("two_forms") processor = self.get_processor(study, workflow_spec_model) processor.do_engine_steps() self.assertEqual(processor.workflow_model.workflow_spec_id, workflow_spec_model.id) task = processor.next_task() task.data = {"color": "blue"} processor.complete_task(task) next_task = processor.next_task() self.assertEqual("Step 2", next_task.task_spec.description) # Modify the specification, with a major change that alters the flow and can't be serialized effectively. file_path = os.path.join(app.root_path, '..', 'tests', 'data', 'two_forms', 'modified', 'two_forms_struc_mod.bpmn') self.replace_file("two_forms.bpmn", file_path) # Assure that creating a new processor doesn't cause any issues, and maintains the spec version. processor.workflow_model.bpmn_workflow_json = processor.serialize() db.session.add(processor.workflow_model) ## Assure this isn't transient, which was causing some errors. self.assertIsNotNone(processor.workflow_model.bpmn_workflow_json) processor2 = WorkflowProcessor(processor.workflow_model) # self.assertFalse(processor2.is_latest_spec) # Still at version 1. # Do a hard reset, which should bring us back to the beginning, but retain the data. processor2 = WorkflowProcessor.reset(processor2.workflow_model) processor3 = WorkflowProcessor(processor.workflow_model) processor3.do_engine_steps() self.assertEqual("Step 1", processor3.next_task().task_spec.description) # self.assertTrue(processor3.is_latest_spec) # Now at version 2. task = processor3.next_task() task.data = {"color": "blue"} processor3.complete_task(task) self.assertEqual("New Step", processor3.next_task().task_spec.description) self.assertEqual("blue", processor3.next_task().data["color"])
def test_some_full_text_queries(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() results = LookupService.lookup(workflow, "AllTheNames", "", limit=10) self.assertEqual(10, len(results), "Blank queries return everything, to the limit") results = LookupService.lookup(workflow, "AllTheNames", "medicines", limit=10) self.assertEqual(1, len(results), "words in the middle of label are detected.") self.assertEqual("The Medicines Company", results[0].label) results = LookupService.lookup(workflow, "AllTheNames", "UVA", limit=10) self.assertEqual(1, len(results), "Beginning of label is found.") self.assertEqual("UVA - INTERNAL - GM USE ONLY", results[0].label) results = LookupService.lookup(workflow, "AllTheNames", "uva", limit=10) self.assertEqual(1, len(results), "case does not matter.") self.assertEqual("UVA - INTERNAL - GM USE ONLY", results[0].label) results = LookupService.lookup(workflow, "AllTheNames", "medici", limit=10) self.assertEqual(1, len(results), "partial words are picked up.") self.assertEqual("The Medicines Company", results[0].label) results = LookupService.lookup(workflow, "AllTheNames", "Genetics Savings", limit=10) self.assertEqual(1, len(results), "multiple terms are picked up..") self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label) results = LookupService.lookup(workflow, "AllTheNames", "Genetics Sav", limit=10) self.assertEqual(1, len(results), "prefix queries still work with partial terms") self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label) results = LookupService.lookup(workflow, "AllTheNames", "Gen Sav", limit=10) self.assertEqual( 1, len(results), "prefix queries still work with ALL the partial terms") self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label) results = LookupService.lookup(workflow, "AllTheNames", "Inc", limit=10) self.assertEqual(7, len(results), "short terms get multiple correct results.") self.assertEqual("Genetics Savings & Clone, Inc.", results[0].label) results = LookupService.lookup(workflow, "AllTheNames", "reaction design", limit=10) self.assertEqual(5, len(results), "all results come back for two terms.") self.assertEqual("Reaction Design", results[0].label, "Exact matches come first.") results = LookupService.lookup(workflow, "AllTheNames", "1 Something", limit=10) self.assertEqual("1 Something", results[0].label, "Exact matches are prefered") results = LookupService.lookup(workflow, "AllTheNames", "1 (!-Something", limit=10) self.assertEqual("1 Something", results[0].label, "special characters don't flake out") results = LookupService.lookup(workflow, "AllTheNames", "1 Something", limit=10) self.assertEqual("1 Something", results[0].label, "double spaces should not be an issue.")