Beispiel #1
0
    def test_success(self, req, dbsession, check_csrf_token):
        """
        It should allow removal of entities from a visit.
        """
        from datetime import date, timedelta
        from pyramid.httpexceptions import HTTPOk
        from occams import models as datastore
        from occams import models

        cycle = models.Cycle(name='week-1', title=u'', week=1)

        schema = datastore.Schema(
            name=u'sample', title=u'', publish_date=date.today())

        study = models.Study(
            name=u'somestudy',
            title=u'Some Study',
            short_title=u'sstudy',
            code=u'000',
            consent_date=date.today(),
            cycles=[cycle],
            schemata=set([schema]))

        site = models.Site(name=u'ucsd', title=u'UCSD')

        default_state = (
            dbsession.query(datastore.State)
            .filter_by(name=u'pending-entry')
            .one())

        t_a = date.today() + timedelta(days=5)
        patient_a = models.Patient(site=site, pid=u'12345')
        visit_a = models.Visit(
            patient=patient_a, cycles=[cycle], visit_date=t_a)
        entity_a_1 = datastore.Entity(
            schema=schema, collect_date=t_a, state=default_state)
        entity_a_2 = datastore.Entity(
            schema=schema, collect_date=t_a, state=default_state)
        entity_a_3 = datastore.Entity(
            schema=schema, collect_date=t_a, state=default_state)
        list(map(visit_a.entities.add, [entity_a_1, entity_a_2, entity_a_3]))

        dbsession.add_all([visit_a, study])
        dbsession.flush()

        req.json_body = {
            'forms': [entity_a_2.id, entity_a_3.id]
        }

        res = self._call_fut(visit_a['forms'], req)

        # refresh the session so we can get a correct listing
        dbsession.expunge_all()
        visit_a = dbsession.query(models.Visit).get(visit_a.id)

        assert isinstance(res, HTTPOk)
        assert sorted([e.id for e in [entity_a_1]]) == \
            sorted([e.id for e in visit_a.entities])
Beispiel #2
0
    def test_cascade_forms(self, req, dbsession, check_csrf_token):
        """
        It should remove all visit-associated forms.
        """
        from datetime import date
        from occams import models as datastore
        from occams import models

        schema = datastore.Schema(
            name=u'sample',
            title=u'Some Sample',
            publish_date=date.today())

        study = models.Study(
            name=u'somestudy',
            title=u'Some Study',
            short_title=u'sstudy',
            code=u'000',
            consent_date=date.today())

        cycle = models.Cycle(
            name=u'week-10',
            title=u'Week 10',
            week=10)

        study.cycles.append(cycle)

        patient = models.Patient(
            site=models.Site(name=u'ucsd', title=u'UCSD'),
            pid=u'12345')

        enrollment = models.Enrollment(
            study=study,
            patient=patient,
            consent_date=date.today())

        visit = models.Visit(
            patient=patient,
            cycles=[cycle],
            visit_date=date.today())

        visit.entities.add(datastore.Entity(
            schema=schema,
            collect_date=date.today()))

        dbsession.add_all([patient, enrollment, study, visit])
        dbsession.flush()

        visit_id = visit.id

        self._call_fut(visit, req)

        assert dbsession.query(models.Visit).get(visit_id) is None
        assert 0 == dbsession.query(datastore.Entity).count()
Beispiel #3
0
    def populate(self, app, dbsession):
        import transaction
        from occams import models
        from datetime import date

        # Any view-dependent data goes here
        # Webtests will use a different scope for its transaction
        with transaction.manager:
            user = models.User(key=USERID)
            dbsession.info['blame'] = user
            dbsession.add(user)
            dbsession.flush()

            site = models.Site(name=u'UCSD',
                               title=u'UCSD',
                               description=u'UCSD Campus',
                               create_date=date.today())

            patient = models.Patient(initials=u'ian',
                                     nurse=u'*****@*****.**',
                                     site=site,
                                     pid=u'123')

            form = models.Schema(name=u'test_schema',
                                 title=u'test_title',
                                 publish_date=date(2015, 1, 1))

            study = models.Study(name=u'test_study',
                                 code=u'test_code',
                                 consent_date=date(2014, 12, 23),
                                 is_randomized=False,
                                 title=u'test_title',
                                 short_title=u'test_short',
                                 schemata=set([form]))

            cycle = models.Cycle(name=u'TestCycle',
                                 title=u'TestCycle',
                                 week=39,
                                 study=study)

            visit = models.Visit(patient=patient,
                                 cycles=[cycle],
                                 visit_date='2015-01-01')

            entity = models.Entity(schema=form, collect_date=date(2015, 1, 1))

            dbsession.add(study)
            dbsession.add(patient)
            dbsession.add(visit)
            dbsession.add(entity)
            patient.entities.add(entity)
Beispiel #4
0
    def test_unique_visit_date(self, req, dbsession, check_csrf_token):
        """
        It should not allow duplicate visit dates
        """
        from datetime import date
        from pyramid.httpexceptions import HTTPBadRequest
        from occams import models

        study = models.Study(
            name=u'somestudy',
            title=u'Some Study',
            short_title=u'sstudy',
            code=u'000',
            consent_date=date.today())

        cycle1 = models.Cycle(name='week-1', title=u'', week=1)
        cycle2 = models.Cycle(name='week-2', title=u'', week=2)

        study.cycles.append(cycle1)
        study.cycles.append(cycle2)

        patient = models.Patient(
            site=models.Site(name=u'ucsd', title=u'UCSD'),
            pid=u'12345')

        visit = models.Visit(
            patient=patient,
            cycles=[cycle1],
            visit_date=date.today())

        dbsession.add_all([patient, study, visit])
        dbsession.flush()

        req.json_body = {
            'cycles': [cycle2.id],
            'visit_date': str(date.today())
        }

        # Update the visit, should allow to update the date
        self._call_fut(visit, req)

        # New visits cannot share dates
        with pytest.raises(HTTPBadRequest) as excinfo:
            self._call_fut(patient['visits'], req)

        assert 'already exists' in \
            excinfo.value.json['errors']['visit_date']
Beispiel #5
0
    def test_unique_cycle(self, req, dbsession, check_csrf_token):
        """
        It should not allow repeat cycles (unless it's interim)
        """
        from datetime import date, timedelta
        from pyramid.httpexceptions import HTTPBadRequest
        from occams import models

        study = models.Study(
            name=u'somestudy',
            title=u'Some Study',
            short_title=u'sstudy',
            code=u'000',
            consent_date=date.today())

        cycle = models.Cycle(name='week-1', title=u'', week=1)

        study.cycles.append(cycle)

        patient = models.Patient(
            site=models.Site(name=u'ucsd', title=u'UCSD'),
            pid=u'12345')

        visit = models.Visit(
            patient=patient, cycles=[cycle], visit_date=date.today())

        dbsession.add_all([patient, study, visit])
        dbsession.flush()

        req.json_body = {
            'cycles': [cycle.id],
            'visit_date': str(date.today() + timedelta(days=1))
        }

        with pytest.raises(HTTPBadRequest) as excinfo:
            self._call_fut(patient['visits'], req)

        assert 'already in use' in \
            excinfo.value.json['errors']['cycles-0'].lower()

        # The exception is interims
        cycle.is_interim = True
        dbsession.flush()
        res = self._call_fut(patient['visits'], req)

        assert res is not None
Beispiel #6
0
    def test_not_in_study(self, req, dbsession):
        """
        It should fail if the form is not part of the study
        """
        from datetime import date, timedelta
        from pyramid.httpexceptions import HTTPBadRequest
        from occams import models

        cycle = models.Cycle(name='week-1', title=u'', week=1)

        schema = models.Schema(name=u'sample',
                               title=u'',
                               publish_date=date.today())

        study = models.Study(name=u'somestudy',
                             title=u'Some Study',
                             short_title=u'sstudy',
                             code=u'000',
                             consent_date=date.today(),
                             cycles=[cycle])

        site = models.Site(name=u'ucsd', title=u'UCSD')

        t_a = date.today() + timedelta(days=5)
        patient_a = models.Patient(site=site, pid=u'12345')
        visit_a = models.Visit(patient=patient_a,
                               cycles=[cycle],
                               visit_date=t_a)

        dbsession.add_all([schema, visit_a, study])
        dbsession.flush()

        req.json_body = {
            'schema': schema.id,
        }

        with pytest.raises(HTTPBadRequest) as excinfo:
            self._call_fut(visit_a['forms'], req)

        assert 'is not part of the studies' in \
            excinfo.value.json['errors']['schema']
Beispiel #7
0
    def test_add_to_visit(self, req, dbsession):
        from datetime import date
        from occams import models

        schema = models.Schema(name=u'schema',
                               title=u'Schema',
                               publish_date=date.today())

        study = models.Study(name='some-study',
                             title=u'Some Study',
                             short_title=u'sstudy',
                             code=u'000',
                             consent_date=date.today(),
                             schemata=set([schema]))

        cycle = models.Cycle(study=study, name=u'cycle-1', title=u'Cycle')

        site = models.Site(name=u'somewhere', title=u'Somewhere')
        patient = models.Patient(pid=u'12345', site=site)

        visit = models.Visit(patient=patient,
                             visit_date=date.today(),
                             cycles=[cycle])

        dbsession.add_all([study, patient, visit])
        dbsession.flush()

        req.matchdict = {'patient': patient, 'visit': visit}
        req.json_body = {
            'schema': schema.id,
            'collect_date': str(date.today()),
        }
        factory = models.FormFactory(req)
        factory.__parent__ = visit
        self._call_fut(factory, req)

        contexts = dbsession.query(models.Context).all()

        assert len(contexts) == 2
        assert sorted(['patient', 'visit']) == \
            sorted([c.external for c in contexts])
Beispiel #8
0
    def test_update_patient(self, req, dbsession, check_csrf_token):
        """
        It should also mark the patient as modified
        """
        from datetime import date
        from occams import models

        patient = models.Patient(
            site=models.Site(name=u'ucsd', title=u'UCSD'),
            pid=u'12345')

        visit = models.Visit(
            patient=patient,
            visit_date=date.today())

        dbsession.add_all([patient, visit])
        dbsession.flush()

        old_modify_date = patient.modify_date
        self._call_fut(visit, req)
        assert old_modify_date < patient.modify_date
Beispiel #9
0
    def test_has_visits(self, req, dbsession, config):
        """
        It should not allow deletion of a cycle if it has visit
        (unless administrator)
        """
        from datetime import date
        from pyramid.httpexceptions import HTTPForbidden
        from occams import models

        cycle = models.Cycle(name='week-1', title=u'Week 1', week=1)

        study = models.Study(name=u'somestudy',
                             title=u'Some Study',
                             short_title=u'sstudy',
                             code=u'000',
                             consent_date=date.today(),
                             cycles=[cycle])

        patient = models.Patient(site=models.Site(name='ucsd', title=u'UCSD'),
                                 pid=u'12345')

        enrollment = models.Enrollment(study=study,
                                       consent_date=date.today(),
                                       patient=patient)

        visit = models.Visit(patient=patient,
                             visit_date=date.today(),
                             cycles=[cycle])

        dbsession.add_all([study, enrollment, visit])
        dbsession.flush()

        # Should not be able to delete if not an admin
        config.testing_securitypolicy(permissive=False)
        with pytest.raises(HTTPForbidden):
            self._call_fut(cycle, req)

        config.testing_securitypolicy(permissive=True)
        self._call_fut(cycle, req)
        assert 0 == study.cycles.count()
Beispiel #10
0
    def test_visit(self, dbsession):
        """
        It should add visit-specific metadata to the report
        """
        from datetime import date, timedelta
        from occams import models as datastore
        from occams import models
        from occams.exports.schema import SchemaPlan

        schema = datastore.Schema(name=u'vitals',
                                  title=u'Vitals',
                                  publish_date=date.today(),
                                  attributes={
                                      'foo':
                                      datastore.Attribute(
                                          name='foo',
                                          title=u'',
                                          type='string',
                                          order=0,
                                      )
                                  })
        entity = datastore.Entity(collect_date=date.today(), schema=schema)
        patient = models.Patient(site=models.Site(name='ucsd', title=u'UCSD'),
                                 pid=u'12345',
                                 entities=[entity])
        visit = models.Visit(
            visit_date=date.today(),
            patient=patient,
            cycles=[
                models.Cycle(name=u'study1-scr',
                             title=u'Study 1 Screening',
                             week=123,
                             study=models.Study(name=u'study1',
                                                short_title=u'S1',
                                                code=u'001',
                                                consent_date=date.today() -
                                                timedelta(365),
                                                title=u'Study 1')),
                models.Cycle(name=u'study2-wk1',
                             title=u'Study 2 Week 1',
                             week=5858,
                             study=models.Study(name=u'study21',
                                                short_title=u'S2',
                                                code=u'002',
                                                consent_date=date.today() -
                                                timedelta(365),
                                                title=u'Study 2'))
            ],
            entities=[entity])
        dbsession.add_all([schema, entity, patient, visit])
        dbsession.flush()

        plan = SchemaPlan.from_schema(dbsession, schema.name)
        codebook = list(plan.codebook())
        query = plan.data()
        codebook_columns = [c['field'] for c in codebook]
        data_columns = [c['name'] for c in query.column_descriptions]
        record = query.one()
        assert sorted(codebook_columns) == sorted(data_columns)
        assert record.site == patient.site.name
        assert record.pid == patient.pid
        assert record.enrollment is None
        cyclefmt = '{cycle.study.title}({cycle.week})'
        assert sorted(record.visit_cycles.split(';')) == \
            sorted([cyclefmt.format(cycle=c) for c in visit.cycles])
        assert str(record.visit_id) == str(visit.id)
        assert record.collect_date == entity.collect_date