def test_qb_pre_retired(self): # Confirm backdating returns the correct QB weekago = now - timedelta(days=7) org, rpv3, rpv3_id = self.setup_org_n_rp(rp_name='v3') org, rpv2, rpv2_id = self.setup_org_n_rp(org=org, rp_name='v2', retired_as_of=weekago) qn3 = self.add_questionnaire(name='epic26-v3') qn2 = self.add_questionnaire(name='epic26-v2') qb3 = QuestionnaireBank(name='Test Questionnaire Bank v3', classification='baseline', research_protocol_id=rpv3_id, start='{"days": 0}', overdue='{"days": 7}', expired='{"days": 90}') qbq3 = QuestionnaireBankQuestionnaire(questionnaire=qn3, rank=0) qb3.questionnaires.append(qbq3) qb2 = QuestionnaireBank(name='Test Questionnaire Bank v2', classification='baseline', research_protocol_id=rpv2_id, start='{"days": 0}', overdue='{"days": 7}', expired='{"days": 90}') qbq2 = QuestionnaireBankQuestionnaire(questionnaire=qn2, rank=0) qb2.questionnaires.append(qbq2) self.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): map(db.session.add, (qb2, qb3)) db.session.add(audit) db.session.add(uc) db.session.commit() user, org, qb2, qb3 = map(db.session.merge, (self.test_user, org, qb2, qb3)) # w/o backdating, should get current QB self.assertEqual( qb3, QuestionnaireBank.most_current_qb( user, as_of_date=now).questionnaire_bank) # backdate prior to retirement of previous, should get the previous QB pre_retirement = weekago - timedelta(days=1) self.assertEqual( qb2, QuestionnaireBank.most_current_qb( user, as_of_date=pre_retirement).questionnaire_bank)
def test_lookup_with_intervention(self): intv = Intervention(name='TEST', description='Test Intervention') epic26 = self.add_questionnaire(name='epic26') eproms_add = self.add_questionnaire(name='eproms_add') with SessionScope(db): db.session.add(intv) db.session.commit() intv, epic26, eproms_add = map(db.session.merge, (intv, epic26, eproms_add)) bank = QuestionnaireBank(name='CRV', intervention_id=intv.id, start='{"days": 7}', expired='{"days": 90}') for rank, q in enumerate((epic26, eproms_add)): qbq = QuestionnaireBankQuestionnaire(questionnaire_id=q.id, rank=rank) bank.questionnaires.append(qbq) self.test_user.interventions.append(intv) self.login() self.add_required_clinical_data() with SessionScope(db): db.session.add(bank) db.session.commit() # User associated with INTV intervention should generate appropriate # questionnaires self.test_user = db.session.merge(self.test_user) qb = QuestionnaireBank.most_current_qb( self.test_user, as_of_date=now).questionnaire_bank results = list(qb.questionnaires) self.assertEqual(2, len(results))
def test_lookup_for_user(self): crv, rp, rp_id = self.setup_org_n_rp(org_name='CRV') epic26 = self.add_questionnaire(name='epic26') eproms_add = self.add_questionnaire(name='eproms_add') comorb = self.add_questionnaire(name='comorb') crv, epic26, eproms_add, comorb = map( db.session.merge, (crv, epic26, eproms_add, comorb)) bank = QuestionnaireBank(name='CRV', research_protocol_id=rp_id, start='{"days": 7}', expired='{"days": 90}') for rank, q in enumerate((epic26, eproms_add, comorb)): qbq = QuestionnaireBankQuestionnaire(questionnaire_id=q.id, rank=rank) bank.questionnaires.append(qbq) self.test_user.organizations.append(crv) self.consent_with_org(org_id=crv.id) with SessionScope(db): db.session.add(bank) db.session.commit() # User associated with CRV org should generate appropriate # questionnaires self.test_user = db.session.merge(self.test_user) qb = QuestionnaireBank.most_current_qb( self.test_user, as_of_date=now).questionnaire_bank results = list(qb.questionnaires) self.assertEqual(3, len(results)) # confirm rank sticks self.assertEqual(results[0].name, 'epic26') self.assertEqual(results[2].name, 'comorb')
def test_visit_baseline(self): crv = self.setup_qbs() self.bless_with_basics() # pick up a consent, etc. self.test_user.organizations.append(crv) self.test_user = db.session.merge(self.test_user) qbd = QuestionnaireBank.most_current_qb(self.test_user, as_of_date=now) self.assertEqual("Baseline", visit_name(qbd))
def test_visit_9mo(self): crv = self.setup_qbs() backdate, nowish = associative_backdate( now=now, backdate=relativedelta(months=9)) self.bless_with_basics(setdate=backdate) self.test_user.organizations.append(crv) self.test_user = db.session.merge(self.test_user) qbd = QuestionnaireBank.most_current_qb(self.test_user, as_of_date=nowish + timedelta(hours=1)) self.assertEqual("Month 9", visit_name(qbd))
def mock_qr(instrument_id, status='completed', timestamp=None, qb=None, doc_id=None, iteration=None): if not doc_id: doc_id = ''.join(choice(ascii_letters) for _ in range(10)) timestamp = timestamp or datetime.utcnow() qr_document = { "questionnaire": { "display": "Additional questions", "reference": "https://{}/api/questionnaires/{}".format('SERVER_NAME', instrument_id) }, "identifier": { "use": "official", "label": "cPRO survey session ID", "value": doc_id, "system": "https://stg-ae.us.truenth.org/eproms-demo" } } enc = Encounter(status='planned', auth_method='url_authenticated', user_id=TEST_USER_ID, start_time=timestamp) with SessionScope(db): db.session.add(enc) db.session.commit() enc = db.session.merge(enc) qb = qb or QuestionnaireBank.most_current_qb(get_user(TEST_USER_ID), timestamp).questionnaire_bank qr = QuestionnaireResponse(subject_id=TEST_USER_ID, status=status, authored=timestamp, document=qr_document, encounter_id=enc.id, questionnaire_bank=qb, qb_iteration=iteration) with SessionScope(db): db.session.add(qr) db.session.commit() invalidate_assessment_status_cache(TEST_USER_ID)
def upgrade(): bind = op.get_bind() session = Session(bind=bind) for qnr in QuestionnaireResponse.query.all(): if ("questionnaire" in qnr.document) and qnr.subject: qn_ref = qnr.document.get("questionnaire").get("reference") qn_name = qn_ref.split("/")[-1] if qn_ref else None qn = Questionnaire.query.filter_by(name=qn_name).first() qbd = QuestionnaireBank.most_current_qb( qnr.subject, as_of_date=qnr.authored) qb = qbd.questionnaire_bank ic = qbd.iteration if qb and qn and (qn.id in [qbq.questionnaire.id for qbq in qb.questionnaires]): ic = ic or 'NULL' session.execute( 'UPDATE questionnaire_responses SET ' 'questionnaire_bank_id = {}, qb_iteration = {} WHERE ' 'id = {}'.format(qb.id, ic, qnr.id))
def test_intervention_in_progress(self): # testing intervention-based QBs q = self.add_questionnaire('q') interv = Intervention(name='interv', description='test') with SessionScope(db): db.session.add(interv) db.session.commit() q, interv, self.test_user = map(db.session.merge, (q, interv, self.test_user)) qb = QuestionnaireBank(name='qb', intervention_id=interv.id, classification='baseline', start='{"days": 0}', expired='{"days": 2}') qbq = QuestionnaireBankQuestionnaire(rank=0, questionnaire=q) qb.questionnaires.append(qbq) # user with biopsy should return biopsy date self.login() self.test_user.save_observation(codeable_concept=CC.BIOPSY, value_quantity=CC.TRUE_VALUE, audit=Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID), status='', issued=None) self.test_user = db.session.merge(self.test_user) obs = self.test_user.observations.first() self.assertEqual(obs.codeable_concept.codings[0].display, 'biopsy') self.assertEqual(qb.trigger_date(self.test_user), obs.issued) # add mock in-process QB - confirm most_current_qb still returns one mock_qr('q', 'in-progress', qb=qb) self.test_user, qb = map(db.session.merge, (self.test_user, qb)) self.assertEqual( qb.most_current_qb(self.test_user, as_of_date=now).questionnaire_bank, qb)
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) 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(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='epic_26', 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 = QuestionnaireBank.most_current_qb( self.test_user, as_of_date=now).questionnaire_bank self.assertEqual(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 = QuestionnaireBank.most_current_qb( self.test_user, as_of_date=now).questionnaire_bank self.assertEqual(qb.name, 'Test Questionnaire Bank') self.assertEqual(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='epic_26', status='completed', timestamp=now, qb=qb) self.test_user = db.session.merge(self.test_user) qb = QuestionnaireBank.most_current_qb( self.test_user, as_of_date=now).questionnaire_bank self.assertEqual(qb.name, 'Test Questionnaire Bank')