Example #1
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)
Example #2
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)
Example #3
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')
Example #4
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))
Example #5
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')
Example #6
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
Example #7
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
Example #8
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)
Example #9
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']))
Example #10
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)]
Example #11
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
Example #12
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()
Example #13
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)])
    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])
Example #15
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
        self.assertFalse(qb.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()
        self.assertEqual(obs.codeable_concept.codings[0].display, 'biopsy')
        self.assertEqual(qb.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)
        qb.__trigger_date = None  # clear out stored trigger_date
        self.assertEqual(qb.trigger_date(self.test_user), tx_date)
Example #16
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
Example #17
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'
Example #18
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
Example #19
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)
Example #20
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
Example #21
0
    def test_questionnaire_gets(self):
        crv = Organization(name='CRV')
        epic26 = Questionnaire(name='epic26')
        eproms_add = Questionnaire(name='eproms_add')
        comorb = Questionnaire(name='comorb')
        with SessionScope(db):
            db.session.add(crv)
            db.session.add(epic26)
            db.session.add(eproms_add)
            db.session.add(comorb)
            db.session.commit()
        crv, epic26, eproms_add, comorb = map(
            db.session.merge, (crv, epic26, eproms_add, comorb))

        resp = self.client.get('/api/questionnaire')
        self.assert200(resp)
        self.assertEquals(len(resp.json['entry']), 3)

        resp = self.client.get('/api/questionnaire/{}'.format('epic26'))
        self.assert200(resp)
        self.assertEquals(resp.json['questionnaire']['name'], 'epic26')

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

        self.test_user.organizations.append(crv)
        with SessionScope(db):
            db.session.add(bank)
            db.session.commit()

        resp = self.client.get('/api/questionnaire_bank')
        self.assert200(resp)
        self.assertEquals(len(resp.json['entry'][0]['questionnaires']), 3)
Example #22
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=now)
        self.promote_user(role_name=ROLE.PATIENT.value)
        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, qb) == obs.issued

        # add mock in-process QB - confirm current qb is still correct
        mock_qr('q', 'in-progress', qb=qb)
        self.test_user, qb = map(db.session.merge, (self.test_user, qb))
        qb_stat = QB_Status(user=self.test_user, as_of_date=now)
        assert qb_stat.current_qbd().questionnaire_bank == qb
Example #23
0
    def test_lookup_for_user(self):
        crv = Organization(name='CRV')
        epic26 = Questionnaire(name='epic26')
        eproms_add = Questionnaire(name='eproms_add')
        comorb = Questionnaire(name='comorb')
        with SessionScope(db):
            db.session.add(crv)
            db.session.add(epic26)
            db.session.add(eproms_add)
            db.session.add(comorb)
            db.session.commit()
        crv, epic26, eproms_add, comorb = map(
            db.session.merge, (crv, epic26, eproms_add, comorb))

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

        self.test_user.organizations.append(crv)
        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)
        qd = QuestionnaireDetails(self.test_user, datetime.utcnow())
        results = list(qd.baseline())
        self.assertEquals(3, len(results))
        # confirm rank sticks
        self.assertEquals(results[0]['name'], 'epic26')
        self.assertEquals(results[2]['name'], 'comorb')
Example #24
0
    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)])
Example #25
0
def mock_questionnairebanks():
    # Define test Orgs and QuestionnaireBanks for each group
    localized_org = Organization(name='localized')
    metastatic_org = Organization(name='metastatic')

    # Recurring assessments every 3 months up to 24 months, then every
    # 6 months prems alternate with epic26 - start with prems
    initial_recur = Recur(days_to_start=90,
                          days_in_cycle=90,
                          days_till_termination=720)
    initial_recur_prems = Recur(days_to_start=90,
                                days_in_cycle=180,
                                days_till_termination=720)
    initial_recur_epic26 = Recur(days_to_start=180,
                                 days_in_cycle=180,
                                 days_till_termination=720)
    every_six_thereafter = Recur(days_to_start=720, days_in_cycle=180)
    every_six_thereafter_prems = Recur(days_to_start=720, days_in_cycle=360)
    every_six_thereafter_epic26 = Recur(days_to_start=900, days_in_cycle=360)

    with SessionScope(db):
        for name in (localized_instruments.union(
                *(metastatic_baseline_instruments,
                  metastatic_indefinite_instruments,
                  metastatic_recurring_instruments))):
            db.session.add(Questionnaire(name=name))
        db.session.add(localized_org)
        db.session.add(metastatic_org)
        db.session.add(initial_recur)
        db.session.add(initial_recur_prems)
        db.session.add(initial_recur_epic26)
        db.session.add(every_six_thereafter)
        db.session.add(every_six_thereafter_prems)
        db.session.add(every_six_thereafter_epic26)
        db.session.commit()
    localized_org, metastatic_org = map(db.session.merge,
                                        (localized_org, metastatic_org))
    localized_org_id = localized_org.id
    metastatic_org_id = metastatic_org.id
    initial_recur = db.session.merge(initial_recur)
    initial_recur_prems = db.session.merge(initial_recur_prems)
    initial_recur_epic26 = db.session.merge(initial_recur_epic26)
    every_six_thereafter = db.session.merge(every_six_thereafter)
    every_six_thereafter_prems = db.session.merge(every_six_thereafter_prems)
    every_six_thereafter_epic26 = db.session.merge(every_six_thereafter_epic26)

    # Localized baseline
    l_qb = QuestionnaireBank(name='localized',
                             classification='baseline',
                             organization_id=localized_org_id)
    for rank, instrument in enumerate(localized_instruments):
        q = Questionnaire.query.filter_by(name=instrument).one()
        qbq = QuestionnaireBankQuestionnaire(questionnaire=q,
                                             days_till_due=7,
                                             days_till_overdue=90,
                                             rank=rank)
        l_qb.questionnaires.append(qbq)

    # Metastatic baseline
    mb_qb = QuestionnaireBank(name='metastatic',
                              classification='baseline',
                              organization_id=metastatic_org_id)
    for rank, instrument in enumerate(metastatic_baseline_instruments):
        q = Questionnaire.query.filter_by(name=instrument).one()
        qbq = QuestionnaireBankQuestionnaire(questionnaire=q,
                                             days_till_due=1,
                                             days_till_overdue=30,
                                             rank=rank)
        mb_qb.questionnaires.append(qbq)

    # Metastatic indefinite
    mi_qb = QuestionnaireBank(name='metastatic_indefinite',
                              classification='indefinite',
                              organization_id=metastatic_org_id)
    for rank, instrument in enumerate(metastatic_indefinite_instruments):
        q = Questionnaire.query.filter_by(name=instrument).one()
        qbq = QuestionnaireBankQuestionnaire(questionnaire=q,
                                             days_till_due=1,
                                             days_till_overdue=3000,
                                             rank=rank)
        mi_qb.questionnaires.append(qbq)

    # Metastatic recurring
    mr_qb = QuestionnaireBank(name='metastatic_recurring',
                              classification='recurring',
                              organization_id=metastatic_org_id)
    for rank, instrument in enumerate(metastatic_recurring_instruments):
        q = Questionnaire.query.filter_by(name=instrument).one()
        if instrument == 'prems':
            recurs = [initial_recur_prems, every_six_thereafter_prems]
        elif instrument == 'epic26':
            recurs = [initial_recur_epic26, every_six_thereafter_epic26]
        else:
            recurs = [initial_recur, every_six_thereafter]

        qbq = QuestionnaireBankQuestionnaire(questionnaire=q,
                                             days_till_due=1,
                                             days_till_overdue=30,
                                             rank=rank,
                                             recurs=recurs)
        mr_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(mr_qb)
        db.session.commit()
Example #26
0
    def setup_qbs(self, org=None, rp_name='v2', retired_as_of=None):
        org, rp, rp_id = self.setup_org_n_rp(org=org,
                                             org_name='CRV',
                                             rp_name=rp_name,
                                             retired_as_of=retired_as_of)
        epic26 = self.add_questionnaire(name='epic26_{}'.format(rp_name))
        recur3 = Recur(start='{"months": 3}',
                       cycle_length='{"months": 6}',
                       termination='{"months": 24}')
        exists = Recur.query.filter_by(start=recur3.start,
                                       cycle_length=recur3.cycle_length,
                                       termination=recur3.termination).first()
        if exists:
            recur3 = exists

        recur6 = Recur(start='{"months": 6}',
                       cycle_length='{"years": 1}',
                       termination='{"years": 3, "months": 3}')
        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(epic26)
            db.session.add(recur3)
            db.session.add(recur6)
            db.session.commit()
        org, epic26, recur3, recur6 = map(db.session.merge,
                                          (org, epic26, recur3, recur6))

        qb_base = QuestionnaireBank(name='CRV Baseline {}'.format(rp_name),
                                    classification='baseline',
                                    research_protocol_id=rp_id,
                                    start='{"days": 0}',
                                    overdue='{"days": 30}',
                                    expired='{"months": 3}')
        qbq = QuestionnaireBankQuestionnaire(questionnaire=epic26, rank=0)
        qb_base.questionnaires.append(qbq)

        qb_m3 = QuestionnaireBank(
            name='CRV_recurring_3mo_period {}'.format(rp_name),
            classification='recurring',
            research_protocol_id=rp_id,
            start='{"days": 0}',
            overdue='{"days": 30}',
            expired='{"months": 3}',
            recurs=[recur3])
        qbq = QuestionnaireBankQuestionnaire(questionnaire=epic26, rank=0)
        qb_m3.questionnaires.append(qbq)

        qb_m6 = QuestionnaireBank(
            name='CRV_recurring_6mo_period {}'.format(rp_name),
            classification='recurring',
            research_protocol_id=rp_id,
            start='{"days": 0}',
            overdue='{"days": 30}',
            expired='{"months": 3}',
            recurs=[recur6])
        qbq = QuestionnaireBankQuestionnaire(questionnaire=epic26, rank=0)
        qb_m6.questionnaires.append(qbq)

        with SessionScope(db):
            db.session.add(qb_base)
            db.session.add(qb_m3)
            db.session.add(qb_m6)
            db.session.commit()
        qb_base, qb_m3, qb_m6 = map(db.session.merge, (qb_base, qb_m3, qb_m6))

        return db.session.merge(org)
Example #27
0
    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
Example #28
0
    def setup_org_qbs(self,
                      org=None,
                      rp_name='v2',
                      retired_as_of=None,
                      include_indef=False):
        org_name = org.name if org else 'CRV'
        org, rp, rp_id = self.setup_org_n_rp(org=org,
                                             org_name=org_name,
                                             rp_name=rp_name,
                                             retired_as_of=retired_as_of)
        # enable re-entrance - if first q exists, probably a second
        # org is being setup - return as the rest is done
        q_name = 'eortc_{}'.format(rp_name)
        for q in Questionnaire.query.all():
            if q.name == q_name:
                return

        eortc = self.add_questionnaire(name=q_name)
        epic26 = self.add_questionnaire(name='epic26_{}'.format(rp_name))
        recur3 = Recur(start='{"months": 3}',
                       cycle_length='{"months": 6}',
                       termination='{"months": 24}')
        exists = Recur.query.filter_by(start=recur3.start,
                                       cycle_length=recur3.cycle_length,
                                       termination=recur3.termination).first()
        if exists:
            recur3 = exists

        recur6 = Recur(start='{"months": 6}',
                       cycle_length='{"years": 1}',
                       termination='{"years": 3, "months": 3}')
        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(eortc)
            db.session.add(epic26)
            db.session.add(recur3)
            db.session.add(recur6)
            db.session.commit()
        org, eortc, epic26, recur3, recur6 = map(
            db.session.merge, (org, eortc, epic26, recur3, recur6))

        qb_base = QuestionnaireBank(name='{} Baseline {}'.format(
            org_name, rp_name),
                                    classification='baseline',
                                    research_protocol_id=rp_id,
                                    start='{"days": 0}',
                                    overdue='{"days": 30}',
                                    expired='{"months": 3}')
        qbq = QuestionnaireBankQuestionnaire(questionnaire=epic26, rank=0)
        qbq2 = QuestionnaireBankQuestionnaire(questionnaire=eortc, rank=1)
        qb_base.questionnaires.append(qbq)
        qb_base.questionnaires.append(qbq2)

        qb_m3 = QuestionnaireBank(name='{}_recurring_3mo_period {}'.format(
            org_name, rp_name),
                                  classification='recurring',
                                  research_protocol_id=rp_id,
                                  start='{"days": 0}',
                                  overdue='{"days": 30}',
                                  expired='{"months": 3}',
                                  recurs=[recur3])
        qbq = QuestionnaireBankQuestionnaire(questionnaire=epic26, rank=0)
        qbq2 = QuestionnaireBankQuestionnaire(questionnaire=eortc, rank=1)
        qb_m3.questionnaires.append(qbq)
        qb_m3.questionnaires.append(qbq2)

        qb_m6 = QuestionnaireBank(name='{}_recurring_6mo_period {}'.format(
            org_name, rp_name),
                                  classification='recurring',
                                  research_protocol_id=rp_id,
                                  start='{"days": 0}',
                                  overdue='{"days": 30}',
                                  expired='{"months": 3}',
                                  recurs=[recur6])
        qbq = QuestionnaireBankQuestionnaire(questionnaire=epic26, rank=0)
        qbq2 = QuestionnaireBankQuestionnaire(questionnaire=eortc, rank=1)
        qb_m6.questionnaires.append(qbq)
        qb_m6.questionnaires.append(qbq2)

        with SessionScope(db):
            db.session.add(qb_base)
            db.session.add(qb_m3)
            db.session.add(qb_m6)
            db.session.commit()

        if include_indef:
            self.setup_qb(questionnaire_name='irondemog_{}'.format(rp_name),
                          qb_name='indef_{}'.format(rp_name),
                          classification='indefinite',
                          rp_id=rp_id,
                          expired="{\"years\": 50}")

        return db.session.merge(org)
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()