Exemplo n.º 1
0
    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')
Exemplo n.º 2
0
    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))
Exemplo n.º 3
0
    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']))
Exemplo n.º 4
0
    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)])
Exemplo n.º 5
0
    def setup_intervention_qbs(self, intervention=None):
        if not intervention:
            intervention = Intervention(name='symptom tracker',
                                        description='test')
            with SessionScope(db):
                db.session.add(intervention)
                db.session.commit()

        eq5d = self.add_questionnaire(name='eq5d')
        epic26 = self.add_questionnaire(name='epic26')
        recur6 = Recur(start='{"months": 3, "weeks": -2}',
                       cycle_length='{"months": 6}',
                       termination='{"months": 27}')
        exists = Recur.query.filter_by(start=recur6.start,
                                       cycle_length=recur6.cycle_length,
                                       termination=recur6.termination).first()
        if exists:
            recur6 = exists

        with SessionScope(db):
            db.session.add(eq5d)
            db.session.add(epic26)
            db.session.add(recur6)
            db.session.commit()
        intervention, eq5d, epic26, recur6 = map(
            db.session.merge, (intervention, eq5d, epic26, recur6))

        qb_base = QuestionnaireBank(name='Symptom Tracker Baseline',
                                    classification='baseline',
                                    intervention_id=intervention.id,
                                    start='{"days": 0}',
                                    expired='{"months": 3, "days": -14}')
        qbq = QuestionnaireBankQuestionnaire(questionnaire=epic26, rank=0)
        qbq2 = QuestionnaireBankQuestionnaire(questionnaire=eq5d, rank=1)
        qb_base.questionnaires.append(qbq)
        qb_base.questionnaires.append(qbq2)

        qb_r6 = QuestionnaireBank(name='Symptom Tracker Recurring',
                                  classification='recurring',
                                  intervention_id=intervention.id,
                                  start='{"days": 0}',
                                  expired='{"months": 3}',
                                  recurs=[recur6])
        qbq = QuestionnaireBankQuestionnaire(questionnaire=epic26, rank=0)
        qbq2 = QuestionnaireBankQuestionnaire(questionnaire=eq5d, rank=1)
        qb_r6.questionnaires.append(qbq)
        qb_r6.questionnaires.append(qbq2)

        with SessionScope(db):
            db.session.add(qb_base)
            db.session.add(qb_r6)
            db.session.commit()

        return db.session.merge(intervention)
Exemplo n.º 6
0
    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)
Exemplo n.º 7
0
    def test_lookup_with_intervention(self):
        intv = Intervention(name='TEST', description='Test Intervention')
        epic26 = Questionnaire(name='epic26')
        eproms_add = Questionnaire(name='eproms_add')
        with SessionScope(db):
            db.session.add(intv)
            db.session.add(epic26)
            db.session.add(eproms_add)
            db.session.commit()
        intv, epic26, eproms_add = map(db.session.merge,
                                       (intv, epic26, eproms_add))

        bank = QuestionnaireBank(name='CRV', intervention_id=intv.id)
        for rank, q in enumerate((epic26, eproms_add)):
            qbq = QuestionnaireBankQuestionnaire(questionnaire_id=q.id,
                                                 days_till_due=7,
                                                 days_till_overdue=90,
                                                 rank=rank)
            bank.questionnaires.append(qbq)

        self.test_user.interventions.append(intv)
        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)
        qd = QuestionnaireDetails(self.test_user, datetime.utcnow())
        results = list(qd.baseline())
        self.assertEquals(2, len(results))
        # confirm rank sticks
        self.assertEquals(results[0]['name'], 'epic26')
        self.assertEquals(results[1]['name'], 'eproms_add')
Exemplo n.º 8
0
    def test_org_trigger_date(self):
        # testing org-based QBs
        org, rp, rp_id = self.setup_org_n_rp()
        q = self.add_questionnaire(name='q')
        q, org, self.test_user = map(db.session.merge,
                                     (q, org, self.test_user))
        qb = QuestionnaireBank(name='qb',
                               research_protocol_id=rp_id,
                               classification='baseline',
                               start='{"days": 1}',
                               expired='{"days": 2}')
        qbq = QuestionnaireBankQuestionnaire(rank=0, questionnaire=q)
        qb.questionnaires.append(qbq)

        # user without consents or TX date should return None
        assert not trigger_date(self.test_user)

        # user with consent should return consent date
        self.consent_with_org(org.id, setdate=now)
        self.test_user = db.session.merge(self.test_user)
        assert trigger_date(self.test_user) == now
        assert trigger_date(self.test_user, qb) == now

        # user with consent and TX date should return TX date (if qb.recurs)
        tx_date = datetime(2017, 6, 10, 20, 00, 00, 000000)
        self.add_procedure(code='7',
                           display='Focal therapy',
                           system=ICHOM,
                           setdate=tx_date)
        self.test_user = db.session.merge(self.test_user)
        recur = Recur(start='{"months": 3}',
                      cycle_length='{"months": 6}',
                      termination='{"months": 24}')
        qb.recurs.append(recur)
        assert trigger_date(self.test_user, qb) == tx_date
Exemplo n.º 9
0
    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()

        # Patient associated with INTV intervention should generate appropriate
        # questionnaires as of start date
        self.promote_user(role_name=ROLE.PATIENT.value)
        self.test_user = db.session.merge(self.test_user)
        qb_status = QB_Status(self.test_user,
                              as_of_date=now + relativedelta(days=8))
        qb = qb_status.current_qbd().questionnaire_bank
        results = list(qb.questionnaires)
        assert len(results) == 2
Exemplo n.º 10
0
    def setup_qb(self,
                 questionnaire_name,
                 qb_name,
                 classification,
                 rp_id,
                 expired=None):
        """Shortcut to setup a testing QB with given values

        Sets up a single qb with a single questionnaire for given
        classification and research_protocol

        """
        if expired is None:
            expired = '{"days": 90}'
        qn = self.add_questionnaire(questionnaire_name)
        qb = QuestionnaireBank(name=qb_name,
                               classification=classification,
                               research_protocol_id=rp_id,
                               start='{"days": 0}',
                               expired=expired)
        qbq = QuestionnaireBankQuestionnaire(questionnaire=qn, rank=0)
        qb.questionnaires.append(qbq)
        with SessionScope(db):
            db.session.add(qb)
            db.session.commit()
        return db.session.merge(qb)
    def test_import(self):
        org, rp, rp_id = self.setup_org_n_rp()
        rp_name = rp.name
        q1 = self.add_questionnaire(name='q1')
        q2 = self.add_questionnaire(name='q2')
        org, q1, q2 = map(db.session.merge, (org, q1, q2))

        data = {
            'resourceType': 'QuestionnaireBank',
            'research_protocol': {'reference': ('api/research_protocol/'
                                                '{}').format(rp_name)},
            'start': '{"days": 0}',
            'overdue': '{"weeks": 1}',
            'expired': '{"days": 30}',
            'questionnaires': [
                {
                    'rank': 2,
                    'questionnaire': {
                        'reference': 'api/questionnaire/{}?system={}'.format(
                            q1.name, TRUENTH_QUESTIONNAIRE_CODE_SYSTEM)}
                },
                {
                    'rank': 1,
                    'questionnaire': {
                        'reference': 'api/questionnaire/{}?system={}'.format(
                            q2.name, TRUENTH_QUESTIONNAIRE_CODE_SYSTEM)}
                }
            ],
            'id': 1,
            'name': 'bank',
            'classification': 'baseline'
        }
        qb = QuestionnaireBank.from_json(data)
        assert len(qb.questionnaires) == 2
        assert qb.research_protocol_id == rp_id
Exemplo n.º 12
0
    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))
Exemplo n.º 13
0
    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)]
Exemplo n.º 14
0
    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_start(self):
        org, rp, rp_id = self.setup_org_n_rp()
        q = self.add_questionnaire('q')
        q, org = map(db.session.merge, (q, org))
        qb = QuestionnaireBank(
            name='qb', research_protocol_id=rp_id, classification='baseline',
            start='{"days": 1}', expired='{"days": 2}')
        qbq = QuestionnaireBankQuestionnaire(rank=0, questionnaire=q)
        qb.questionnaires.append(qbq)

        trigger_date = datetime.strptime('2000-01-01', '%Y-%m-%d')
        start = qb.calculated_start(trigger_date).relative_start
        assert start > trigger_date
        assert start == datetime.strptime('2000-01-02', '%Y-%m-%d')

        end = qb.calculated_expiry(start)
        expected_expiry = datetime.strptime('2000-01-04', '%Y-%m-%d')
        assert end == expected_expiry
Exemplo n.º 16
0
def mock_tnth_questionnairebanks():
    for name in (symptom_tracker_instruments):
        TestCase.add_questionnaire(name=name)

    # Symptom Tracker Baseline
    self_management = INTERVENTION.SELF_MANAGEMENT
    st_qb = QuestionnaireBank(
        name='symptom_tracker',
        classification='baseline',
        intervention_id=self_management.id,
        start='{"days": 0}',
        expired='{"months": 3}'
    )
    for rank, instrument in enumerate(symptom_tracker_instruments):
        q = Questionnaire.find_by_name(name=instrument)
        qbq = QuestionnaireBankQuestionnaire(questionnaire=q, rank=rank)
        st_qb.questionnaires.append(qbq)

    # Symptom Tracker Recurrence
    st_recur = Recur(
        start='{"months": 3}', cycle_length='{"months": 3}',
        termination='{"months": 27}')

    with SessionScope(db):
        db.session.add(st_qb)
        db.session.add(st_recur)
        db.session.commit()

    self_management = INTERVENTION.SELF_MANAGEMENT
    st_recur_qb = QuestionnaireBank(
        name='symptom_tracker_recurring',
        classification='recurring',
        intervention_id=self_management.id,
        start='{"days": 0}',
        expired='{"months": 3}',
        recurs=[st_recur]
    )
    for rank, instrument in enumerate(symptom_tracker_instruments):
        q = Questionnaire.find_by_name(name=instrument)
        qbq = QuestionnaireBankQuestionnaire(questionnaire=q, rank=rank)
        st_recur_qb.questionnaires.append(qbq)
    with SessionScope(db):
        db.session.add(st_recur_qb)
        db.session.commit()
Exemplo n.º 17
0
    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)
Exemplo n.º 18
0
    def test_start(self):
        org, rp, rp_id = self.setup_org_n_rp()
        q = self.add_questionnaire('q')
        q, org = map(db.session.merge, (q, org))
        qb = QuestionnaireBank(name='qb',
                               research_protocol_id=rp_id,
                               classification='baseline',
                               start='{"days": 1}',
                               expired='{"days": 2}')
        qbq = QuestionnaireBankQuestionnaire(rank=0, questionnaire=q)
        qb.questionnaires.append(qbq)

        trigger_date = datetime.strptime('2000-01-01', '%Y-%m-%d')
        start = qb.calculated_start(trigger_date).relative_start
        assert start > trigger_date
        assert start == datetime.strptime('2000-01-02', '%Y-%m-%d')

        end = qb.calculated_expiry(start)
        expected_expiry = datetime.strptime('2000-01-04', '%Y-%m-%d')
        assert end == expected_expiry
Exemplo n.º 19
0
    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 test_serialize(self):
        org, rp, rp_id = self.setup_org_n_rp()
        q1 = self.add_questionnaire(name='q1')
        q2 = self.add_questionnaire(name='q2')
        q1, q2, org = map(db.session.merge, (q1, q2, org))
        qb = QuestionnaireBank(
            name='qb', research_protocol_id=rp_id, classification='baseline',
            start='{"days": 0}', overdue='{"days": 5}', expired='{"days": 30}')
        for rank, q in enumerate((q1, q2)):
            qbq = QuestionnaireBankQuestionnaire(
                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()
        assert 'QuestionnaireBank' == data.get('resourceType')
        assert len(data['questionnaires']) == 2
Exemplo n.º 21
0
    def test_serialize(self):
        org, rp, rp_id = self.setup_org_n_rp()
        q1 = self.add_questionnaire(name='q1')
        q2 = self.add_questionnaire(name='q2')
        q1, q2, org = map(db.session.merge, (q1, q2, org))
        qb = QuestionnaireBank(name='qb',
                               research_protocol_id=rp_id,
                               classification='baseline',
                               start='{"days": 0}',
                               overdue='{"days": 5}',
                               expired='{"days": 30}')
        for rank, q in enumerate((q1, q2)):
            qbq = QuestionnaireBankQuestionnaire(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()
        assert 'QuestionnaireBank' == data.get('resourceType')
        assert len(data['questionnaires']) == 2
Exemplo n.º 22
0
    def test_due(self):
        org, rp, rp_id = self.setup_org_n_rp()
        q = self.add_questionnaire('q')
        q, org = map(db.session.merge, (q, org))
        qb = QuestionnaireBank(name='qb',
                               research_protocol_id=rp_id,
                               classification='baseline',
                               start='{"days": 1}',
                               due='{"days": 2}')
        qbq = QuestionnaireBankQuestionnaire(rank=0, questionnaire=q)
        qb.questionnaires.append(qbq)

        trigger_date = datetime.strptime('2000-01-01', '%Y-%m-%d')
        now = datetime.now()
        start = qb.calculated_start(trigger_date,
                                    as_of_date=now).relative_start
        self.assertTrue(start > trigger_date)
        self.assertEqual(start, datetime.strptime('2000-01-02', '%Y-%m-%d'))

        due = qb.calculated_due(trigger_date, as_of_date=now)
        expected_due = datetime.strptime('2000-01-04', '%Y-%m-%d')
        self.assertEqual(due, expected_due)
    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_no_start_date(self):
     # W/O a biopsy (i.e. event start date), no questionnaries
     self.promote_user(role_name=ROLE.PATIENT.value)
     # toggle default setup - set biopsy false for test user
     self.login()
     self.test_user = db.session.merge(self.test_user)
     self.test_user.save_observation(codeable_concept=CC.BIOPSY,
                                     value_quantity=CC.FALSE_VALUE,
                                     audit=Audit(user_id=TEST_USER_ID,
                                                 subject_id=TEST_USER_ID),
                                     status='final',
                                     issued=None)
     assert not QuestionnaireBank.qbs_for_user(
         self.test_user, 'baseline', as_of_date=now)
Exemplo n.º 25
0
    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 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)
Exemplo n.º 27
0
    def test_import(self):
        org, rp, rp_id = self.setup_org_n_rp()
        rp_name = rp.name
        q1 = self.add_questionnaire(name='q1')
        q2 = self.add_questionnaire(name='q2')
        org, q1, q2 = map(db.session.merge, (org, q1, q2))

        data = {
            'resourceType':
            'QuestionnaireBank',
            'research_protocol': {
                'reference': ('api/research_protocol/'
                              '{}').format(rp_name)
            },
            'start':
            '{"days": 0}',
            'overdue':
            '{"weeks": 1}',
            'expired':
            '{"days": 30}',
            'questionnaires': [{
                'rank': 2,
                'questionnaire': {
                    'reference':
                    'api/questionnaire/{}?system={}'.format(
                        q1.name, TRUENTH_QUESTIONNAIRE_CODE_SYSTEM)
                }
            }, {
                'rank': 1,
                'questionnaire': {
                    'reference':
                    'api/questionnaire/{}?system={}'.format(
                        q2.name, TRUENTH_QUESTIONNAIRE_CODE_SYSTEM)
                }
            }],
            'id':
            1,
            'name':
            'bank',
            'classification':
            'baseline'
        }
        qb = QuestionnaireBank.from_json(data)
        assert len(qb.questionnaires) == 2
        assert qb.research_protocol_id == rp_id
    def test_early(self):
        # Prior to days passing, no message should be generated
        mock_communication_request('symptom_tracker', '{"days": 90}')

        self.promote_user(role_name=ROLE.PATIENT.value)
        self.login()
        self.add_required_clinical_data(backdate=relativedelta(days=89))
        self.test_user = db.session.merge(self.test_user)

        # Confirm test user qualifies for ST QB
        assert QuestionnaireBank.qbs_for_user(self.test_user,
                                              'baseline',
                                              as_of_date=datetime.utcnow())

        # Being a day short, shouldn't fire
        update_patient_loop(update_cache=False, queue_messages=True)
        expected = Communication.query.first()
        assert not expected
Exemplo n.º 29
0
    def test_import_followup(self):
        intervention = Intervention(name='testy', description='simple')
        q1 = self.add_questionnaire(name='q1')
        q2 = self.add_questionnaire(name='q2')
        with SessionScope(db):
            db.session.add(intervention)
            db.session.commit()
        intervention, q1, q2 = map(db.session.merge, (intervention, q1, q2))

        data = {
            'resourceType':
            'QuestionnaireBank',
            'intervention': {
                'reference': 'api/intervention/{}'.format(intervention.name)
            },
            'expired':
            '{"days": 104}',
            'start':
            '{"days": 76}',
            'questionnaires': [{
                'rank': 2,
                'questionnaire': {
                    'reference':
                    'api/questionnaire/{}?system={}'.format(
                        q1.name, TRUENTH_QUESTIONNAIRE_CODE_SYSTEM)
                }
            }, {
                'rank': 1,
                'questionnaire': {
                    'reference':
                    'api/questionnaire/{}?system={}'.format(
                        q2.name, TRUENTH_QUESTIONNAIRE_CODE_SYSTEM)
                }
            }],
            'id':
            1,
            'name':
            u'bank',
            'classification':
            'followup'
        }
        qb = QuestionnaireBank.from_json(data)
        self.assertEqual(2, len(qb.questionnaires))
Exemplo n.º 30
0
    def test_import(self):
        org = Organization(name='org')
        q1 = Questionnaire(name='q1')
        q2 = Questionnaire(name='q2')
        with SessionScope(db):
            db.session.add(org)
            db.session.add(q1)
            db.session.add(q2)
            db.session.commit()
        org, q1, q2 = map(db.session.merge, (org, q1, q2))
        q2_id = q2.id

        data = {
            'resourceType':
            'QuestionnaireBank',
            'organization': {
                'reference': 'api/organization/{}'.format(org.id)
            },
            'questionnaires': [{
                'days_till_overdue': 30,
                'days_till_due': 5,
                'rank': 2,
                'questionnaire': {
                    'reference': 'api/questionnaire/{}'.format(q1.name)
                }
            }, {
                'days_till_overdue': 30,
                'days_till_due': 5,
                'rank': 1,
                'questionnaire': {
                    'reference': 'api/questionnaire/{}'.format(q2.name)
                }
            }],
            'id':
            1,
            'name':
            u'bank',
            'classification':
            'baseline'
        }
        qb = QuestionnaireBank.from_json(data)
        self.assertEquals(2, len(qb.questionnaires))
Exemplo n.º 31
0
    def test_intervention_trigger_date(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": 1}',
                               expired='{"days": 2}')
        qbq = QuestionnaireBankQuestionnaire(rank=0, questionnaire=q)
        qb.questionnaires.append(qbq)

        # user without biopsy or TX date should return None
        assert not trigger_date(self.test_user)

        # 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()
        assert obs.codeable_concept.codings[0].display == 'biopsy'
        assert trigger_date(self.test_user) == obs.issued

        # user with biopsy and TX date should return TX date
        tx_date = datetime.utcnow()
        self.add_procedure(code='7',
                           display='Focal therapy',
                           system=ICHOM,
                           setdate=tx_date)
        self.test_user = db.session.merge(self.test_user)
        assert trigger_date(self.test_user) == tx_date
Exemplo n.º 32
0
    def test_questionnaire_gets(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))

        resp = self.client.get('/api/questionnaire')
        assert resp.status_code == 200
        assert len(resp.json['entry']) == 3
        assert all(('resource' in entry for entry in resp.json['entry']))

        resp = self.client.get('/api/questionnaire/{}?system={}'.format(
            'epic26', TRUENTH_QUESTIONNAIRE_CODE_SYSTEM))
        assert resp.status_code == 200
        q_ids = [
            ident for ident in resp.json['identifier']
            if ident['system'] == TRUENTH_QUESTIONNAIRE_CODE_SYSTEM
        ]
        assert len(q_ids) == 1
        assert q_ids[0]['value'] == 'epic26'

        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 = db.session.merge(self.test_user)
        self.test_user.organizations.append(crv)
        with SessionScope(db):
            db.session.add(bank)
            db.session.commit()

        resp = self.client.get('/api/questionnaire_bank')
        assert resp.status_code == 200
        assert len(resp.json['entry'][0]['resource']['questionnaires']) == 3
Exemplo n.º 33
0
    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 = db.session.merge(self.test_user)
        self.test_user.organizations.append(crv)
        self.consent_with_org(org_id=crv.id, setdate=now)
        self.promote_user(role_name=ROLE.PATIENT.value)
        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)

        # Doesn't start for 7 days, initially shouldn't get any
        qb_stat = QB_Status(user=self.test_user, as_of_date=now)
        assert qb_stat.current_qbd() is None

        qb_stat = QB_Status(user=self.test_user,
                            as_of_date=now + relativedelta(days=7))
        qb = qb_stat.current_qbd().questionnaire_bank
        results = list(qb.questionnaires)
        assert len(results) == 3
        # confirm rank sticks
        assert results[0].name == 'epic26'
        assert results[2].name == 'comorb'
Exemplo n.º 34
0
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_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)])