def test_deactivate_tous(self):
        timestamp = datetime.utcnow()

        pptou_audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID,
                            timestamp=timestamp)
        pptou = ToU(audit=pptou_audit, agreement_url=tou_url,
                    type='privacy policy')

        wtou_audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        wtou = ToU(audit=wtou_audit, agreement_url=tou_url,
                   type='website terms of use')

        with SessionScope(db):
            db.session.add(pptou)
            db.session.add(wtou)
            db.session.commit()
        self.test_user, pptou, wtou = map(
            db.session.merge, (self.test_user, pptou, wtou))

        # confirm active
        self.assertTrue(all((pptou.active, wtou.active)))

        # test deactivating single type
        self.test_user.deactivate_tous(self.test_user, ['privacy policy'])
        self.assertFalse(pptou.active)
        self.assertTrue(wtou.active)

        # test deactivating all types
        self.test_user.deactivate_tous(self.test_user)
        self.assertFalse(all((pptou.active, wtou.active)))
Example #2
0
 def prep_db_for_clinical(self):
     # First push some clinical data into the db for the test user
     with SessionScope(db):
         audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
         observation = Observation()
         coding = Coding(system='SNOMED-CT',
                         code='372278000',
                         display='Gleason score')
         cc = CodeableConcept(codings=[
             coding,
         ])
         observation.codeable_concept = cc
         observation.value_quantity = ValueQuantity(value=2)
         performer = Performer(reference_txt=json.dumps(
             Reference.patient(TEST_USER_ID).as_fhir()))
         observation.performers.append(performer)
         db.session.add(observation)
         enc = Encounter(status='planned',
                         auth_method='url_authenticated',
                         user_id=TEST_USER_ID,
                         start_time=datetime.utcnow())
         db.session.add(enc)
         db.session.flush()
         db.session.add(
             UserObservation(user_id=int(TEST_USER_ID),
                             observation_id=observation.id,
                             encounter_id=enc.id,
                             audit=audit))
         db.session.commit()
Example #3
0
 def add_procedure(self, code='367336001', display='Chemotherapy',
                   system=SNOMED, setdate=None):
     "Add procedure data into the db for the test user"
     with SessionScope(db):
         audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
         procedure = Procedure(audit=audit)
         coding = Coding(
             system=system,
             code=code,
             display=display).add_if_not_found(True)
         code = CodeableConcept(codings=[coding]).add_if_not_found(True)
         enc = Encounter(
             status='planned',
             auth_method='url_authenticated',
             user_id=TEST_USER_ID, start_time=datetime.utcnow())
         db.session.add(enc)
         db.session.commit()
         enc = db.session.merge(enc)
         procedure.code = code
         procedure.user = db.session.merge(self.test_user)
         procedure.start_time = setdate or datetime.utcnow()
         procedure.end_time = datetime.utcnow()
         procedure.encounter = enc
         db.session.add(procedure)
         db.session.commit()
Example #4
0
 def test_staff_access(self):
     staff = self.add_user('*****@*****.**')
     self.promote_user(role_name=ROLE.PATIENT)
     self.promote_user(staff, role_name=ROLE.STAFF)
     self.shallow_org_tree()
     org = Organization.query.filter(Organization.id > 0).first()
     staff.organizations.append(org)
     self.test_user.organizations.append(org)
     audit = Audit(user_id=TEST_USER_ID,
                   subject_id=TEST_USER_ID,
                   comment='just test data')
     consent = UserConsent(user_id=TEST_USER_ID,
                           organization_id=org.id,
                           audit=audit,
                           agreement_url='http://fake.org')
     with SessionScope(db):
         db.session.add(audit)
         db.session.add(consent)
         db.session.commit()
     staff = db.session.merge(staff)
     self.login(staff.id)
     rv = self.client.get('/api/user/{}/audit'.format(TEST_USER_ID))
     self.assert200(rv)
     self.assertEquals(1, len(rv.json['audits']))
     self.assertEquals(
         rv.json['audits'][0]['by']['reference'],
         Reference.patient(TEST_USER_ID).as_fhir()['reference'])
     self.assertEquals(rv.json['audits'][0]['on'],
                       Reference.patient(TEST_USER_ID).as_fhir())
     self.assertEquals(rv.json['audits'][0]['context'], 'other')
     self.assertEquals(rv.json['audits'][0]['comment'], 'just test data')
    def test_user_consent(self):
        self.shallow_org_tree()
        org1, org2 = [
            org
            for org in Organization.query.filter(Organization.id > 0).limit(2)
        ]

        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        uc1 = UserConsent(organization_id=org1.id,
                          user_id=TEST_USER_ID,
                          agreement_url=self.url,
                          audit=audit)
        uc2 = UserConsent(organization_id=org2.id,
                          user_id=TEST_USER_ID,
                          agreement_url=self.url,
                          audit=audit)
        uc1.staff_editable = True
        uc1.send_reminders = False
        uc2.staff_editable = True
        uc2.send_reminders = False
        with SessionScope(db):
            db.session.add(uc1)
            db.session.add(uc2)
            db.session.commit()
        self.test_user = db.session.merge(self.test_user)
        self.login()
        rv = self.client.get('/api/user/{}/consent'.format(TEST_USER_ID))
        self.assert200(rv)
        self.assertEquals(len(rv.json['consent_agreements']), 2)
        self.assertTrue(
            'send_reminders' not in rv.json['consent_agreements'][0])
        self.assertTrue('staff_editable' in rv.json['consent_agreements'][0])
Example #6
0
    def testP3Pstrategy(self):
        # Prior to meeting conditions in strategy, user shouldn't have access
        # (provided we turn off public access)
        INTERVENTION.DECISION_SUPPORT_P3P.public_access = False
        INTERVENTION.SEXUAL_RECOVERY.public_access = False  # part of strat.
        user = self.test_user
        assert not INTERVENTION.DECISION_SUPPORT_P3P.display_for_user(
            user).access

        # Fulfill conditions
        enc = Encounter(status='in-progress',
                        auth_method='url_authenticated',
                        user_id=TEST_USER_ID,
                        start_time=datetime.utcnow())
        with SessionScope(db):
            db.session.add(enc)
            db.session.commit()
        self.add_procedure(code='424313000',
                           display='Started active surveillance')
        get_user(TEST_USER_ID).save_observation(
            codeable_concept=CC.PCaLocalized,
            value_quantity=CC.TRUE_VALUE,
            audit=Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID),
            status=None,
            issued=None)
        self.promote_user(user, role_name=ROLE.PATIENT.value)
        with SessionScope(db):
            db.session.commit()
        user = db.session.merge(user)

        # P3P strategy should now be in view for test user
        assert INTERVENTION.DECISION_SUPPORT_P3P.display_for_user(user).access
    def test_user_consent(self):
        self.shallow_org_tree()
        org1, org2 = [
            org
            for org in Organization.query.filter(Organization.id > 0).limit(2)
        ]

        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        uc1 = UserConsent(organization_id=org1.id,
                          user_id=TEST_USER_ID,
                          agreement_url=self.url,
                          audit=audit)
        uc2 = UserConsent(organization_id=org2.id,
                          user_id=TEST_USER_ID,
                          agreement_url=self.url,
                          audit=audit)
        uc1.staff_editable = True
        uc1.send_reminders = False
        uc2.staff_editable = True
        uc2.send_reminders = False
        uc2.status = 'suspended'
        with SessionScope(db):
            db.session.add(uc1)
            db.session.add(uc2)
            db.session.commit()
        self.test_user = db.session.merge(self.test_user)
        self.login()
        response = self.client.get('/api/user/{}/consent'.format(TEST_USER_ID))
        assert response.status_code == 200
        assert len(response.json['consent_agreements']) == 2
        assert 'send_reminders' not in response.json['consent_agreements'][0]
        assert 'staff_editable' in response.json['consent_agreements'][0]
        assert response.json['consent_agreements'][0]['status'] == 'consented'
        assert response.json['consent_agreements'][1]['status'] == 'suspended'
Example #8
0
 def add_required_clinical_data(self):
     " Add clinical data to get beyond the landing page "
     for cc in CC.BIOPSY, CC.PCaDIAG, CC.PCaLocalized:
         get_user(TEST_USER_ID).save_constrained_observation(
             codeable_concept=cc,
             value_quantity=CC.TRUE_VALUE,
             audit=Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID))
 def test_tou_str(self):
     audit = Audit(
         user_id=TEST_USER_ID, subject_id=TEST_USER_ID,
         comment="Agreed to ToU", context='other')
     tou = ToU(audit=audit, agreement_url=tou_url,
               type='website terms of use')
     results = "{}".format(tou)
     self.assertTrue(tou_url in results)
def upgrade():
    localized_org = current_app.config.get('LOCALIZED_AFFILIATE_ORG')
    if not localized_org:
        return

    bind = op.get_bind()
    session = Session(bind=bind)

    admin = User.query.filter_by(email='*****@*****.**').first()
    admin = admin or User.query.join(
        UserRoles).join(Role).filter(
        sa.and_(
            Role.id == UserRoles.role_id, UserRoles.user_id == User.id,
            Role.name == 'admin')).first()
    admin_id = admin.id

    # encounter needed to save_observation
    initiate_encounter(admin, "staff_authenticated")

    localized_org_id = session.query(Organization).filter(
        Organization.name == localized_org).one().id
    patient_id = session.query(Role).filter(Role.name == 'patient').one().id
    org_list = OrgTree().here_and_below_id(localized_org_id)

    query = User.query.join(UserOrganization).join(UserRoles).filter(sa.and_(
        User.id == UserOrganization.user_id,
        User.id == UserRoles.user_id,
        UserRoles.role_id == patient_id,
        UserOrganization.organization_id.in_(org_list))).with_entities(User)

    for user in query:
        if user.concept_value(CC.PCaLocalized) == 'true':
            # user already has positive PCaLocalized observation
            continue
        else:
            audit = Audit(
                user_id=admin_id, subject_id=patient_id,
                context='observation')
            user.save_observation(
                codeable_concept=CC.PCaLocalized,
                value_quantity=CC.TRUE_VALUE,
                audit=audit, status=None, issued=None)
            audit.comment = "set {0} {1} on user {2}".format(
                CC.PCaLocalized, CC.TRUE_VALUE, patient_id)

    session.commit()
Example #11
0
def upgrade():
    localized_org = current_app.config.get('LOCALIZED_AFFILIATE_ORG')
    if not localized_org:
        return

    bind = op.get_bind()
    session = Session(bind=bind)

    admin = User.query.filter_by(email='*****@*****.**').first()
    admin = admin or User.query.join(UserRoles).join(Role).filter(
        sa.and_(Role.id == UserRoles.role_id, UserRoles.user_id == User.id,
                Role.name == 'admin')).first()
    admin_id = admin.id

    # encounter needed to save_observation
    initiate_encounter(admin, "staff_authenticated")

    localized_org_id = session.query(Organization).filter(
        Organization.name == localized_org).one().id
    patient_id = session.query(Role).filter(Role.name == 'patient').one().id
    org_list = OrgTree().here_and_below_id(localized_org_id)

    query = User.query.join(UserOrganization).join(UserRoles).filter(
        sa.and_(User.id == UserOrganization.user_id,
                User.id == UserRoles.user_id, UserRoles.role_id == patient_id,
                UserOrganization.organization_id.in_(org_list))).with_entities(
                    User)

    for user in query:
        if user.concept_value(CC.PCaLocalized) == 'true':
            # user already has positive PCaLocalized observation
            continue
        else:
            audit = Audit(user_id=admin_id,
                          subject_id=patient_id,
                          context='observation')
            user.save_observation(codeable_concept=CC.PCaLocalized,
                                  value_quantity=CC.TRUE_VALUE,
                                  audit=audit,
                                  status=None,
                                  issued=None)
            audit.comment = "set {0} {1} on user {2}".format(
                CC.PCaLocalized, CC.TRUE_VALUE, patient_id)

    session.commit()
Example #12
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 #13
0
    def test_procedure_from_fhir(self):
        with open(os.path.join(os.path.dirname(__file__),
                               'procedure-example.json'), 'r') as fhir_data:
            data = json.load(fhir_data)

        proc = Procedure.from_fhir(data, Audit(user_id=TEST_USER_ID))
        assert proc.code.codings[0].system == 'http://snomed.info/sct'
        assert proc.code.codings[0].code == '80146002'
        assert proc.start_time == dateutil.parser.parse("2013-04-05")
Example #14
0
    def bless_with_basics(self, backdate=None):
        """Bless test user with basic requirements for coredata

        :param backdate: timedelta value.  Define to mock consents
          happening said period in the past

        """
        self.test_user = db.session.merge(self.test_user)
        self.test_user.birthdate = datetime.utcnow()

        # Register with a clinic
        self.shallow_org_tree()
        org = Organization.query.filter(Organization.partOf_id != None).first()
        assert org
        self.test_user.organizations.append(org)

        # Agree to Terms of Use and sign consent
        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        if backdate:
            audit.timestamp = datetime.utcnow() - backdate
        tou = ToU(audit=audit,
                  agreement_url='http://not.really.org',
                  type='website terms of use')
        privacy = ToU(audit=audit,
                      agreement_url='http://not.really.org',
                      type='privacy policy')
        parent_org = OrgTree().find(org.id).top_level()
        options = (STAFF_EDITABLE_MASK | INCLUDE_IN_REPORTS_MASK
                   | SEND_REMINDERS_MASK)
        consent = UserConsent(user_id=TEST_USER_ID,
                              organization_id=parent_org,
                              options=options,
                              audit=audit,
                              agreement_url='http://fake.org')
        with SessionScope(db):
            db.session.add(tou)
            db.session.add(privacy)
            db.session.add(consent)
            db.session.commit()

        # Invalidate org tree cache, in case orgs are added by other
        # tests.  W/o doing so, the new orgs aren't in the orgtree
        OrgTree.invalidate_cache()
Example #15
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)
Example #16
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)
    def test_get(self):
        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        tou = ToU(audit=audit, agreement_url=tou_url,
                  type='website terms of use')
        with SessionScope(db):
            db.session.add(tou)
            db.session.commit()

        self.login()
        rv = self.client.get('/api/user/{}/tou'.format(TEST_USER_ID))
        doc = json.loads(rv.data)
        self.assert200(rv)
        self.assertEqual(len(doc['tous']), 1)
Example #18
0
 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=now)
     qstats = QB_Status(self.test_user, now)
     assert not qstats.current_qbd()
     assert not qstats.enrolled_in_classification("baseline")
 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)
Example #20
0
    def test_get(self):
        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        tou = ToU(audit=audit,
                  agreement_url=tou_url,
                  type='website terms of use')
        with SessionScope(db):
            db.session.add(tou)
            db.session.commit()

        self.login()
        response = self.client.get('/api/user/{}/tou'.format(TEST_USER_ID))
        doc = response.json
        assert response.status_code == 200
        assert len(doc['tous']) == 1
Example #21
0
    def add_required_clinical_data(self, backdate=None, setdate=None):
        """Add clinical data to get beyond the landing page

        :param backdate: timedelta value.  Define to mock Dx
          happening said period in the past
        :param setdate: datetime value.  Define to mock Dx
          happening at given time

        """
        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        for cc in CC.BIOPSY, CC.PCaDIAG, CC.PCaLocalized:
            get_user(TEST_USER_ID).save_observation(
                codeable_concept=cc, value_quantity=CC.TRUE_VALUE,
                audit=audit, status='preliminary', issued=calc_date_params(
                    backdate=backdate, setdate=setdate))
Example #22
0
def upgrade():
    bind = op.get_bind()
    session = Session(bind=bind)

    to_delete = set()
    for obs_id, audit_id in session.execute(
            'SELECT id, audit_id FROM observations'):
        to_delete.add(audit_id)

    if session.execute("SELECT * FROM information_schema.table_constraints "
                       "WHERE constraint_name='observations_audit_id_fkey'"
                       "AND table_name='observations'").rowcount > 0:
        op.drop_constraint(u'observations_audit_id_fkey',
                           'observations',
                           type_='foreignkey')
    elif session.execute("SELECT * FROM information_schema.table_constraints "
                         "WHERE constraint_name='observations_audit_fk'"
                         "AND table_name='observations'").rowcount > 0:
        op.drop_constraint(u'observations_audit_fk',
                           'observations',
                           type_='foreignkey')
    op.drop_column('observations', 'audit_id')
    op.add_column('user_observations',
                  sa.Column('audit_id', sa.Integer(), nullable=True))
    op.create_foreign_key(u'user_observations_audit_id_fkey',
                          'user_observations', 'audit', ['audit_id'], ['id'])

    # delete old Observation audits
    if to_delete:
        session.execute("DELETE from audit where id in {}".format(
            tuple(to_delete)))

    # create new audits for UserObservations
    for uo_id, user_id in session.execute(
            'SELECT id, user_id FROM user_observations'):
        aud = Audit(
            user_id=user_id,
            subject_id=user_id,
            comment="entry predates audit records for user observations")
        session.add(aud)
        session.commit()
        aud = session.merge(aud)
        session.execute('UPDATE user_observations SET audit_id = {} '
                        'WHERE id = {}'.format(aud.id, uo_id))

    op.alter_column('user_observations', 'audit_id', nullable=False)
Example #23
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_org_qbs(rp_name='v2', retired_as_of=weekago)
        org_id = org.id
        self.setup_org_qbs(org=org, rp_name='v3')

        self.promote_user(role_name=ROLE.PATIENT.value)
        self.test_user = db.session.merge(self.test_user)
        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()
        user = db.session.merge(self.test_user)

        # Now, should still be rp v3, 3mo recurrence
        a_s = QB_Status(user=user, as_of_date=now)
        assert (a_s.current_qbd().questionnaire_bank.name ==
                'CRV_recurring_3mo_period v3')
        assert a_s.instruments_needing_full_assessment() == [
            'epic26_v3', 'eortc_v3'
        ]

        # Complete the questionnaire from the 3mo v2 QB
        v2qb = QuestionnaireBank.query.filter(
            QuestionnaireBank.name == 'CRV_recurring_3mo_period v2').one()
        mock_qr('epic26_v2', timestamp=twoweeksago, qb=v2qb, iteration=0)
        mock_qr('eortc_v2', timestamp=twoweeksago, qb=v2qb, iteration=0)

        # Two weeks ago, should be completed
        user = db.session.merge(user)
        a_s = QB_Status(user=user, as_of_date=twoweeksago)
        assert a_s.overall_status == OverallStatus.completed

        # Current should also be completed, even tho protocol changed
        a_s = QB_Status(user=user, as_of_date=now)
        assert a_s.overall_status == OverallStatus.completed
Example #24
0
    def test_get_by_type(self):
        timestamp = datetime.utcnow()
        audit = Audit(user_id=TEST_USER_ID,
                      subject_id=TEST_USER_ID,
                      timestamp=timestamp)
        tou = ToU(audit=audit, agreement_url=tou_url, type='privacy policy')
        with SessionScope(db):
            db.session.add(tou)
            db.session.commit()

        self.login()
        rv = self.client.get(
            '/api/user/{}/tou/privacy-policy'.format(TEST_USER_ID))
        self.assert200(rv)
        self.assertEquals(rv.json['accepted'],
                          timestamp.strftime("%Y-%m-%dT%H:%M:%S"))
        self.assertEquals(rv.json['type'], 'privacy policy')
Example #25
0
def downgrade():
    bind = op.get_bind()
    session = Session(bind=bind)

    to_delete = set()
    for obs_id, audit_id in session.execute(
            'SELECT id, audit_id FROM user_observations'):
        to_delete.add(audit_id)

    op.drop_constraint(u'user_observations_audit_id_fkey',
                       'user_observations',
                       type_='foreignkey')
    op.drop_column('user_observations', 'audit_id')
    op.add_column(
        'observations',
        sa.Column('audit_id', sa.INTEGER(), autoincrement=False,
                  nullable=True))
    op.create_foreign_key(u'observations_audit_id_fkey', 'observations',
                          'audit', ['audit_id'], ['id'])

    # delete old UserObservation audits
    session.execute("DELETE from audit where id in {}".format(
        tuple(to_delete)))

    # create new audits for Observations
    admin = User.query.filter_by(email='*****@*****.**').first()
    admin = admin or User.query.join(UserRoles).join(Role).filter(
        sa.and_(Role.id == UserRoles.role_id, UserRoles.user_id == User.id,
                Role.name == 'admin')).first()
    admin_id = admin.id

    for obs_id in session.execute(
            'SELECT id FROM observations where audit_id IS NULL'):
        aud = Audit(
            user_id=admin_id,
            subject_id=admin_id,
            comment="entry replaces audit records for user observations")
        session.add(aud)
        session.commit()
        aud = session.merge(aud)
        session.execute('UPDATE observations SET audit_id = {} '
                        'WHERE id = {}'.format(aud.id, obs_id[0]))

    op.alter_column('observations', 'audit_id', nullable=False)
    def test_delete_user_consent(self):
        self.shallow_org_tree()
        org1, org2 = [
            org
            for org in Organization.query.filter(Organization.id > 0).limit(2)
        ]
        org1_id, org2_id = org1.id, org2.id
        data = {'organization_id': org1_id}

        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        uc1 = UserConsent(organization_id=org1_id,
                          user_id=TEST_USER_ID,
                          agreement_url=self.url,
                          audit=audit)
        uc2 = UserConsent(organization_id=org2_id,
                          user_id=TEST_USER_ID,
                          agreement_url=self.url,
                          audit=audit)
        with SessionScope(db):
            db.session.add(uc1)
            db.session.add(uc2)
            db.session.commit()
        self.test_user = db.session.merge(self.test_user)
        assert self.test_user.valid_consents.count() == 2
        self.login()

        response = self.client.delete(
            '/api/user/{}/consent'.format(TEST_USER_ID),
            content_type='application/json',
            data=json.dumps(data))
        assert response.status_code == 200
        assert self.test_user.valid_consents.count() == 1
        assert self.test_user.valid_consents[0].organization_id == org2_id

        # We no longer omit deleted consent rows, but rather, include
        # their audit data.
        response = self.client.get('/api/user/{}/consent'.format(TEST_USER_ID))
        assert 'deleted' in json.dumps(response.json)

        # confirm deleted status
        dc = UserConsent.query.filter_by(user_id=TEST_USER_ID,
                                         organization_id=org1_id).first()
        assert dc.status == 'deleted'
    def test_get_by_type(self):
        timestamp = datetime.utcnow()
        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID,
                      timestamp=timestamp)
        tou = ToU(audit=audit, agreement_url=tou_url,
                  type='privacy policy')
        with SessionScope(db):
            db.session.add(tou)
            db.session.commit()

        self.login()
        rv = self.client.get('/api/user/{}/tou/privacy-policy'.format(
                             TEST_USER_ID))
        self.assert200(rv)
        # result must be timezone aware isoformat, without microseconds
        tzaware = timestamp.replace(tzinfo=pytz.utc)
        wo_micro = tzaware.replace(microsecond=0)
        self.assertEqual(rv.json['accepted'], wo_micro.isoformat())
        self.assertEqual(rv.json['type'], 'privacy policy')
Example #28
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 #29
0
def upgrade():
    bind = op.get_bind()
    session = Session(bind=bind)

    admin = User.query.filter_by(email='*****@*****.**').first()
    admin = admin or User.query.join(
        UserRoles).join(Role).filter(
        sa.and_(
            Role.id == UserRoles.role_id, UserRoles.user_id == User.id,
            Role.name == 'admin')).first()
    admin_id = admin.id

    query = session.query(UserConsent).join(
        Audit, UserConsent.audit_id == Audit.id).with_entities(
        UserConsent, Audit.timestamp)

    eligible_uc_ids = {}
    for uc, timestamp in query:
        if uc.acceptance_date.microsecond != 0:
            # skip the honest ones, that differ by milliseconds
            if timestamp - uc.acceptance_date < timedelta(seconds=5):
                continue
            if timestamp - uc.acceptance_date > timedelta(days=8):
                raise ValueError(
                    "too big of a jump - please review {} {} {}".format(
                        uc.user_id, timestamp, uc.acceptance_date))
            eligible_uc_ids[uc.id] = (
                uc.acceptance_date, timestamp.replace(microsecond=0))

    # now update each in eligible list outside of initial query
    for uc_id, dates in eligible_uc_ids.items():
        old_acceptance_date, new_acceptance_date = dates
        msg = "Correct stale default acceptance_date {} to {}".format(
            old_acceptance_date, new_acceptance_date)
        uc = session.query(UserConsent).get(uc_id)
        audit = Audit(
            user_id=admin_id, subject_id=uc.user_id, context='consent',
            comment=msg)
        uc.audit = audit
        uc.acceptance_date = new_acceptance_date

    session.commit()
Example #30
0
    def consent_with_org(self, org_id, user_id=TEST_USER_ID,
                         backdate=None, setdate=None):
        """Bless given user with a valid consent with org

        :param backdate: timedelta value.  Define to mock consents
          happening said period in the past

        :param setdate: datetime value.  Define to mock consents
          happening at exact time in the past

        """
        audit = Audit(user_id=user_id, subject_id=user_id)
        consent = UserConsent(
            user_id=user_id, organization_id=org_id,
            audit=audit, agreement_url='http://fake.org',
            acceptance_date=calc_date_params(
                backdate=backdate, setdate=setdate))
        with SessionScope(db):
            db.session.add(consent)
            db.session.commit()
    def test_content_options(self):
        audit = Audit(user_id=TEST_USER_ID, subject_id=TEST_USER_ID)
        self.shallow_org_tree()
        org1, _ = [
            org
            for org in Organization.query.filter(Organization.id > 0).limit(2)
        ]
        uc = UserConsent(user_id=TEST_USER_ID,
                         organization=org1,
                         audit=audit,
                         agreement_url='http://no.com')
        uc.include_in_reports = True
        with SessionScope(db):
            db.session.add(uc)
            db.session.commit()

        uc = UserConsent.query.first()
        self.assertTrue(uc.include_in_reports)
        self.assertFalse(uc.staff_editable)
        self.assertFalse(uc.send_reminders)
Example #32
0
 def test_parse_timezone(self):
     a1 = Audit.from_logentry(log_login_google)
     expected = parser.parse("2016-02-23 09:52")
     assert a1.timestamp == expected
Example #33
0
 def test_message(self):
     a1 = Audit.from_logentry(log_callbacks)
     expected = """ after: Client: yoOjy6poL2dVPVcXgi7zc8gCS0qvnOzpwyQemCTw, redirects: https://stg-sr.us.truenth.org/, callback: https://stg-sr.us.truenth.org/_/callback"""
     assert a1.comment == expected
Example #34
0
 def test_parse_context(self):
     a1 = Audit.from_logentry(log_login_idp)
     assert a1.context == "login"
Example #35
0
 def test_parse_subject(self):
     a1 = Audit.from_logentry(log_login_idp)
     assert a1.subject_id == TEST_USER_ID
Example #36
0
 def test_parse_user(self):
     a1 = Audit.from_logentry(log_login_idp)
     assert a1.user_id == TEST_USER_ID