def test_user_by_organization(self): # generate a handful of users in different orgs org_evens = Organization(name='odds') org_odds = Organization(name='odds') with SessionScope(db): map(db.session.add,(org_evens, org_odds)) for i in range(5): user = self.add_user(username='******'.format(i)) if i % 2: user.organizations.append(org_odds) else: user.organizations.append(org_evens) db.session.add(user) db.session.commit() org_evens, org_odds = map(db.session.merge, (org_evens, org_odds)) evens = org_evens.users odds = org_odds.users self.assertEqual(3, len(evens)) self.assertEqual(2, len(odds)) pattern = re.compile(r'test_user(\d+)@foo.com') self.assertTrue( all([int(pattern.match(o.username).groups()[0]) % 2 for o in odds]))
def test_organization_get_by_identifier(self): org_id_system = "http://test/system" org_id_value = "testval" self.login() org = Organization(name='test', id=999) ident = Identifier(id=99, system=org_id_system, value=org_id_value) org_ident = OrganizationIdentifier(organization_id=999, identifier_id=99) with SessionScope(db): db.session.add(org) db.session.add(ident) db.session.commit() db.session.add(org_ident) db.session.commit() # use api to obtain FHIR response = self.client.get( '/api/organization?system={system}&value={value}'.format( system=quote_plus(org_id_system), value=org_id_value)) assert response.status_code == 200 assert response.json['total'] == 1 assert response.json['entry'][0]['id'] == 999 # use alternative API to obtain organization response = self.client.get( '/api/organization/{value}?system={system}'.format( system=quote_plus(org_id_system), value=org_id_value)) assert response.status_code == 200 fetched = Organization.from_fhir(response.json) org = db.session.merge(org) assert org.id == fetched.id assert org.name == fetched.name
def test_timezone_inheritance(self): parent = Organization(id=101, name='parentOrg') org = Organization(id=102, name='org', partOf_id=101) # test that with no timezones set, defaults to UTC with SessionScope(db): db.session.add(parent) db.session.add(org) db.session.commit() parent, org = map(db.session.merge, (parent, org)) assert org.timezone == 'UTC' # test that timezone-less child org inherits from parent parent.timezone = 'Asia/Tokyo' with SessionScope(db): db.session.add(parent) db.session.commit() parent, org = map(db.session.merge, (parent, org)) assert org.timezone == 'Asia/Tokyo' # test that child org with timezone does NOT inherit from parent org.timezone = 'Europe/Rome' with SessionScope(db): db.session.add(org) db.session.commit() org = db.session.merge(org) assert org.timezone == 'Europe/Rome'
def test_overdue_table_html(self): org = Organization(name='OrgC', id=101) org2 = Organization(name='OrgB', id=102, partOf_id=101) org3 = Organization(name='OrgA', id=103, partOf_id=101) false_org = Organization(name='falseorg') user = self.add_user('test_user)') with SessionScope(db): db.session.add(org) db.session.add(org3) db.session.add(org2) db.session.add(false_org) user.organizations.append(org) user.organizations.append(org3) user.organizations.append(org2) user.organizations.append(false_org) db.session.add(user) db.session.commit() org, org2, org3, false_org, user = map( db.session.merge, (org, org2, org3, false_org, user)) ostats = { (org3.id, org3.name): [(2, 101), (3, 102)], (org2.id, org2.name): [(1, 103), (5, 104)], (org.id, org.name): [(1, 105), (8, 106), (9, 107), (11, 108)] } cutoffs = [5, 10] table1 = generate_overdue_table_html(cutoff_days=cutoffs, overdue_stats=ostats, user=user, top_org=org) assert '<table>' in table1 assert '<th>1-5 Days</th>' in table1 assert '<th>6-10 Days</th>' in table1 assert '<td>{}</td>'.format(org.name) in table1 org_row = r'\s*'.join(( '<td>{}</td>', '<td>1</td>', '<td>2</td>', '<td>3</td>', )).format(org.name) assert search(org_row, table1) # confirm alphabetical order org_order = r'{}[^O]*{}[^O]*{}'.format(org3.name, org2.name, org.name) assert search(org_order, table1) # confirm that the table contains no orgs table2 = generate_overdue_table_html(cutoff_days=cutoffs, overdue_stats=ostats, user=user, top_org=false_org) assert '<table>' in table2 # org should not show up, as the table's top_org=false_org assert not '<td>{}</td>'.format(org.name) in table2 # false_org should not show up, as it's not in the ostats assert not '<td>{}</td>'.format(false_org.name) in table2
def test_from_fhir_partOf(self): # prepopulate database with parent organization parent = Organization(id=101, name='fake parent reference') with SessionScope(db): db.session.add(parent) db.session.commit() parent = db.session.merge(parent) parent_id = parent.id with (open( os.path.join(os.path.dirname(__file__), 'organization-example-f002-burgers-card.json'), 'r')) as fhir_data: data = json.load(fhir_data) # remove the id from the file - doesn't play well with ours data.pop('id') org = Organization.from_fhir(data) assert org.addresses[0].line1 == data['address'][0]['line'][0] assert org.name == data['name'] assert org.phone == "022-655 2320" assert org.partOf_id == parent_id # confirm we can store with SessionScope(db): db.session.add(org) db.session.commit() org = db.session.merge(org) assert org.id assert org.partOf_id == parent_id
def test_multiple_rps_in_fhir(self): yesterday = datetime.utcnow() - timedelta(days=1) lastyear = datetime.utcnow() - timedelta(days=365) org = Organization(name='Testy') rp1 = ResearchProtocol(name='rp1') rp2 = ResearchProtocol(name='yesterday') rp3 = ResearchProtocol(name='last year') with SessionScope(db): map(db.session.add, (org, rp1, rp2, rp3)) db.session.commit() org, rp1, rp2, rp3 = map(db.session.merge, (org, rp1, rp2, rp3)) o_rp1 = OrganizationResearchProtocol( research_protocol=rp1, organization=org) o_rp2 = OrganizationResearchProtocol( research_protocol=rp2, organization=org, retired_as_of=yesterday) o_rp3 = OrganizationResearchProtocol( research_protocol=rp3, organization=org, retired_as_of=lastyear) with SessionScope(db): map(db.session.add, (o_rp1, o_rp2, o_rp3)) db.session.commit() org, rp1, rp2, rp3 = map(db.session.merge, (org, rp1, rp2, rp3)) data = org.as_fhir() assert org.name == data['name'] rps = [ extension for extension in data['extension'] if extension['url'] == ResearchProtocolExtension.extension_url] assert len(rps) == 1 assert len(rps[0]['research_protocols']) == 3 # confirm the order is descending in the custom accessor method results = [(rp, retired) for rp, retired in org.rps_w_retired()] assert [(rp1, None), (rp2, yesterday), (rp3, lastyear)] == results
def test_organization_extension_update(self): # confirm clearing one of several extensions works self.promote_user(role_name=ROLE.ADMIN.value) self.login() en_AU = LocaleConstants().AustralianEnglish # Populate db with complete org, and set many fields org = Organization(name='test', phone='800-800-5665', timezone='US/Pacific') org.identifiers.append( Identifier(value='state:NY', system=PRACTICE_REGION)) org.locales.append(en_AU) org.default_locale = 'en_AU' rp = ResearchProtocol(name='rp1') with SessionScope(db): db.session.add(rp) db.session.add(org) db.session.commit() org, rp = map(db.session.merge, (org, rp)) org_id, rp_id = org.id, rp.id org.research_protocols.append(rp) data = org.as_fhir() input = { k: v for k, v in data.items() if k in ('name', 'resourceType') } # Replace locale extension with null value, copy # over others. input['extension'] = [ e for e in data['extension'] if e['url'] != LocaleExtension.extension_url ] input['extension'].append({'url': LocaleExtension.extension_url}) response = self.client.put('/api/organization/{}'.format(org_id), content_type='application/json', data=json.dumps(input)) assert response.status_code == 200 # Pull the updated db entry org = Organization.query.get(org_id) en_AU = db.session.merge(en_AU) # Confirm all the unmentioned entries survived assert org.phone == '800-800-5665' assert org.default_locale == 'en_AU' assert org.locales.count() == 0 assert org.timezone == 'US/Pacific' assert org.research_protocol(as_of_date=datetime.utcnow()).id == rp_id # Confirm empty extension isn't included in result results = response.json for e in results['extension']: assert 'url' in e assert len(e.keys()) > 1
def test_rp_alteration(self): # orgs with old rp should migrate to multiple w/ updated retired from portal.system_uri import SHORTCUT_ALIAS, TRUENTH_CR_NAME from portal.models.identifier import Identifier rp1 = ResearchProtocol(name='initial') rp2 = ResearchProtocol(name='replacement') org = Organization(name='testy') org.research_protocols.append(rp1) with SessionScope(db): db.session.add(rp2) db.session.add(org) db.session.commit() mp = ModelPersistence(Organization, lookup_field='id', sequence_name='organizations_id_seq', target_dir=self.tmpdir) mp.export() # Add second rp, mark old as retired with open(os.path.join(self.tmpdir, 'Organization.json'), 'r') as pfile: data = json.load(pfile) now = datetime.utcnow().replace(microsecond=0) updated = { 'url': ResearchProtocolExtension.extension_url, 'research_protocols': [{ "name": 'replacement' }, { "name": 'initial', "retired_as_of": FHIR_datetime.as_fhir(now) }] } for i, entry in enumerate(data['entry']): if entry['name'] != 'testy': continue extensions = entry['extension'] keepers = [ ext for ext in extensions if ext['url'] != ResearchProtocolExtension.extension_url ] keepers.append(updated) data['entry'][i]['extension'] = keepers with open(os.path.join(self.tmpdir, 'Organization.json'), 'w') as pfile: pfile.write(json.dumps(data)) mp.import_(keep_unmentioned=False) org = Organization.query.filter(Organization.name == 'testy').one() assert len(org.research_protocols) == 2 # Make sure retired_as_of was set properly on old rp1, rp2 = map(db.session.merge, (rp1, rp2)) expected = [(rp2, None), (rp1, now)] results = [(rp, retired) for rp, retired in org.rps_w_retired()] assert results == expected
def test_as_fhir(self): org = Organization(name='Homer\'s Hospital') org.use_specific_codings = True org.race_codings = False data = org.as_fhir() self.assertEquals(org.name, data['name']) self.assertTrue(data['use_specific_codings']) self.assertFalse(data['race_codings'])
def test_as_fhir(self): org = Organization(name='Homer\'s Hospital') org.use_specific_codings = True org.race_codings = False data = org.as_fhir() assert org.name == data['name'] assert data['use_specific_codings'] assert not data['race_codings']
def test_permissions(self): """Shouldn't get results from orgs outside view permissions""" # Generate a few patients from different orgs org1_name, org2_name = 'test_org1', 'test_org2' org1 = Organization(name=org1_name) org2 = Organization(name=org2_name) with SessionScope(db): db.session.add(org1) db.session.add(org2) db.session.commit() org1 = db.session.merge(org1) org1_id = org1.id self.setup_org_qbs(org1) org2 = db.session.merge(org2) self.setup_org_qbs(org2) user2 = self.add_user('user2') user3 = self.add_user('user3') user4 = self.add_user('user4') with SessionScope(db): db.session.add(user2) db.session.add(user3) db.session.add(user4) db.session.commit() user2 = db.session.merge(user2) user3 = db.session.merge(user3) user4 = db.session.merge(user4) now = datetime.utcnow() back15, nowish = associative_backdate(now, relativedelta(days=15)) back45, nowish = associative_backdate(now, relativedelta(days=45)) back115, nowish = associative_backdate(now, relativedelta(days=115)) self.bless_with_basics(user=user2, setdate=back15, local_metastatic=org1_name) self.bless_with_basics(user=user3, setdate=back45, local_metastatic=org1_name) self.bless_with_basics(user=user4, setdate=back115, local_metastatic=org2_name) self.test_user = db.session.merge(self.test_user) self.promote_user(role_name=ROLE.STAFF.value) self.login() response = self.client.get("/api/report/questionnaire_status") assert response.status_code == 200 # with zero orgs in common, should see empty result set assert response.json['total'] == 0 # Add org to staff to see results from matching patiens (2&3) self.consent_with_org(org_id=org1_id) response = self.client.get("/api/report/questionnaire_status") assert response.status_code == 200 assert response.json['total'] == 2
def shallow_org_tree(self): """Create shallow org tree for common test needs""" org_101 = Organization(id=101, name='101') org_102 = Organization(id=102, name='102') org_1001 = Organization(id=1001, name='1001', partOf_id=101) with SessionScope(db): [db.session.add(org) for org in (org_101, org_102, org_1001)] db.session.commit() OrgTree.invalidate_cache()
def test_organization_extension_update(self): # confirm clearing one of several extensions works self.promote_user(role_name=ROLE.ADMIN.value) self.login() en_AU = LocaleConstants().AustralianEnglish # Populate db with complete org, and set many fields org = Organization( name='test', phone='800-800-5665', timezone='US/Pacific') org.identifiers.append(Identifier( value='state:NY', system=PRACTICE_REGION)) org.locales.append(en_AU) org.default_locale = 'en_AU' rp = ResearchProtocol(name='rp1') with SessionScope(db): db.session.add(rp) db.session.add(org) db.session.commit() org, rp = map(db.session.merge, (org, rp)) org_id, rp_id = org.id, rp.id org.research_protocols.append(rp) data = org.as_fhir() input = {k: v for k, v in data.items() if k in ( 'name', 'resourceType')} # Replace locale extension with null value, copy # over others. input['extension'] = [ e for e in data['extension'] if e['url'] != LocaleExtension.extension_url] input['extension'].append({'url': LocaleExtension.extension_url}) response = self.client.put( '/api/organization/{}'.format(org_id), content_type='application/json', data=json.dumps(input)) assert response.status_code == 200 # Pull the updated db entry org = Organization.query.get(org_id) en_AU = db.session.merge(en_AU) # Confirm all the unmentioned entries survived assert org.phone == '800-800-5665' assert org.default_locale == 'en_AU' assert org.locales.count() == 0 assert org.timezone == 'US/Pacific' assert org.research_protocol(as_of_date=datetime.utcnow()).id == rp_id # Confirm empty extension isn't included in result results = response.json for e in results['extension']: assert 'url' in e assert len(e.keys()) > 1
def deepen_org_tree(self): """Create deeper tree when test needs it""" self.shallow_org_tree() org_l2 = Organization(id=1002, name='l2', partOf_id=102) org_l3_1 = Organization(id=10031, name='l3_1', partOf_id=1002) org_l3_2 = Organization(id=10032, name='l3_2', partOf_id=1002) with SessionScope(db): [db.session.add(org) for org in (org_l2, org_l3_1, org_l3_2)] db.session.commit() OrgTree.invalidate_cache()
def test_rp_alteration(self): # orgs with old rp should migrate to multiple w/ updated retired from portal.system_uri import SHORTCUT_ALIAS, TRUENTH_CR_NAME from portal.models.identifier import Identifier rp1 = ResearchProtocol(name='initial') rp2 = ResearchProtocol(name='replacement') org = Organization(name='testy') org.research_protocols.append(rp1) with SessionScope(db): db.session.add(rp2) db.session.add(org) db.session.commit() mp = ModelPersistence( Organization, lookup_field='id', sequence_name='organizations_id_seq', target_dir=self.tmpdir) mp.export() # Add second rp, mark old as retired with open( os.path.join(self.tmpdir, 'Organization.json'), 'r') as pfile: data = json.load(pfile) now = datetime.utcnow().replace(microsecond=0) updated = { 'url': ResearchProtocolExtension.extension_url, 'research_protocols': [ {"name": 'replacement'}, {"name": 'initial', "retired_as_of": FHIR_datetime.as_fhir( now)}]} for i, entry in enumerate(data['entry']): if entry['name'] != 'testy': continue extensions = entry['extension'] keepers = [ ext for ext in extensions if ext['url'] != ResearchProtocolExtension.extension_url] keepers.append(updated) data['entry'][i]['extension'] = keepers with open( os.path.join(self.tmpdir, 'Organization.json'), 'w') as pfile: pfile.write(json.dumps(data)) mp.import_(keep_unmentioned=False) org = Organization.query.filter(Organization.name == 'testy').one() assert len(org.research_protocols) == 2 # Make sure retired_as_of was set properly on old rp1, rp2 = map(db.session.merge, (rp1, rp2)) expected = [(rp2, None), (rp1, now)] results = [(rp, retired) for rp, retired in org.rps_w_retired()] assert results == expected
def test_overdue_table_html(self): org = Organization(name='OrgC', id=101) org2 = Organization(name='OrgB', id=102, partOf_id=101) org3 = Organization(name='OrgA', id=103, partOf_id=101) false_org = Organization(name='falseorg') user = self.add_user('test_user)') with SessionScope(db): db.session.add(org) db.session.add(org3) db.session.add(org2) db.session.add(false_org) user.organizations.append(org) user.organizations.append(org3) user.organizations.append(org2) user.organizations.append(false_org) db.session.add(user) db.session.commit() org, org2, org3, false_org, user = map( db.session.merge, (org, org2, org3, false_org, user)) ostats = {org3: [2, 3], org2: [1, 5], org: [1, 8, 9, 11]} cutoffs = [5, 10] table1 = generate_overdue_table_html(cutoff_days=cutoffs, overdue_stats=ostats, user=user, top_org=org) self.assertTrue('<table>' in table1) self.assertTrue('<th>1-5 Days</th>' in table1) self.assertTrue('<th>6-10 Days</th>' in table1) self.assertTrue('<td>{}</td>'.format(org.name) in table1) org_row = (r'<td>{}<\/td>\s*<td>1<\/td>\s*' '<td>2<\/td>\s*<td>3<\/td>'.format(org.name)) self.assertTrue(search(org_row, table1)) # confirm alphabetical order org_order = r'{}[^O]*{}[^O]*{}'.format(org3.name, org2.name, org.name) self.assertTrue(search(org_order, table1)) # confirm that the table contains no orgs table2 = generate_overdue_table_html(cutoff_days=cutoffs, overdue_stats=ostats, user=user, top_org=false_org) self.assertTrue('<table>' in table2) # org should not show up, as the table's top_org=false_org self.assertFalse('<td>{}</td>'.format(org.name) in table2) # false_org should not show up, as it's not in the ostats self.assertFalse('<td>{}</td>'.format(false_org.name) in table2)
def test_delete_extension(self): org = Organization(name='testy') org.timezone = 'Asia/Tokyo' # stored in an extension with SessionScope(db): db.session.add(org) db.session.commit() org = db.session.merge(org) mp = ModelPersistence( Organization, lookup_field='id', sequence_name='organizations_id_seq', target_dir=self.tmpdir) mp.export() # Strip the empty extensions, as expected in the real persistence file with open( os.path.join(self.tmpdir, 'Organization.json'), 'r') as pfile: data = json.load(pfile) # Special handling of extensions - empties only have 'url' key for i, entry in enumerate(data['entry']): extensions = entry['extension'] keepers = [] for e in extensions: if len(e.keys()) > 1: keepers.append(e) data['entry'][i]['extension'] = keepers empty_keys = [k for k, v in entry.items() if not v] for k in empty_keys: del data['entry'][i][k] with open( os.path.join(self.tmpdir, 'Organization.json'), 'w') as pfile: pfile.write(json.dumps(data)) # Add an additional extension to the org, make sure # they are deleted when importing again from # persistence that doesn't include them org.locales.append(LocaleConstants().AmericanEnglish) with SessionScope(db): db.session.commit() org = db.session.merge(org) assert len(org.as_fhir()['extension']) > 1 mp.import_(keep_unmentioned=False) org = Organization.query.filter(Organization.name == 'testy').one() assert org.locales.count() == 0 assert org.timezone == 'Asia/Tokyo'
def test_from_fhir_partOf(self): # prepopulate database with parent organization parent = Organization(id=101, name='fake parent reference') with SessionScope(db): db.session.add(parent) db.session.commit() parent = db.session.merge(parent) parent_id = parent.id with (open( os.path.join( os.path.dirname(__file__), 'organization-example-f002-burgers-card.json'), 'r') ) as fhir_data: data = json.load(fhir_data) # remove the id from the file - doesn't play well with ours data.pop('id') org = Organization.from_fhir(data) assert org.addresses[0].line1 == data['address'][0]['line'][0] assert org.name == data['name'] assert org.phone == "022-655 2320" assert org.partOf_id == parent_id # confirm we can store with SessionScope(db): db.session.add(org) db.session.commit() org = db.session.merge(org) assert org.id assert org.partOf_id == parent_id
def test_music_exception(self): "For patients with music org, the terms get special handling" music_org = Organization( name="Michigan Urological Surgery Improvement Collaborative" " (MUSIC)") with SessionScope(db): db.session.add(music_org) db.session.commit() music_org = db.session.merge(music_org) self.config_as(system=TRUENTH, ACCEPT_TERMS_ON_NEXT_ORG=music_org.name) self.test_user = db.session.merge(self.test_user) self.test_user.organizations.append(music_org) self.promote_user(role_name=ROLE.PATIENT.value) user = db.session.merge(self.test_user) needed = Coredata().still_needed(user) assert ({ 'field': WEB_TOU, 'collection_method': "ACCEPT_ON_NEXT" } in needed) self.login() resp = self.client.get( '/api/coredata/user/{}/still_needed'.format(TEST_USER_ID)) assert resp.status_code == 200 passed = False for entry in resp.json['still_needed']: if entry['field'] == WEB_TOU: assert entry['collection_method'] == 'ACCEPT_ON_NEXT' passed = True assert passed
def test_organization_get_by_identifier(self): org_id_system = "http://test/system" org_id_value = "testval" self.login() org = Organization(name='test', id=999) ident = Identifier(id=99, system=org_id_system, value=org_id_value) org_ident = OrganizationIdentifier( organization_id=999, identifier_id=99) with SessionScope(db): db.session.add(org) db.session.add(ident) db.session.commit() db.session.add(org_ident) db.session.commit() # use api to obtain FHIR response = self.client.get( '/api/organization?system={system}&value={value}'.format( system=quote_plus(org_id_system), value=org_id_value)) assert response.status_code == 200 assert response.json['total'] == 1 assert response.json['entry'][0]['id'] == 999 # use alternative API to obtain organization response = self.client.get( '/api/organization/{value}?system={system}'.format( system=quote_plus(org_id_system), value=org_id_value)) assert response.status_code == 200 fetched = Organization.from_fhir(response.json) org = db.session.merge(org) assert org.id == fetched.id assert org.name == fetched.name
def test_serialize(self): q1 = Questionnaire(name='q1') q2 = Questionnaire(name='q2') org = Organization(name='org') with SessionScope(db): db.session.add(q1) db.session.add(q2) db.session.add(org) db.session.commit() q1, q2, org = map(db.session.merge, (q1, q2, org)) qb = QuestionnaireBank(name='qb', organization_id=org.id, classification='baseline') for rank, q in enumerate((q1, q2)): qbq = QuestionnaireBankQuestionnaire(days_till_due=5, days_till_overdue=30, rank=rank, questionnaire=q) qb.questionnaires.append(qbq) with SessionScope(db): db.session.add(qb) db.session.commit() qb = db.session.merge(qb) data = qb.as_json() self.assertEquals('QuestionnaireBank', data.get('resourceType')) self.assertEquals(2, len(data['questionnaires']))
def setup_org_n_rp(org=None, org_name='org', rp_name='proto', retired_as_of=None): """Create simple test org with RP, return (org, rp, rp_id)""" if not org: org = Organization(name=org_name) # RP may have already been setup - confirm # it's assigned to given org and return existing_rp = ResearchProtocol.query.filter( ResearchProtocol.name == rp_name).first() if existing_rp: if existing_rp not in org.research_protocols: org.research_protocols.append(existing_rp) return org, existing_rp, existing_rp.id rp = ResearchProtocol(name=rp_name) with SessionScope(db): db.session.add(org) db.session.add(rp) db.session.commit() org, rp = map(db.session.merge, (org, rp)) if not retired_as_of: org.research_protocols.append(rp) else: o_rp = OrganizationResearchProtocol(research_protocol=rp, organization=org, retired_as_of=retired_as_of) with SessionScope(db): db.session.add(o_rp) db.session.commit() org, rp = map(db.session.merge, (org, rp)) return (org, rp, rp.id)
def test_from_fhir(self): with open( os.path.join(os.path.dirname(__file__), 'organization-example-f001-burgers.json'), 'r') as fhir_data: data = json.load(fhir_data) #prepopuate database with matching locale Coding.from_fhir({ 'code': 'en_AU', 'display': 'Australian English', 'system': "urn:ietf:bcp:47" }) org = Organization.from_fhir(data) self.assertEquals(org.addresses[0].line1, data['address'][0]['line'][0]) self.assertEquals(org.addresses[1].line1, data['address'][1]['line'][0]) self.assertEquals(org.name, data['name']) self.assertEquals(org.phone, "022-655 2300") self.assertTrue(org.use_specific_codings) self.assertTrue(org.race_codings) self.assertFalse(org.ethnicity_codings) self.assertEquals(org.locales.count(), 1) self.assertEquals(org.default_locale, "en_AU")
def test_clinc_id(self): # Create several orgs with identifier org1 = Organization(name='org1') org2 = Organization(name='org2') org3 = Organization(name='org3') identifier = Identifier(value='pick me', system=DECISION_SUPPORT_GROUP) for org in (org1, org2, org3): org.identifiers.append(identifier) # Add access strategy to the care plan intervention cp = INTERVENTION.CARE_PLAN cp.public_access = False # turn off public access to force strategy cp_id = cp.id with SessionScope(db): map(db.session.add, (org1, org2, org3)) db.session.commit() org1, org2, org3 = map(db.session.merge, (org1, org2, org3)) d = { 'function': 'limit_by_clinic_w_id', 'kwargs': [{ 'name': 'identifier_value', 'value': 'pick me' }] } strat = AccessStrategy(name="member of org with identifier", intervention_id=cp_id, function_details=json.dumps(d)) with SessionScope(db): db.session.add(strat) db.session.commit() cp = INTERVENTION.CARE_PLAN user = db.session.merge(self.test_user) # Prior to associating user with any orgs, shouldn't have access self.assertFalse(cp.display_for_user(user).access) # Add association and test again user.organizations.append(org3) with SessionScope(db): db.session.commit() user, cp = map(db.session.merge, (user, cp)) self.assertTrue(cp.display_for_user(user).access)
def test_overdue_stats(self): self.promote_user(user=self.test_user, role_name=ROLE.PATIENT.value) rp = ResearchProtocol(name='proto') with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) rp_id = rp.id crv = Organization(name='CRV') crv.research_protocols.append(rp) epic26 = self.add_questionnaire(name='epic26') with SessionScope(db): db.session.add(crv) db.session.commit() crv, epic26 = map(db.session.merge, (crv, epic26)) crv_id = crv.id bank = QuestionnaireBank(name='CRV', research_protocol_id=rp_id, start='{"days": 1}', overdue='{"days": 2}', expired='{"days": 90}') qbq = QuestionnaireBankQuestionnaire(questionnaire_id=epic26.id, rank=0) bank.questionnaires.append(qbq) with SessionScope(db): db.session.add(bank) db.session.commit() self.test_user = db.session.merge(self.test_user) self.test_user.organizations.append(crv) self.consent_with_org(org_id=crv_id) self.test_user = db.session.merge(self.test_user) # test user with status = 'Expired' (should not show up) a_s = QB_Status(self.test_user, as_of_date=datetime.utcnow()) assert a_s.overall_status == OverallStatus.expired ostats = self.get_ostats() assert len(ostats) == 0 # test user with status = 'Overdue' (should show up) self.consent_with_org(org_id=crv_id, backdate=relativedelta(days=18)) with SessionScope(db): db.session.add(bank) db.session.commit() crv, self.test_user = map(db.session.merge, (crv, self.test_user)) invalidate_users_QBT(self.test_user.id) a_s = QB_Status(self.test_user, as_of_date=datetime.utcnow()) assert a_s.overall_status == OverallStatus.overdue ostats = self.get_ostats() assert len(ostats) == 1 assert ostats[(crv.id, crv.name)] == [(15, TEST_USER_ID)]
def prep_org_w_identifier(self): o = Organization(name='test org') i = Identifier(system=US_NPI, value='123-45') o.identifiers.append(i) with SessionScope(db): db.session.add(o) db.session.commit() o = db.session.merge(o) return o
def test_submit_assessment_for_qb(self): swagger_spec = swagger(self.app) data = swagger_spec['definitions']['QuestionnaireResponse']['example'] rp = ResearchProtocol(name='proto') with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) rp_id = rp.id qn = self.add_questionnaire(name='epic26') org = Organization(name="testorg") org.research_protocols.append(rp) with SessionScope(db): db.session.add(qn) db.session.add(org) db.session.commit() qn, org = map(db.session.merge, (qn, org)) qb = QuestionnaireBank(name='Test Questionnaire Bank', classification='baseline', research_protocol_id=rp_id, start='{"days": 0}', overdue='{"days": 7}', expired='{"days": 90}') qbq = QuestionnaireBankQuestionnaire(questionnaire=qn, rank=0) qb.questionnaires.append(qbq) test_user = get_user(TEST_USER_ID) test_user.organizations.append(org) audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID) uc = UserConsent(user_id=TEST_USER_ID, organization=org, audit=audit, agreement_url='http://no.com') with SessionScope(db): db.session.add(qb) db.session.add(test_user) db.session.add(audit) db.session.add(uc) db.session.commit() qb = db.session.merge(qb) self.login() response = self.client.post( '/api/patient/{}/assessment'.format(TEST_USER_ID), content_type='application/json', data=json.dumps(data), ) assert response.status_code == 200 test_user = get_user(TEST_USER_ID) assert test_user.questionnaire_responses.count() == 1 assert test_user.questionnaire_responses[0].questionnaire_bank_id ==\ qb.id
def test_redirect_validation(self): self.promote_user(role_name=ROLE.ADMIN.value) self.promote_user(role_name=ROLE.STAFF.value) org = Organization(name='test org') user = get_user(TEST_USER_ID) with SessionScope(db): db.session.add(org) user.organizations.append(org) db.session.commit() self.login() client = self.add_client() client_url = client._redirect_uris local_url = "http://{}/home?test".format( self.app.config.get('SERVER_NAME')) invalid_url = 'http://invalid.org' # validate redirect of /website-consent-script GET response = self.client.get( '/website-consent-script/{}'.format(TEST_USER_ID), query_string={'redirect_url': local_url}) assert response.status_code == 200 response2 = self.client.get( '/website-consent-script/{}'.format(TEST_USER_ID), query_string={'redirect_url': invalid_url}) assert response2.status_code == 401 # validate session login redirect with valid url oauth_info = { 'user_id': TEST_USER_ID, 'next': client_url, } response3 = self.login(oauth_info=oauth_info) assert response3.status_code == 200 # validate session login redirect with invalid url oauth_info['next'] = invalid_url response4 = self.login(oauth_info=oauth_info) assert response4.status_code == 401 # validate provider login redirect with invalid url oauth_info = dict(OAUTH_INFO_PROVIDER_LOGIN) oauth_info['next'] = invalid_url response5 = self.login(oauth_info=oauth_info) assert response5.status_code == 401 # validate redirect of /challenge POST formdata = {'user_id': TEST_USER_ID, 'next_url': local_url} response6 = self.client.post('/challenge', data=formdata) assert response6.status_code == 200 formdata['next_url'] = invalid_url response7 = self.client.post('/challenge', data=formdata) assert response7.status_code == 401
def test_questionnaire_banks_recurs(self): # set up a few recurring instances initial_recur = Recur(days_to_start=90, days_in_cycle=90, days_till_termination=720) every_six_thereafter = Recur(days_to_start=720, days_in_cycle=180) metastatic_org = Organization(name='metastatic') questionnaire = Questionnaire(name='test_q') with SessionScope(db): db.session.add(initial_recur) db.session.add(every_six_thereafter) db.session.add(metastatic_org) db.session.add(questionnaire) db.session.commit() initial_recur = db.session.merge(initial_recur) every_six_thereafter = db.session.merge(every_six_thereafter) metastatic_org_id = db.session.merge(metastatic_org).id # with bits in place, setup a recurring QB mr_qb = QuestionnaireBank(name='metastatic_recurring', classification='recurring', organization_id=metastatic_org_id) questionnaire = db.session.merge(questionnaire) recurs = [initial_recur, every_six_thereafter] qbq = QuestionnaireBankQuestionnaire(questionnaire=questionnaire, days_till_due=1, days_till_overdue=30, rank=1, recurs=recurs) mr_qb.questionnaires.append(qbq) # confirm persistence of this questionnaire bank includes the bits # added above results = mr_qb.as_json() copy = QuestionnaireBank.from_json(results) self.assertEquals(copy.name, mr_qb.name) copy_q = copy.questionnaires[0] self.assertEquals(copy_q.recurs, [initial_recur, every_six_thereafter]) # now, modify the persisted form, remove one recur and add another new_recur = Recur(days_to_start=900, days_in_cycle=180, days_till_termination=1800) results['questionnaires'][0]['recurs'] = [ initial_recur.as_json(), new_recur.as_json() ] updated_copy = QuestionnaireBank.from_json(results) self.assertEquals( [r.as_json() for r in updated_copy.questionnaires[0].recurs], [r.as_json() for r in (initial_recur, new_recur)])
def test_demographics_delete_ref(self): # existing careProvider should get removed self.login() org = Organization(name='test org') org2 = Organization(name='two') org3 = Organization(name='three') with SessionScope(db): db.session.add(org) db.session.add(org2) db.session.add(org3) db.session.commit() org = db.session.merge(org) org2 = db.session.merge(org2) org3 = db.session.merge(org3) org_id = org.id # associate test orgs 2 and 3 with test user self.test_user = db.session.merge(self.test_user) self.test_user.organizations.append(org3) self.test_user.organizations.append(org2) with SessionScope(db): db.session.add(self.test_user) db.session.commit() # now push only the first org in via the api data = { "careProvider": [{ "reference": "Organization/{}".format(org_id) }], "resourceType": "Patient", } response = self.client.put('/api/demographics/%s' % TEST_USER_ID, content_type='application/json', data=json.dumps(data)) assert response.status_code == 200 user = db.session.merge(self.test_user) # confirm only the one sent via API is intact. assert len(user.organizations) == 1 assert user.organizations[0].name == 'test org'
def test_organization_put_update(self): # confirm unmentioned fields persist self.promote_user(role_name=ROLE.ADMIN.value) self.login() en_AU = LocaleConstants().AustralianEnglish # Populate db with complet org, and set many fields org = Organization( name='test', phone='800-800-5665', timezone='US/Pacific') org.identifiers.append(Identifier( value='state:NY', system=PRACTICE_REGION)) org.locales.append(en_AU) org.default_locale = 'en_AU' with SessionScope(db): db.session.add(org) db.session.commit() org = db.session.merge(org) org_id = org.id data = org.as_fhir() # Now strip down the representation - confirm a post doesn't # wipe unmentioned fields del data['extension'] del data['telecom'] del data['language'] response = self.client.put( '/api/organization/{}'.format(org_id), content_type='application/json', data=json.dumps(data)) assert response.status_code == 200 # Pull the updated db entry org = Organization.query.get(org_id) en_AU = db.session.merge(en_AU) # Confirm all the unmentioned entries survived assert org.phone == '800-800-5665' assert org.default_locale == 'en_AU' assert org.locales[0] == en_AU assert org.timezone == 'US/Pacific'
def test_organization_put_update(self): # confirm unmentioned fields persist self.promote_user(role_name=ROLE.ADMIN.value) self.login() en_AU = LocaleConstants().AustralianEnglish # Populate db with complet org, and set many fields org = Organization(name='test', phone='800-800-5665', timezone='US/Pacific') org.identifiers.append( Identifier(value='state:NY', system=PRACTICE_REGION)) org.locales.append(en_AU) org.default_locale = 'en_AU' with SessionScope(db): db.session.add(org) db.session.commit() org = db.session.merge(org) org_id = org.id data = org.as_fhir() # Now strip down the representation - confirm a post doesn't # wipe unmentioned fields del data['extension'] del data['telecom'] del data['language'] response = self.client.put('/api/organization/{}'.format(org_id), content_type='application/json', data=json.dumps(data)) assert response.status_code == 200 # Pull the updated db entry org = Organization.query.get(org_id) en_AU = db.session.merge(en_AU) # Confirm all the unmentioned entries survived assert org.phone == '800-800-5665' assert org.default_locale == 'en_AU' assert org.locales[0] == en_AU assert org.timezone == 'US/Pacific'
def test_rp_inheritance(self): rp = ResearchProtocol(name="test_rp") with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) parent = Organization(name='parent', id=101) parent.research_protocols.append(rp) child = Organization(name='child', partOf_id=101) with SessionScope(db): db.session.add(parent) db.session.add(child) db.session.commit() parent, child, rp = map(db.session.merge, (parent, child, rp)) self.assertEqual(1, len(parent.research_protocols)) self.assertEqual(parent.research_protocols[0].id, rp.id) self.assertEqual(0, len(child.research_protocols)) self.assertEqual(child.research_protocol(as_of_date=datetime.utcnow()).id, rp.id)
def test_organization_get(self): self.login() org = Organization(name='test') with SessionScope(db): db.session.add(org) db.session.commit() org = db.session.merge(org) # use api to obtain FHIR response = self.client.get('/api/organization/{}'.format(org.id)) assert response.status_code == 200
def test_rp_inheritance(self): rp = ResearchProtocol(name="test_rp") with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) parent = Organization(name='parent', id=101) parent.research_protocols.append(rp) child = Organization(name='child', partOf_id=101) with SessionScope(db): db.session.add(parent) db.session.add(child) db.session.commit() parent, child, rp = map(db.session.merge, (parent, child, rp)) assert len(parent.research_protocols) == 1 assert parent.research_protocols[0].id == rp.id assert len(child.research_protocols) == 0 assert (child.research_protocol(as_of_date=datetime.utcnow()).id == rp.id)
def test_overdue_stats(self): self.promote_user(user=self.test_user, role_name=ROLE.PATIENT.value) rp = ResearchProtocol(name='proto') with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) rp_id = rp.id crv = Organization(name='CRV') crv.research_protocols.append(rp) epic26 = self.add_questionnaire(name='epic26') with SessionScope(db): db.session.add(crv) db.session.commit() crv, epic26 = map(db.session.merge, (crv, epic26)) bank = QuestionnaireBank(name='CRV', research_protocol_id=rp_id, start='{"days": 1}', overdue='{"days": 2}', expired='{"days": 90}') qbq = QuestionnaireBankQuestionnaire(questionnaire_id=epic26.id, rank=0) bank.questionnaires.append(qbq) self.test_user = db.session.merge(self.test_user) # test user with status = 'Expired' (should not show up) a_s = AssessmentStatus(self.test_user, as_of_date=datetime.utcnow()) self.assertEqual(a_s.overall_status, 'Expired') ostats = self.get_ostats() self.assertEqual(len(ostats), 0) # test user with status = 'Overdue' (should show up) self.test_user.organizations.append(crv) self.consent_with_org(org_id=crv.id, backdate=relativedelta(days=18)) with SessionScope(db): db.session.add(bank) db.session.commit() crv, self.test_user = map(db.session.merge, (crv, self.test_user)) a_s = AssessmentStatus(self.test_user, as_of_date=datetime.utcnow()) self.assertEqual(a_s.overall_status, 'Overdue') ostats = self.get_ostats() self.assertEqual(len(ostats), 1) self.assertEqual(ostats[crv], [15])
def test_locale_inheritance(self): # prepopuate database with matching locale cd = Coding.from_fhir({'code': 'en_AU', 'display': 'Australian English', 'system': "urn:ietf:bcp:47"}) # create parent with locale parent_id = 101 parent = Organization(id=parent_id, name='test parent') ol = OrganizationLocale(organization_id=parent_id, coding_id=cd.id) # create child org with no locales org = Organization(id=102, name='test', partOf_id=parent_id) org.use_specific_codings = False with SessionScope(db): db.session.add(parent) db.session.commit() db.session.add(ol) db.session.add(org) db.session.commit() org = db.session.merge(org) self.assertEquals(org.partOf_id, parent_id) # add child org to user user = User.query.get(TEST_USER_ID) user.organizations.append(org) # test locale inheritance self.assertEquals(user.locale_display_options,set(['en_AU']))
def test_org_rp_reference(self): rp = ResearchProtocol(name="test_rp") with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) org_data = {"name": "test_org", "extension": [ {"url": TRUENTH_RP_EXTENSION, "research_protocols": [{'name': "test_rp"}]} ]} org = Organization.from_fhir(org_data) assert len(org.research_protocols) == 1 assert org.research_protocols[0].id == rp.id
def test_from_fhir(self): with (open( os.path.join( os.path.dirname(__file__), 'organization-example-f001-burgers.json'), 'r') ) as fhir_data: data = json.load(fhir_data) # prepopulate database with matching locale Coding.from_fhir( {'code': 'en_AU', 'display': 'Australian English', 'system': IETF_LANGUAGE_TAG}) org = Organization.from_fhir(data) assert org.addresses[0].line1 == data['address'][0]['line'][0] assert org.addresses[1].line1 == data['address'][1]['line'][0] assert org.name == data['name'] assert org.phone == "022-655 2300" assert org.use_specific_codings assert org.race_codings assert not org.ethnicity_codings assert org.locales.count() == 1 assert org.default_locale == "en_AU" assert org._timezone == "US/Pacific"