def test_localized_as_of_date(self): # backdating consent beyond expired and the status lookup date # within a valid window should show available assessments. backdate, nowish = associative_backdate( now=now, backdate=relativedelta(months=3)) self.bless_with_basics(setdate=backdate) self.mark_localized() # backdate so the baseline q's have expired mock_qr(instrument_id='epic26', status='in-progress', doc_id='doc-26', timestamp=backdate) self.test_user = db.session.merge(self.test_user) as_of_date = backdate + relativedelta(days=2) a_s = AssessmentStatus(user=self.test_user, as_of_date=as_of_date) assert a_s.overall_status == "In Progress" # with only epic26 started, should see results for both # instruments_needing_full_assessment and insturments_in_progress assert \ {'eproms_add', 'comorb'} ==\ set(a_s.instruments_needing_full_assessment()) assert ['doc-26'] == a_s.instruments_in_progress()
def test_enrolled_in_metastatic(self): """metastatic should include baseline and indefinite""" self.bless_with_basics() self.mark_metastatic() user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=user) self.assertTrue(a_s.enrolled_in_classification('baseline')) self.assertTrue(a_s.enrolled_in_classification('indefinite'))
def test_enrolled_in_localized(self): """localized should include baseline but not indefinite""" self.bless_with_basics() self.mark_localized() user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=user) self.assertTrue(a_s.enrolled_in_classification('baseline')) self.assertFalse(a_s.enrolled_in_classification('indefinite'))
def test_localized_using_org(self): self.bless_with_basics() self.mark_localized() self.test_user = db.session.merge(self.test_user) # confirm appropriate instruments a_s = AssessmentStatus(user=self.test_user, as_of_date=now) assert set(a_s.instruments_needing_full_assessment()) ==\ localized_instruments
def test_completed_older_rp(self): """If current qb completed on older rp, should show as done""" fourmonthsago = now - timedelta(days=120) weekago = now - timedelta(weeks=1) twoweeksago = now - timedelta(weeks=2) org = self.setup_qbs(rp_name='v2', retired_as_of=weekago) org_id = org.id self.setup_qbs(org=org, rp_name='v3') 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_id=org_id, audit=audit, agreement_url='http://no.com', acceptance_date=fourmonthsago) with SessionScope(db): db.session.add(audit) db.session.add(uc) db.session.commit() # Two weeks ago, still on rp v2, should be in 3mo recurrence user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=user, as_of_date=twoweeksago) v2qb = a_s.qb_data.qbd.questionnaire_bank self.assertEqual('CRV_recurring_3mo_period v2', a_s.qb_data.qbd.questionnaire_bank.name) self.assertEqual('CRV_recurring_3mo_period v2', a_s.qb_name) self.assertEqual(['epic26_v2'], a_s.instruments_needing_full_assessment()) # Now, should still be rp v3, 3mo recurrence a_s = AssessmentStatus(user=user, as_of_date=now) self.assertEqual('CRV_recurring_3mo_period v3', a_s.qb_data.qbd.questionnaire_bank.name) self.assertEqual(['epic26_v3'], a_s.instruments_needing_full_assessment()) # Complete the questionnaire from the 3mo v2 QB mock_qr('epic26_v2', timestamp=twoweeksago, qb=v2qb, iteration=0) # Two weeks ago, should be completed user = db.session.merge(user) a_s = AssessmentStatus(user=user, as_of_date=twoweeksago) self.assertEqual('Completed', a_s.overall_status) # Current should also be completed, even tho protocol changed a_s = AssessmentStatus(user=user, as_of_date=now) self.assertEqual('Completed', a_s.overall_status) # Should see both as candidates qbds = QuestionnaireBank.qbs_for_user(user, classification='recurring', as_of_date=now) self.assertEqual(len(qbds), 2)
def test_metastatic_overdue(self): # if the user completed something on time, and nothing else # is due, should see the thankyou message. # backdate so the baseline q's have expired mock_qr(user_id=TEST_USER_ID, instrument_id='epic26', status='in-progress') self.bless_with_basics(backdate=timedelta(days=31)) self.mark_metastatic() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, "Partially Completed") # with all q's from baseline expired, # instruments_needing_full_assessment and insturments_in_progress # should be empty self.assertFalse(a_s.instruments_needing_full_assessment('baseline')) self.assertFalse(a_s.instruments_in_progress('baseline')) # mock completing the indefinite QB and expect to see 'thank you' mock_qr(user_id=TEST_USER_ID, instrument_id='irondemog') self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertTrue(a_s.enrolled_in_classification('indefinite')) self.assertFalse(a_s.instruments_needing_full_assessment('indefinite')) self.assertFalse(a_s.instruments_in_progress('indefinite'))
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_localized_on_time(self): # User finished both on time self.bless_with_basics() # pick up a consent, etc. self.mark_localized() mock_qr(instrument_id='eproms_add') mock_qr(instrument_id='epic26') mock_qr(instrument_id='comorb') self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=now) assert a_s.overall_status == "Completed" # confirm appropriate instruments assert not a_s.instruments_needing_full_assessment('all')
def test_localized_on_time(self): # User finished both on time self.bless_with_basics() # pick up a consent, etc. self.mark_localized() mock_qr(user_id=TEST_USER_ID, instrument_id='eproms_add') mock_qr(user_id=TEST_USER_ID, instrument_id='epic26') mock_qr(user_id=TEST_USER_ID, instrument_id='comorb') self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, "Completed") # confirm appropriate instruments self.assertFalse(a_s.instruments_needing_full_assessment('all')) self.assertFalse(a_s.instruments_in_progress('baseline'))
def test_secondary_recur_due(self): # backdate so baseline q's have expired, and we within the # second recurrance window self.bless_with_basics(backdate=timedelta(days=180)) self.mark_metastatic() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, "Expired") # in the initial window w/ no questionnaires submitted # should include all from initial recur self.assertEquals( set(a_s.instruments_needing_full_assessment('recurring')), set(['eortc', 'hpfs', 'epic26']))
def test_localized_in_process(self): # User finished one, time remains for other self.bless_with_basics() # pick up a consent, etc. self.mark_localized() mock_qr(instrument_id='eproms_add') self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=now) assert a_s.overall_status == "In Progress" # confirm appropriate instruments assert\ localized_instruments -\ set(a_s.instruments_needing_full_assessment('all')) ==\ {'eproms_add'} assert not a_s.instruments_in_progress()
def test_secondary_recur_due(self): # backdate so baseline q's have expired, and we are within the # second recurrence window backdate, nowish = associative_backdate(now=now, backdate=relativedelta( months=6, hours=1)) self.bless_with_basics(setdate=backdate) self.mark_metastatic() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=nowish) assert a_s.overall_status == "Due" # w/ no questionnaires submitted # should include all from second recur assert set(a_s.instruments_needing_full_assessment()) == metastatic_4
def test_localized_in_process(self): # User finished one, time remains for other self.bless_with_basics() # pick up a consent, etc. self.mark_localized() mock_qr(user_id=TEST_USER_ID, instrument_id='eproms_add') self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, "In Progress") # confirm appropriate instruments self.assertEquals( localized_instruments - set(a_s.instruments_needing_full_assessment('all')), set(['eproms_add'])) self.assertFalse(a_s.instruments_in_progress('baseline'))
def test_localized_using_org(self): self.bless_with_basics() self.mark_localized() self.test_user = db.session.merge(self.test_user) # confirm appropriate instruments a_s = AssessmentStatus(user=self.test_user) self.assertEquals( set(a_s.instruments_needing_full_assessment('baseline')), localized_instruments) # check due date access for questionnaire in a_s.questionnaire_data.baseline(): self.assertTrue(questionnaire.get('by_date') > datetime.utcnow()) self.assertFalse(a_s.instruments_in_progress('baseline')) self.assertFalse(a_s.instruments_in_progress('all'))
def test_boundry_overdue(self): "At days_till_overdue, should still be overdue" self.login() self.bless_with_basics(backdate=timedelta(days=89, hours=23)) self.mark_localized() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, 'Overdue')
def test_boundry_expired(self): "At days_till_overdue +1, should be expired" self.login() self.bless_with_basics(backdate=timedelta(days=91)) self.mark_localized() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, 'Expired')
def test_metastatic_on_time(self): # User finished both on time self.bless_with_basics() # pick up a consent, etc. self.mark_metastatic() for i in metastatic_baseline_instruments: mock_qr(instrument_id=i) mi_qb = QuestionnaireBank.query.filter_by( name='metastatic_indefinite').first() mock_qr(instrument_id='irondemog', qb=mi_qb) self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=now) assert a_s.overall_status == "Completed" # shouldn't need full or any inprocess assert not a_s.instruments_needing_full_assessment('all') assert not a_s.instruments_in_progress('all')
def test_metastatic_on_time(self): # User finished both on time self.bless_with_basics() # pick up a consent, etc. mock_qr(user_id=TEST_USER_ID, instrument_id='eortc') mock_qr(user_id=TEST_USER_ID, instrument_id='ironmisc') mock_qr(user_id=TEST_USER_ID, instrument_id='factfpsi') mock_qr(user_id=TEST_USER_ID, instrument_id='epic26') mock_qr(user_id=TEST_USER_ID, instrument_id='prems') mock_qr(user_id=TEST_USER_ID, instrument_id='irondemog') self.mark_metastatic() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, "Completed") # shouldn't need full or any inprocess self.assertFalse(a_s.instruments_needing_full_assessment('all')) self.assertFalse(a_s.instruments_in_progress('all'))
def test_none_org(self): # check users w/ none of the above org self.test_user.organizations.append(Organization.query.get(0)) self.login() self.bless_with_basics() self.mark_metastatic() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, "Due")
def test_boundary_overdue(self): self.login() backdate, nowish = associative_backdate(now=now, backdate=relativedelta( months=3, hours=-1)) self.bless_with_basics(setdate=backdate) self.mark_localized() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=nowish) assert a_s.overall_status == 'Overdue'
def test_2nd_recur_due(self): # backdate so baseline q's have expired, and we within the 2nd # recurrence window backdate, nowish = associative_backdate(now=now, backdate=relativedelta( months=9, hours=1)) self.bless_with_basics(setdate=backdate) self.mark_metastatic() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=nowish) assert a_s.overall_status == "Due" # in the initial window w/ no questionnaires submitted # should include all from initial recur assert set(a_s.instruments_needing_full_assessment()) == metastatic_3 # however, we should be looking at iteration 2 (zero index)! assert a_s.qb_data.qbd.iteration == 1
def test_boundry_in_progress_expired(self): self.login() self.bless_with_basics(backdate=timedelta(days=91)) self.mark_localized() for instrument in localized_instruments: mock_qr(user_id=TEST_USER_ID, instrument_id=instrument, status='in-progress') self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, 'Partially Completed')
def test_localized_overdue(self): # if the user completed something on time, and nothing else # is due, should see the thank you message. backdate, nowish = associative_backdate(now=now, backdate=relativedelta( months=3, hours=1)) self.bless_with_basics(setdate=backdate) self.mark_localized() # backdate so the baseline q's have expired mock_qr(instrument_id='epic26', status='in-progress') self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=nowish) assert a_s.overall_status == "Partially Completed" # with all q's expired, # instruments_needing_full_assessment and instruments_in_progress # should be empty assert not a_s.instruments_needing_full_assessment() assert not a_s.instruments_in_progress()
def test_boundary_in_progress_expired(self): self.login() backdate, nowish = associative_backdate(now=now, backdate=relativedelta( months=3, hours=1)) self.bless_with_basics(setdate=backdate) self.mark_localized() for instrument in localized_instruments: mock_qr(instrument_id=instrument, status='in-progress') self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=nowish) assert a_s.overall_status == 'Partially Completed'
def test_initial_recur_baseline_done(self): # backdate to be within the first recurrence window backdate, nowish = associative_backdate(now=now, backdate=relativedelta( months=3, days=2)) self.bless_with_basics(setdate=backdate) self.mark_metastatic() # add baseline QNRs, as if submitted nearly 3 months ago, during # baseline window backdated = nowish - relativedelta(months=2, days=25) baseline = QuestionnaireBank.query.filter_by(name='metastatic').one() for instrument in metastatic_baseline_instruments: mock_qr(instrument, qb=baseline, timestamp=backdated) self.test_user = db.session.merge(self.test_user) # Check status during baseline window a_s_baseline = AssessmentStatus(user=self.test_user, as_of_date=backdated) assert a_s_baseline.overall_status == "Completed" assert not a_s_baseline.instruments_needing_full_assessment() # Whereas "current" status for the initial recurrence show due. a_s = AssessmentStatus(user=self.test_user, as_of_date=nowish) assert a_s.overall_status == "Due" # in the initial window w/ no questionnaires submitted # should include all from initial recur assert set(a_s.instruments_needing_full_assessment()) == metastatic_3
def test_boundary_recurring_in_progress(self): self.login() backdate, nowish = associative_backdate(now=now, backdate=relativedelta( months=6, hours=-1)) self.bless_with_basics(setdate=backdate) self.mark_metastatic() for instrument in metastatic_3: mock_qr(instrument_id=instrument, status='in-progress', iteration=0) self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=nowish) assert a_s.overall_status == 'In Progress'
def test_metastatic_due(self): # hasn't taken, but still in "Due" period self.bless_with_basics() # pick up a consent, etc. self.mark_metastatic() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user) self.assertEquals(a_s.overall_status, "Due") # confirm list of expected intruments needing attention a_s.instruments_needing_full_assessment('baseline') self.assertEquals( metastatic_baseline_instruments, set(a_s.instruments_needing_full_assessment('baseline'))) self.assertFalse(a_s.instruments_in_progress('baseline')) # metastatic indefinite should also be 'due' self.assertEquals( metastatic_indefinite_instruments, set(a_s.instruments_needing_full_assessment('indefinite'))) self.assertFalse(a_s.instruments_in_progress('indefinite'))
def test_all_expired_old_tx(self): self.login() # backdate outside of baseline window (which uses consent date) backdate, nowish = associative_backdate(now=now, backdate=relativedelta( months=4, hours=1)) self.bless_with_basics(setdate=backdate) self.mark_localized() # provide treatment date outside of all recurrences tx_date = datetime(2000, 3, 12, 0, 0, 00, 000000) self.add_procedure(code='7', display='Focal therapy', system=ICHOM, setdate=tx_date) self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=nowish) assert a_s.overall_status == 'Expired'
def test_metastatic_due(self): # hasn't taken, but still in "Due" period self.bless_with_basics() # pick up a consent, etc. self.mark_metastatic() self.test_user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=self.test_user, as_of_date=now) assert a_s.overall_status == "Due" # confirm list of expected intruments needing attention assert \ metastatic_baseline_instruments ==\ set(a_s.instruments_needing_full_assessment()) assert not a_s.instruments_in_progress() # metastatic indefinite should also be 'due' assert metastatic_indefinite_instruments ==\ set(a_s.instruments_needing_full_assessment('indefinite')) assert not a_s.instruments_in_progress('indefinite')
def test_outdated_done_indef(self): """Confirm completed indefinite counts after RP switch""" # boiler plate to create baseline and indef with retired RP yesterday = now - timedelta(days=1) weekago = now - timedelta(weeks=1) org, rp2, rp2_id = self.setup_org_n_rp(org_name='testorg', rp_name='v2', retired_as_of=yesterday) org, rp3, rp3_id = self.setup_org_n_rp(org=org, rp_name='v3') org_id = org.id 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_id=org_id, audit=audit, agreement_url='http://no.com', acceptance_date=weekago) with SessionScope(db): db.session.add(audit) db.session.add(uc) db.session.commit() self.setup_qb(questionnaire_name='epic23', qb_name='baseline v2', classification='baseline', rp_id=rp2_id) self.setup_qb(questionnaire_name='epic26', qb_name='baseline v3', classification='baseline', rp_id=rp3_id) qb2_indef = self.setup_qb(questionnaire_name='irondemog', qb_name='indef v2', classification='indefinite', rp_id=rp2_id) self.setup_qb(questionnaire_name='irondemog_v3', qb_name='indef v3', classification='indefinite', rp_id=rp3_id) # for today, should get the v3 baseline user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=user, as_of_date=now) self.assertEqual( ['epic26', 'irondemog_v3'], a_s.instruments_needing_full_assessment(classification='all')) # create done QNR for indefinite dated prior to rp transition # belonging to older qb - confirm that clears indef work as of then mock_qr('irondemog', timestamp=weekago, qb=qb2_indef) user = db.session.merge(self.test_user) a_s = AssessmentStatus(user=user, as_of_date=weekago) self.assertEqual([], a_s.instruments_needing_full_assessment( classification='indefinite')) # move forward in time; user should no longer need indefinite, even # tho RP changed qb2_indef = db.session.merge(qb2_indef) self.assertEqual( [qb2_indef], QuestionnaireBank.qbs_for_user(user, classification='indefinite', as_of_date=now)) a_s = AssessmentStatus(user=user, as_of_date=now) self.assertEqual([], a_s.instruments_needing_full_assessment( classification='indefinite')) self.assertEqual( ['epic26'], a_s.instruments_needing_full_assessment(classification='all'))