def test_rp_as_json(self): rp = ResearchProtocol(name="test_rp") with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) rp_json = rp.as_json() assert rp_json['name'] == 'test_rp' assert rp_json['created_at'] assert rp_json['display_name'] == 'Test Rp'
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_rp_from_json(self): # test from_fhir for new RP data = {"name": "test_rp"} rp = ResearchProtocol.from_json(data) with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) self.assertTrue(rp.id) self.assertTrue(rp.created_at)
def test_rp_from_json(self): # test from_fhir for new RP data = {"name": "test_rp"} rp = ResearchProtocol.from_json(data) with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) assert rp.id assert rp.created_at
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_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_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) self.assertEqual(1, len(org.research_protocols)) self.assertEqual(org.research_protocols[0].id, rp.id)
def migrate_to_rp(org_id, rp_name): bind = op.get_bind() session = Session(bind=bind) org = session.query(Organization).get(org_id) if org: rp = ResearchProtocol(name=rp_name) session.add(rp) session.commit() rp = session.merge(rp) rp_id = rp.id session.execute('UPDATE organizations ' 'SET research_protocol_id = {} ' 'WHERE id = {}'.format(rp_id, org_id)) session.execute('UPDATE questionnaire_banks ' 'SET research_protocol_id = {} ' 'WHERE organization_id = {}'.format(rp_id, org_id))
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 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 = 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_questionnaire_banks_recurs(self): # only one recurrence per qb allowed at this time initial_recur = Recur(start='{"days": 90}', cycle_length='{"days": 90}', termination='{"days": 720}') every_six_thereafter = Recur(start='{"days": 720}', cycle_length='{"days": 180}') rp = ResearchProtocol(name='proto') with SessionScope(db): db.session.add(rp) db.session.commit() rp = db.session.merge(rp) rp_id = rp.id metastatic_org = Organization(name='metastatic') metastatic_org.research_protocols.append(rp) questionnaire = self.add_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) # with bits in place, setup a recurring QB recurs = [initial_recur, every_six_thereafter] mr_qb = QuestionnaireBank(name='metastatic_recurring', classification='recurring', research_protocol_id=rp_id, start='{"days": 0}', overdue='{"days": 1}', expired='{"days": 30}', recurs=recurs) questionnaire = db.session.merge(questionnaire) qbq = QuestionnaireBankQuestionnaire(questionnaire=questionnaire, rank=1) mr_qb.questionnaires.append(qbq) with SessionScope(db): db.session.add(mr_qb) db.session.commit() mr_qb, initial_recur, every_six_thereafter = map( db.session.merge, (mr_qb, initial_recur, every_six_thereafter)) # confirm persistence of this questionnaire bank includes the bits # added above results = mr_qb.as_json() copy = QuestionnaireBank.from_json(results) assert copy.name == mr_qb.name assert copy.recurs == [initial_recur, every_six_thereafter] # now, modify the persisted form, remove one recur and add another new_recur = Recur(start='{"days": 900}', cycle_length='{"days": 180}', termination='{"days": 1800}') results['recurs'] = [initial_recur.as_json(), new_recur.as_json()] updated_copy = QuestionnaireBank.from_json(results) assert ([r.as_json() for r in updated_copy.recurs ] == [r.as_json() for r in (initial_recur, new_recur)])
def test_outdated_inprogress_qb(self): # create base QB/RP org, rp, rp_id = self.setup_org_n_rp(org_name='testorg') qn = self.add_questionnaire(name='epic26') qn, org, self.test_user = map(db.session.merge, (qn, org, self.test_user)) org_id = org.id 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) self.test_user.organizations.append(org) self.promote_user(role_name=ROLE.PATIENT.value) 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', acceptance_date=now) with SessionScope(db): db.session.add(qb) db.session.add(self.test_user) db.session.add(audit) db.session.add(uc) db.session.commit() qb = db.session.merge(qb) # create in-progress QNR for User/QB/RP mock_qr(instrument_id='epic26', status='in-progress', timestamp=now, qb=qb) # User associated with CRV org should generate appropriate # questionnaires self.test_user = db.session.merge(self.test_user) qb_stat = QB_Status(self.test_user, now) qb = qb_stat.current_qbd().questionnaire_bank assert qb.research_protocol.name == 'proto' # Pointing the User's org to a new QB/RP # marking the old RP as retired as of yesterday old_rp = OrganizationResearchProtocol.query.filter( OrganizationResearchProtocol.organization_id == org_id, OrganizationResearchProtocol.research_protocol_id == rp_id).one() old_rp.retired_as_of = now - timedelta(days=1) rp2 = ResearchProtocol(name='new_proto') qn2 = self.add_questionnaire(name='epic27') with SessionScope(db): db.session.add(rp2) db.session.commit() rp2 = db.session.merge(rp2) rp2_id = rp2.id qn2, org = map(db.session.merge, (qn2, org)) qb2 = QuestionnaireBank(name='Test Questionnaire Bank 2', classification='baseline', research_protocol_id=rp2_id, start='{"days": 0}', overdue='{"days": 7}', expired='{"days": 90}') qbq2 = QuestionnaireBankQuestionnaire(questionnaire=qn2, rank=0) qb2.questionnaires.append(qbq2) org.research_protocols.append(rp2) with SessionScope(db): db.session.add(qb2) db.session.add(org) db.session.commit() qb2 = db.session.merge(qb2) # outdated QB/RP should be used as long as User has in-progress QNR self.test_user = db.session.merge(self.test_user) qb_stat = QB_Status(self.test_user, now) qb = qb_stat.current_qbd().questionnaire_bank assert qb.name == 'Test Questionnaire Bank' assert qb.research_protocol.name == 'proto' # completing QNR should result in completed status # shouldn't pick up new protocol till next iteration mock_qr(instrument_id='epic26', status='completed', timestamp=now, qb=qb) self.test_user = db.session.merge(self.test_user) invalidate_users_QBT(TEST_USER_ID) qb_stat = QB_Status(self.test_user, now) qb = qb_stat.current_qbd().questionnaire_bank assert qb.name == 'Test Questionnaire Bank' assert qb_stat.overall_status == OverallStatus.completed
def mock_eproms_questionnairebanks(): # Define base ResearchProtocols localized_protocol = ResearchProtocol(name='localized_protocol') metastatic_protocol = ResearchProtocol(name='metastatic_protocol') with SessionScope(db): db.session.add(localized_protocol) db.session.add(metastatic_protocol) db.session.commit() localized_protocol = db.session.merge(localized_protocol) metastatic_protocol = db.session.merge(metastatic_protocol) locpro_id = localized_protocol.id metapro_id = metastatic_protocol.id # Define test Orgs and QuestionnaireBanks for each group localized_org = Organization(name='localized') localized_org.research_protocols.append(localized_protocol) metastatic_org = Organization(name='metastatic') metastatic_org.research_protocols.append(metastatic_protocol) # from https://docs.google.com/spreadsheets/d/\ # 1oJ8HKfMHOdXkSshjRlr8lFXxT4aUHX5ntxnKMgf50wE/edit#gid=1339608238 three_q_recur = Recur(start='{"months": 3}', cycle_length='{"months": 6}', termination='{"months": 24}') four_q_recur1 = Recur(start='{"months": 6}', cycle_length='{"years": 1}', termination='{"months": 21}') four_q_recur2 = Recur(start='{"months": 30}', cycle_length='{"years": 1}', termination='{"months": 33}') six_q_recur = Recur(start='{"years": 1}', cycle_length='{"years": 1}', termination='{"years": 3, "months": 3}') for name in (localized_instruments.union( *(metastatic_baseline_instruments, metastatic_indefinite_instruments, metastatic_3, metastatic_4, metastatic_6))): TestCase.add_questionnaire(name=name) with SessionScope(db): db.session.add(localized_org) db.session.add(metastatic_org) db.session.add(three_q_recur) db.session.add(four_q_recur1) db.session.add(four_q_recur2) db.session.add(six_q_recur) db.session.commit() localized_org, metastatic_org = map(db.session.merge, (localized_org, metastatic_org)) three_q_recur = db.session.merge(three_q_recur) four_q_recur1 = db.session.merge(four_q_recur1) four_q_recur2 = db.session.merge(four_q_recur2) six_q_recur = db.session.merge(six_q_recur) # Localized baseline l_qb = QuestionnaireBank(name='localized', classification='baseline', research_protocol_id=locpro_id, start='{"days": 0}', overdue='{"days": 7}', expired='{"months": 3}') for rank, instrument in enumerate(localized_instruments): q = Questionnaire.find_by_name(name=instrument) qbq = QuestionnaireBankQuestionnaire(questionnaire=q, rank=rank) l_qb.questionnaires.append(qbq) # Metastatic baseline mb_qb = QuestionnaireBank(name='metastatic', classification='baseline', research_protocol_id=metapro_id, start='{"days": 0}', overdue='{"days": 30}', expired='{"months": 3}') for rank, instrument in enumerate(metastatic_baseline_instruments): q = Questionnaire.find_by_name(name=instrument) qbq = QuestionnaireBankQuestionnaire(questionnaire=q, rank=rank) mb_qb.questionnaires.append(qbq) # Metastatic indefinite mi_qb = QuestionnaireBank(name='metastatic_indefinite', classification='indefinite', research_protocol_id=metapro_id, start='{"days": 0}', expired='{"years": 50}') for rank, instrument in enumerate(metastatic_indefinite_instruments): q = Questionnaire.find_by_name(name=instrument) qbq = QuestionnaireBankQuestionnaire(questionnaire=q, rank=rank) mi_qb.questionnaires.append(qbq) # Metastatic recurring 3 mr3_qb = QuestionnaireBank(name='metastatic_recurring3', classification='recurring', research_protocol_id=metapro_id, start='{"days": 0}', overdue='{"days": 30}', expired='{"months": 3}', recurs=[three_q_recur]) for rank, instrument in enumerate(metastatic_3): q = Questionnaire.find_by_name(name=instrument) qbq = QuestionnaireBankQuestionnaire(questionnaire=q, rank=rank) mr3_qb.questionnaires.append(qbq) # Metastatic recurring 4 mr4_qb = QuestionnaireBank(name='metastatic_recurring4', classification='recurring', research_protocol_id=metapro_id, recurs=[four_q_recur1, four_q_recur2], start='{"days": 0}', overdue='{"days": 30}', expired='{"months": 3}') for rank, instrument in enumerate(metastatic_4): q = Questionnaire.find_by_name(name=instrument) qbq = QuestionnaireBankQuestionnaire(questionnaire=q, rank=rank) mr4_qb.questionnaires.append(qbq) # Metastatic recurring 6 mr6_qb = QuestionnaireBank(name='metastatic_recurring6', classification='recurring', research_protocol_id=metapro_id, recurs=[six_q_recur], start='{"days": 0}', overdue='{"days": 30}', expired='{"months": 3}') for rank, instrument in enumerate(metastatic_6): q = Questionnaire.find_by_name(name=instrument) qbq = QuestionnaireBankQuestionnaire(questionnaire=q, rank=rank) mr6_qb.questionnaires.append(qbq) with SessionScope(db): db.session.add(l_qb) db.session.add(mb_qb) db.session.add(mi_qb) db.session.add(mr3_qb) db.session.add(mr4_qb) db.session.add(mr6_qb) db.session.commit()