예제 #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])
예제 #2
0
def test_entity_force_date(dbsession):
    """
    It should maintain a date object for date types.
    (Sometimes applications will blindly assign datetimes...)
    """
    from datetime import date, datetime
    from occams import models

    schema = models.Schema(name=u'Foo',
                           title=u'',
                           publish_date=date(2000, 1, 1))
    s1 = models.Attribute(schema=schema,
                          name='s1',
                          title=u'Section 1',
                          type='section',
                          order=0)
    entity = models.Entity(schema=schema)

    # Do simple values
    simpleName = 'choicesimple'
    schema.attributes[simpleName] = models.Attribute(schema=schema,
                                                     parent_attribute=s1,
                                                     title=u'',
                                                     type='date',
                                                     is_required=False,
                                                     order=1)

    now = datetime.now()
    today = now.date()

    entity[simpleName] = now
    dbsession.flush()
    assert isinstance(entity[simpleName], date)
    assert today == entity[simpleName]
예제 #3
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()
예제 #4
0
def test_entity_add_unpublished_schema(dbsession):
    """
    It should not allow adding entities related to unpublished schemata
    """
    from occams import models
    from occams.exc import InvalidEntitySchemaError

    schema = models.Schema(name=u'Foo', title=u'')
    entity = models.Entity(schema=schema)
    dbsession.add(entity)
    with pytest.raises(InvalidEntitySchemaError):
        dbsession.flush()
예제 #5
0
def test_choice_constraint(dbsession):
    """
    It should validate against choice constraints
    """
    from datetime import date
    from occams import models
    from occams.exc import ConstraintError

    schema = models.Schema(name=u'Foo',
                           title=u'',
                           publish_date=date(2000, 1, 1))
    s1 = models.Attribute(schema=schema,
                          name='s1',
                          title=u'Section 1',
                          type='section',
                          order=0)
    models.Attribute(schema=schema,
                     parent_attribute=s1,
                     name=u'test',
                     title=u'',
                     type=u'choice',
                     is_required=False,
                     order=0,
                     choices={
                         '001': models.Choice(name=u'001',
                                              title=u'Foo',
                                              order=0),
                         '002': models.Choice(name=u'002',
                                              title=u'Bar',
                                              order=1),
                         '003': models.Choice(name=u'003',
                                              title=u'Baz',
                                              order=2)
                     })
    dbsession.add(schema)
    dbsession.flush()

    entity = models.Entity(schema=schema)
    dbsession.add(entity)

    entity['test'] = None
    entity['test'] = u'002'
    dbsession.flush()

    entry = (dbsession.query(models.ValueChoice).filter(
        models.ValueChoice.value.has(name=u'002')).one())
    assert entry.value.name == '002'

    # Should not be able to set it to something outside of the specified
    # choice constraints

    with pytest.raises(ConstraintError):
        entity['test'] = u'999'
예제 #6
0
    def test_enrollment(self, dbsession):
        """
        It should add enrollment-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'termination',
                                  title=u'Termination',
                                  publish_date=date.today(),
                                  attributes={
                                      'foo':
                                      datastore.Attribute(
                                          name='foo',
                                          title=u'',
                                          type='string',
                                          order=0,
                                      )
                                  })
        entity = datastore.Entity(schema=schema, collect_date=date.today())
        patient = models.Patient(site=models.Site(name='ucsd', title=u'UCSD'),
                                 pid=u'12345',
                                 entities=[entity])
        study = models.Study(name=u'cooties',
                             short_title=u'CTY',
                             code=u'999',
                             consent_date=date.today() - timedelta(365),
                             title=u'Cooties')
        enrollment = models.Enrollment(
            patient=patient,
            study=study,
            consent_date=date.today() - timedelta(5),
            latest_consent_date=date.today() - timedelta(3),
            termination_date=date.today(),
            entities=[entity])
        dbsession.add_all([schema, entity, patient, study, enrollment])

        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 == enrollment.study.name
        assert record.enrollment_ids == str(enrollment.id)
        assert record.visit_cycles is None
        assert record.collect_date == entity.collect_date
예제 #7
0
def test_entity_default_collect_date(dbsession):
    """
    It should default to today's date as the collect_date if not is provided
    """
    from datetime import date
    from occams import models
    # Make sure the system can auto-assign a collect date for the entry

    schema = models.Schema(name=u'Foo',
                           title=u'',
                           publish_date=date(2000, 1, 1))
    entity = models.Entity(schema=schema)
    dbsession.add(entity)
    dbsession.flush()
    assert date.today() == entity.collect_date

    # If one is supplied by the user, don't do anything
    collect_date = date(2010, 9, 1)
    entity = models.Entity(schema=schema, collect_date=collect_date)
    dbsession.add(entity)
    dbsession.flush()
    assert entity.collect_date == collect_date
예제 #8
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)
예제 #9
0
def test_build_report_context(dbsession):
    """
    It should be able to associate with a context. (for easier joins)
    """

    from datetime import date
    from occams import models, reporting

    today = date.today()

    schema1 = models.Schema(name=u'A',
                            title=u'A',
                            publish_date=today,
                            attributes={
                                's1':
                                models.Attribute(name=u's1',
                                                 title=u'S1',
                                                 type='section',
                                                 order=0,
                                                 attributes={
                                                     'a':
                                                     models.Attribute(
                                                         name=u'a',
                                                         title=u'',
                                                         type='string',
                                                         is_private=True,
                                                         order=1)
                                                 })
                            })
    dbsession.add(schema1)
    dbsession.flush()

    entity1 = models.Entity(schema=schema1)
    entity1['a'] = u'002'
    dbsession.add(entity1)
    dbsession.flush()

    dbsession.add(models.Context(external='sometable', key=123,
                                 entity=entity1))
    dbsession.flush()

    # not specified
    report = reporting.build_report(dbsession, u'A')
    assert 'context_key' not in report.c

    # specified
    report = reporting.build_report(dbsession, u'A', context='sometable')
    result = dbsession.query(report).one()
    assert 'context_key' in report.c
    assert result.context_key == 123
예제 #10
0
def test_build_report_ignore_private(dbsession):
    """
    It should be able to de-identify private data upon request
    """

    from datetime import date
    from occams import models, reporting

    today = date.today()

    schema1 = models.Schema(name=u'A',
                            title=u'A',
                            publish_date=today,
                            attributes={
                                's1':
                                models.Attribute(name=u's1',
                                                 title=u'S1',
                                                 type='section',
                                                 order=0,
                                                 attributes={
                                                     'name':
                                                     models.Attribute(
                                                         name=u'name',
                                                         title=u'',
                                                         type='string',
                                                         is_private=True,
                                                         order=1)
                                                 })
                            })

    dbsession.add(schema1)
    dbsession.flush()

    # add some entries for the schema
    entity1 = models.Entity(schema=schema1)
    entity1['name'] = u'Jane Doe'
    dbsession.add(entity1)
    dbsession.flush()

    # not de-identified
    report = reporting.build_report(dbsession, u'A', ignore_private=False)
    result = dbsession.query(report).one()
    assert entity1[u'name'] == result.name

    # de-identified
    report = reporting.build_report(dbsession, u'A', ignore_private=True)
    result = dbsession.query(report).one()
    assert '[PRIVATE]' == result.name
예제 #11
0
def check_value_min_constraint(dbsession, type_, limit, below, equal, over):
    """
    It should validate against minimum constratins
    """
    from datetime import date
    from occams import models
    from occams.exc import ConstraintError

    schema = models.Schema(name=u'Foo',
                           title=u'',
                           publish_date=date(2000, 1, 1))
    s1 = models.Attribute(schema=schema,
                          name='s1',
                          title=u'Section 1',
                          type='section',
                          order=0)
    entity = models.Entity(schema=schema)
    dbsession.add(entity)
    dbsession.flush()

    models.Attribute(schema=schema,
                     parent_attribute=s1,
                     name=type_,
                     title=u'',
                     type=type_,
                     is_required=False,
                     value_min=limit,
                     order=0)

    with pytest.raises(ConstraintError):
        entity[type_] = below

    entity[type_] = None
    entity[type_] = equal
    entity[type_] = over

    models.Attribute(schema=schema,
                     parent_attribute=s1,
                     name=u'boolean',
                     title=u'',
                     type=u'boolean',
                     value_min=10,
                     order=1)

    with pytest.raises(NotImplementedError):
        entity['boolean'] = True
예제 #12
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]))

            state = (dbsession.query(
                models.State).filter_by(name=u'pending-entry').one())

            dbsession.add(
                models.Entity(state=state,
                              schema=form,
                              collect_date=date(2015, 2, 1)))

            dbsession.add(
                models.Enrollment(patient=patient,
                                  study=study,
                                  consent_date=date(2014, 12, 22)))
예제 #13
0
def test_build_report_datetime(dbsession):
    """
    It should be able to cast DATE/DATETIME
    """
    from datetime import date
    from occams import models, reporting

    today = date.today()

    schema1 = models.Schema(name=u'A',
                            title=u'A',
                            publish_date=today,
                            attributes={
                                's1':
                                models.Attribute(name=u's1',
                                                 title=u'S1',
                                                 type='section',
                                                 order=0,
                                                 attributes={
                                                     'a':
                                                     models.Attribute(
                                                         name=u'a',
                                                         title=u'',
                                                         type='date',
                                                         order=1)
                                                 })
                            })
    dbsession.add(schema1)
    dbsession.flush()

    # add some entries for the schema
    entity1 = models.Entity(schema=schema1)
    entity1['a'] = date(1976, 7, 4)
    dbsession.add(entity1)
    dbsession.flush()

    report = reporting.build_report(dbsession, u'A')
    result = dbsession.query(report).one()
    assert str(result.a) == '1976-07-04'

    schema1.attributes['s1'].attributes['a'].type = 'datetime'
    dbsession.flush()
    report = reporting.build_report(dbsession, u'A')
    result = dbsession.query(report).one()
    assert str(result.a) == '1976-07-04 00:00:00'
예제 #14
0
def test_entity_blob_type(dbsession):
    """
    It should be able to keep track of file uploads (will not be storing in DB)
    """

    from occams import models
    from datetime import date

    schema = models.Schema(name='HasBlob',
                           title=u'',
                           publish_date=date(2000, 1, 1))
    s1 = models.Attribute(schema=schema,
                          name='s1',
                          title=u'Section 1',
                          type='section',
                          order=0)
    schema.attributes['theblob'] = models.Attribute(parent_attribute=s1,
                                                    name=u'theblob',
                                                    title=u'',
                                                    type='blob',
                                                    order=0)

    entity = models.Entity(schema=schema)
    dbsession.add(entity)
    dbsession.flush()
    entity_id = entity.id

    # Add value
    entity['theblob'] = models.BlobInfo(file_name=u'foo', path='bar/baz.gif')
    dbsession.add(entity)
    dbsession.flush()
    entity = dbsession.query(models.Entity).get(entity_id)
    blob = entity['theblob']
    assert u'foo' == blob.file_name
    assert 'bar/baz.gif' == blob.path

    # Clear value
    entity['theblob'] = None
    dbsession.flush()
    entity = dbsession.query(models.Entity).get(entity_id)
    blob = entity['theblob']
    assert blob is None
예제 #15
0
    def test_list_not_include_rand(self, dbsession):
        """
        It should not include randomization data if specified.
        """
        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)
        study = models.Study(name=u'study1',
                             short_title=u'S1',
                             code=u'001',
                             consent_date=date.today() - timedelta(365),
                             title=u'Study 1')
        armga = models.Arm(name=u'groupa', title=u'GROUP A', study=study)
        stratum = models.Stratum(study=study,
                                 arm=armga,
                                 block_number=12384,
                                 randid=u'8484',
                                 entities=[entity])
        dbsession.add_all([schema, entity, stratum])
        dbsession.flush()

        plans = SchemaPlan.list_all(dbsession, include_private=True)
        assert len(plans) == 1

        plans = SchemaPlan.list_all(dbsession, include_rand=False)
        assert len(plans) == 0
예제 #16
0
    def test_patient(self, dbsession):
        """
        It should add patient-specific metadata to the report
        """
        from datetime import date
        from occams import models as datastore
        from occams import models
        from occams.exports.schema import SchemaPlan

        schema = datastore.Schema(name=u'contact',
                                  title=u'Contact Details',
                                  publish_date=date.today(),
                                  attributes={
                                      'foo':
                                      datastore.Attribute(
                                          name='foo',
                                          title=u'',
                                          type='string',
                                          order=0,
                                      )
                                  })
        entity = datastore.Entity(schema=schema, collect_date=date.today())
        patient = models.Patient(site=models.Site(name='ucsd', title=u'UCSD'),
                                 pid=u'12345',
                                 entities=[entity])
        dbsession.add_all([schema, entity, patient])
        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
        assert record.visit_cycles is None
        assert record.visit_date is None
        assert record.collect_date == entity.collect_date
예제 #17
0
def test_build_report_scalar_values(dbsession):
    """
    It should properly report scalar values
    """

    from datetime import date
    from occams import models, reporting

    today = date.today()

    schema1 = models.Schema(name=u'A',
                            title=u'A',
                            publish_date=today,
                            attributes={
                                's1':
                                models.Attribute(name=u's1',
                                                 title=u'S1',
                                                 type='section',
                                                 order=0,
                                                 attributes={
                                                     'a':
                                                     models.Attribute(
                                                         name=u'a',
                                                         title=u'',
                                                         type='string',
                                                         order=1)
                                                 })
                            })

    dbsession.add(schema1)
    dbsession.flush()

    # add some entries for the schema
    entity1 = models.Entity(schema=schema1)
    entity1['a'] = u'foovalue'
    dbsession.add(entity1)
    dbsession.flush()

    report = reporting.build_report(dbsession, u'A')
    result = dbsession.query(report).one()
    assert entity1[u'a'] == result.a
예제 #18
0
    def test_without_state(self, req, dbsession):
        """
        It should generate none if no state data is available
        """
        import mock
        from occams import models
        from datetime import date

        myfirst = models.Schema(name=u'myfirst',
                                title=u'My First Schema',
                                publish_date=date.today())
        mydata = models.Entity(schema=myfirst)
        dbsession.add(mydata)
        dbsession.flush()
        mydata.__parent__ = mock.MagicMock()
        mydata.__parent__.__parent__ = mock.MagicMock()

        req.session.changed = mock.Mock()
        res = self._call_fut(mydata, req)

        assert res['state'] is None
예제 #19
0
def test_validator_pattern_constraint(dbsession):
    """
    It should validate against string pattern constraints
    """
    from datetime import date
    from occams import models
    from occams.exc import ConstraintError

    schema = models.Schema(name=u'Foo',
                           title=u'',
                           publish_date=date(2000, 1, 1))
    s1 = models.Attribute(schema=schema,
                          name='s1',
                          title=u'Section 1',
                          type='section',
                          order=0)
    models.Attribute(
        schema=schema,
        parent_attribute=s1,
        name=u'test',
        title=u'',
        type=u'string',
        is_required=False,
        # Valid US phone number
        pattern=r'\d{3}-\d{3}-\d{4}',
        order=0)
    dbsession.add(schema)
    dbsession.flush()

    entity = models.Entity(schema=schema)
    dbsession.add(entity)

    entity['test'] = None

    with pytest.raises(ConstraintError):
        entity['test'] = u'trollol'

    entity['test'] = u'123-456-7890'
    dbsession.flush()
    assert '123-456-7890' == entity['test']
예제 #20
0
def test_validator_max_constraint(dbsession):
    """
    It should validate string/number value min/max
    """
    from datetime import date
    from occams import models
    from occams.exc import ConstraintError

    schema = models.Schema(name=u'Foo',
                           title=u'',
                           publish_date=date(2000, 1, 1))
    s1 = models.Attribute(schema=schema,
                          name='s1',
                          title=u'Section 1',
                          type='section',
                          order=0)
    models.Attribute(schema=schema,
                     parent_attribute=s1,
                     name=u'test',
                     title=u'',
                     type=u'string',
                     is_required=False,
                     value_max=3,
                     order=0)
    dbsession.add(schema)
    dbsession.flush()

    entity = models.Entity(schema=schema)
    dbsession.add(entity)

    entity['test'] = None

    with pytest.raises(ConstraintError):
        entity['test'] = u'foobar'

    entity['test'] = u'foo'
    dbsession.flush()
    assert 'foo' == entity['test']
예제 #21
0
    def test_with_state(self, req, dbsession):
        """
        It should generate state data is available
        """
        from datetime import date
        import mock
        from occams import models

        myfirst = models.Schema(name=u'myfirst',
                                title=u'My First Schema',
                                publish_date=date.today())
        mydata = models.Entity(schema=myfirst,
                               state=(dbsession.query(models.State).filter_by(
                                   name=u'pending-entry').one()))
        dbsession.add(mydata)
        dbsession.flush()
        mydata.__parent__ = mock.MagicMock()
        mydata.__parent__.__parent__ = mock.MagicMock()

        req.session.changed = mock.Mock()
        res = self._call_fut(mydata, req)

        assert res['state'] is not None
예제 #22
0
def test_state_entity_relationship(dbsession):
    """
    It should implement state/entity relationship
    """
    from datetime import date
    from occams import models

    schema = models.Schema(name=u'Foo',
                           title=u'Foo',
                           publish_date=date(2000, 1, 1))
    pending_entry = \
        dbsession.query(models.State).filter_by(name=u'pending-entry').one()
    entity = models.Entity(schema=schema)
    dbsession.add_all([pending_entry, entity])
    dbsession.flush()

    assert entity.state is None
    assert pending_entry.entities.count() == 0

    entity.state = pending_entry
    dbsession.flush()

    assert entity.state is not None
    assert pending_entry.entities.count() == 1
예제 #23
0
    def test_cascade_entities(self, req, dbsession, check_csrf_token):
        """
        It should delete associated entities
        """

        from datetime import date
        from occams import models as datastore
        from occams import models

        schema = datastore.Schema(name=u'somepatientform',
                                  title=u'Some Patient Form',
                                  publish_date=date.today())
        entity = datastore.Entity(collect_date=date.today(), schema=schema)
        patient = models.Patient(site=models.Site(name=u'la', title=u'LA'),
                                 pid=u'12345')
        patient.entities.add(entity)
        dbsession.add_all([patient, entity, schema])
        dbsession.flush()

        patient = dbsession.query(models.Patient).one()

        self._call_fut(patient, req)

        assert 0 == dbsession.query(datastore.Entity).count()
예제 #24
0
def test_entity_choices(dbsession):
    """
    It should properly handle choices
    """
    from datetime import date
    from occams import models

    schema = models.Schema(name=u'Foo',
                           title=u'',
                           publish_date=date(2000, 1, 1))
    s1 = models.Attribute(schema=schema,
                          name='s1',
                          title=u'Section 1',
                          type='section',
                          order=0)
    entity = models.Entity(schema=schema)
    dbsession.add(entity)
    dbsession.flush()

    # Do simple values
    simpleName = 'choicesimple'
    schema.attributes[simpleName] = models.Attribute(
        schema=schema,
        parent_attribute=s1,
        name=simpleName,
        title=u'',
        type='choice',
        is_required=False,
        order=1,
        choices={
            '001': models.Choice(name=u'001', title=u'Foo', order=1),
            '002': models.Choice(name=u'002', title=u'Bar', order=2),
            '003': models.Choice(name=u'003', title=u'Baz', order=3),
            '004': models.Choice(name=u'004', title=u'Caz', order=4),
            '005': models.Choice(name=u'005', title=u'Jaz', order=5),
        })
    entity[simpleName] = None
    dbsession.flush()
    assert entity[simpleName] is None

    entity[simpleName] = u'002'
    dbsession.flush()
    assert u'002' == entity[simpleName]

    # Now try collections
    collectionName = 'choicecollection'
    schema.attributes[collectionName] = models.Attribute(
        schema=schema,
        parent_attribute=s1,
        name=collectionName,
        title=u'',
        type='choice',
        is_collection=True,
        order=2,
        choices={
            '001': models.Choice(name=u'001', title=u'Foo', order=1),
            '002': models.Choice(name=u'002', title=u'Bar', order=2),
            '003': models.Choice(name=u'003', title=u'Baz', order=3),
            '004': models.Choice(name=u'004', title=u'Caz', order=4),
            '005': models.Choice(name=u'005', title=u'Jaz', order=5)
        })
    entity[collectionName] = [u'001', u'002', u'005']
    dbsession.flush()
    assert sorted([u'001', u'002', u'005']) == \
        sorted(entity['choicecollection'])
예제 #25
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
예제 #26
0
    def test_rand(self, dbsession):
        """
        It should add randomization-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])
        study = models.Study(name=u'study1',
                             short_title=u'S1',
                             code=u'001',
                             consent_date=date.today() - timedelta(365),
                             title=u'Study 1')
        armga = models.Arm(name=u'groupa', title=u'GROUP A', study=study)
        stratum = models.Stratum(study=study,
                                 arm=armga,
                                 block_number=12384,
                                 randid=u'8484',
                                 patient=patient,
                                 entities=[entity])
        enrollment = models.Enrollment(
            patient=patient,
            study=study,
            consent_date=date.today() - timedelta(5),
            latest_consent_date=date.today() - timedelta(3),
            termination_date=date.today(),
            entities=[entity])
        dbsession.add_all([schema, entity, patient, enrollment, stratum])
        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 == enrollment.study.name
        assert record.enrollment_ids == str(enrollment.id)
        assert record.collect_date == entity.collect_date
        assert record.block_number == stratum.block_number
        assert record.arm_name == stratum.arm.title
        assert record.randid == stratum.randid
예제 #27
0
def test_build_report_choice_types(dbsession):
    """
    It should be able to use choice labels instead of codes.
    (for human readibily)
    """

    from datetime import date
    from occams import models, reporting

    today = date.today()

    schema1 = models.Schema(name=u'A',
                            title=u'A',
                            publish_date=today,
                            attributes={
                                's1':
                                models.Attribute(
                                    name=u's1',
                                    title=u'S1',
                                    type='section',
                                    order=0,
                                    attributes={
                                        'a':
                                        models.Attribute(
                                            name=u'a',
                                            title=u'',
                                            type='choice',
                                            is_collection=False,
                                            order=0,
                                            choices={
                                                '001':
                                                models.Choice(name=u'001',
                                                              title=u'Green',
                                                              order=0),
                                                '002':
                                                models.Choice(name=u'002',
                                                              title=u'Red',
                                                              order=1),
                                                '003':
                                                models.Choice(name=u'003',
                                                              title=u'Blue',
                                                              order=2)
                                            })
                                    })
                            })
    dbsession.add(schema1)
    dbsession.flush()

    entity1 = models.Entity(schema=schema1)
    entity1['a'] = u'002'
    dbsession.add(entity1)
    dbsession.flush()

    # labels off
    report = reporting.build_report(dbsession, u'A', use_choice_labels=False)
    result = dbsession.query(report).one()
    assert result.a == '002'

    # labels on
    report = reporting.build_report(dbsession, u'A', use_choice_labels=True)
    result = dbsession.query(report).one()
    assert result.a == 'Red'

    # switch to multiple-choice
    schema1.attributes['a'].is_collection = True
    entity1['a'] = ['002', '003']
    dbsession.flush()

    # delimited multiple-choice, labels off
    report = reporting.build_report(dbsession,
                                    u'A',
                                    expand_collections=False,
                                    use_choice_labels=False)
    result = dbsession.query(report).one()
    assert sorted(result.a.split(';')) == sorted(['002', '003'])

    # delimited multiple-choice, labels on
    report = reporting.build_report(dbsession,
                                    u'A',
                                    expand_collections=False,
                                    use_choice_labels=True)
    result = dbsession.query(report).one()
    assert sorted(result.a.split(';')) == sorted(['Red', 'Blue'])

    # expanded multiple-choice, labels off
    report = reporting.build_report(dbsession,
                                    u'A',
                                    expand_collections=True,
                                    use_choice_labels=False)
    result = dbsession.query(report).one()
    assert result.a_001 == 0
    assert result.a_002 == 1
    assert result.a_003 == 1

    # expanded multiple-choice, labels on
    report = reporting.build_report(dbsession,
                                    u'A',
                                    expand_collections=True,
                                    use_choice_labels=True)
    result = dbsession.query(report).one()
    assert result.a_001 is None
    assert result.a_002 == 'Red'
    assert result.a_003 == 'Blue'
예제 #28
0
def test_build_report_expand_none_selected(dbsession):
    """
    It should leave all choices blank (not zero) on if no option was selected
    """
    from datetime import date
    from occams import models, reporting

    today = date.today()

    schema1 = models.Schema(name=u'A',
                            title=u'A',
                            publish_date=today,
                            attributes={
                                's1':
                                models.Attribute(
                                    name=u's1',
                                    title=u'S1',
                                    type='section',
                                    order=0,
                                    attributes={
                                        'a':
                                        models.Attribute(
                                            name=u'a',
                                            title=u'',
                                            type='choice',
                                            is_collection=True,
                                            order=1,
                                            choices={
                                                '001':
                                                models.Choice(name=u'001',
                                                              title=u'Green',
                                                              order=0),
                                                '002':
                                                models.Choice(name=u'002',
                                                              title=u'Red',
                                                              order=1),
                                                '003':
                                                models.Choice(name=u'003',
                                                              title=u'Blue',
                                                              order=2)
                                            })
                                    })
                            })
    dbsession.add(schema1)
    dbsession.flush()

    entity1 = models.Entity(schema=schema1)
    dbsession.add(entity1)
    dbsession.flush()

    # delimited multiple-choice, labels off
    report = reporting.build_report(dbsession,
                                    u'A',
                                    expand_collections=False,
                                    use_choice_labels=False)
    result = dbsession.query(report).one()
    assert result.a is None

    # delimited multiple-choice, labels on
    report = reporting.build_report(dbsession,
                                    u'A',
                                    expand_collections=False,
                                    use_choice_labels=True)
    result = dbsession.query(report).one()
    assert result.a is None

    # expanded multiple-choice, labels off
    report = reporting.build_report(dbsession,
                                    u'A',
                                    expand_collections=True,
                                    use_choice_labels=False)
    result = dbsession.query(report).one()
    assert result.a_001 is None
    assert result.a_002 is None
    assert result.a_003 is None

    # expanded multiple-choice, labels on
    report = reporting.build_report(dbsession,
                                    u'A',
                                    expand_collections=True,
                                    use_choice_labels=True)
    result = dbsession.query(report).one()
    assert result.a_001 is None
    assert result.a_002 is None
    assert result.a_003 is None
예제 #29
0
def check_entity_types(dbsession, type, simple, update, collection):
    """
    It should properly handle supported types
    """
    from datetime import date
    from occams import models

    schema = models.Schema(name=u'Foo',
                           title=u'',
                           publish_date=date(2000, 1, 1),
                           attributes={
                               's1':
                               models.Attribute(name='s1',
                                                title=u'Section 1',
                                                type='section',
                                                order=1)
                           })
    entity = models.Entity(schema=schema)
    dbsession.add(entity)
    dbsession.flush()

    order = 1

    ModelClass = models.nameModelMap[type]

    # Do simple values
    simpleName = type + 'simple'

    # Try null first
    schema.attributes['s1'].attributes[simpleName] = models.Attribute(
        name=simpleName, title=u'', type=type, is_required=False, order=order)
    assert entity[simpleName] is None
    entity[simpleName] = None
    dbsession.flush()
    assert entity[simpleName] is None

    # Update value
    entity[simpleName] = simple
    dbsession.flush()
    assert simple == entity[simpleName]

    # Double check auditing
    valueQuery = (dbsession.query(ModelClass).filter_by(
        attribute=schema.attributes[simpleName]))
    valueObject = valueQuery.one()
    assert 1 == valueObject.revision

    # Update again
    entity[simpleName] = update
    dbsession.flush()
    assert update == entity[simpleName]

    # Triple check auditing
    valueObject = valueQuery.one()
    assert 2 == valueObject.revision

    order += 1

    # Now try collections
    collectionName = type + 'collection'
    schema.attributes['s1'].attributes[collectionName] = models.Attribute(
        name=collectionName,
        schema=schema,
        title=u'',
        type=type,
        is_collection=True,
        order=order)
    entity[collectionName] = collection
    dbsession.flush()
    assert set(collection) == set(entity[collectionName])

    valueQuery = (dbsession.query(ModelClass).filter_by(
        attribute=schema.attributes[collectionName]))

    order += 1

    # Make sure we can also update
    entity[collectionName] = collection[:2]
    dbsession.flush()
    assert set(collection[:2]) == set(entity[collectionName])
    assert 2 == valueQuery.count()

    # Lists are not audited, they're just removed and a new one is
    # set
    assert sorted([1, 1]) == sorted([v.revision for v in valueQuery])