コード例 #1
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')

            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',
            )

            dbsession.add(
                models.Enrollment(patient=patient,
                                  study=study,
                                  consent_date=date(2014, 12, 22)))
コード例 #2
0
    def test_delete(self, req, dbsession, config, check_csrf_token):
        """
        It should allow the owner of the export to cancel/delete the export
        """
        import mock
        from pyramid.httpexceptions import HTTPOk
        from occams import models

        blame = models.User(key=u'joe')
        dbsession.add(blame)
        dbsession.flush()
        dbsession.info['blame'] = blame

        export = models.Export(
            owner_user=(
                dbsession.query(models.User)
                .filter_by(key='joe')
                .one()),
            contents=[],
            status='complete')
        dbsession.add(export)
        dbsession.flush()
        export_id = export.id
        export_name = export.name
        dbsession.expunge_all()

        config.testing_securitypolicy(userid='joe')
        with mock.patch('occams.tasks.app.control.revoke') as revoke:
            res = self._call_fut(export, req)
        check_csrf_token.assert_called_with(req)
        assert isinstance(res, HTTPOk)
        assert dbsession.query(models.Export).get(export_id) is None
        revoke.assert_called_with(export_name)
コード例 #3
0
def dbsession(config):
    """
    (Integartion Testing) Instantiates a database session.

    :param config: The pyramid testing configuartion

    :returns: An instantiated sqalchemy database session
    """
    from occams import models
    import occams.models.events
    import zope.sqlalchemy

    dbsession = config.registry['dbsession_factory']()

    occams.models.events.register(dbsession)
    zope.sqlalchemy.register(dbsession)

    # Pre-configure with a blame user
    blame = models.User(key=USERID)
    dbsession.add(blame)
    dbsession.flush()
    dbsession.info['blame'] = blame

    # Other expected settings
    dbsession.info['settings'] = config.registry.settings

    # Hardcoded workflow
    dbsession.add_all([
        models.State(name=u'pending-entry', title=u'Pending Entry'),
        models.State(name=u'pending-review', title=u'Pending Review'),
        models.State(name=u'pending-correction', title=u'Pending Correction'),
        models.State(name=u'complete', title=u'Complete')
    ])

    return dbsession
コード例 #4
0
ファイル: test_export.py プロジェクト: stevenweaver/occams
 def test_not_owner(self, app, dbsession):
     import transaction
     from occams import models
     with transaction.manager:
         dbsession.add(models.User(key='somebody_else'))
     environ = make_environ(userid='somebody_else')
     app.get(self.url, extra_environ=environ, status=403)
コード例 #5
0
ファイル: test_patient.py プロジェクト: stevenweaver/occams
    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())

            dbsession.add(
                models.Site(name=u'UCLA',
                            title=u'UCLA',
                            description=u'UCLA Campus',
                            create_date=date.today()))

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

            dbsession.flush()
コード例 #6
0
    def test_get_not_found_status(self, req, dbsession, status):
        """
        It should return 404 if the record is not ready
        """
        from pyramid.httpexceptions import HTTPBadRequest
        from occams import models

        blame = models.User(key=u'joe')
        dbsession.add(blame)
        dbsession.flush()
        dbsession.info['blame'] = blame

        export = models.Export(
            id=123,
            owner_user=(
                dbsession.query(models.User)
                .filter_by(key='joe')
                .one()),
            contents=[],
            status=status)
        dbsession.add(export)
        dbsession.flush()

        with pytest.raises(HTTPBadRequest):
            self._call_fut(export, req)
コード例 #7
0
ファイル: test_tasks.py プロジェクト: stevenweaver/occams
    def test_zip(self):
        """
        It should generate a zip file containing the specified contents
        """
        from zipfile import ZipFile
        from occams.celery import Session
        from occams import models as datastore
        from occams import models, tasks
        from occams.exports.pid import PidPlan

        owner = datastore.User(key=u'joe')
        Session.info['blame'] = owner
        Session.add(owner)
        Session.flush()

        export = models.Export(owner_user=owner,
                               contents=[{
                                   'name': 'pid',
                                   'title': 'PID',
                                   'versions': []
                               }],
                               status='complete')
        Session.add(export)
        Session.flush()

        tasks.app.settings['studies.export.plans'] = [PidPlan]
        tasks.make_export(export.name)

        # @in_transaction removes the session metadata, so we gotta do this
        export = Session.merge(export)
        with ZipFile(export.path, 'r') as zfp:
            file_names = zfp.namelist()

        assert sorted(['pid.csv', 'codebook.csv']) == sorted(file_names)
コード例 #8
0
ファイル: test_export.py プロジェクト: stevenweaver/occams
    def populate(self, app, dbsession):
        import transaction
        from occams import models

        # Any view-dependent data goes here
        # Webtests will use a different scope for its transaction
        with transaction.manager:
            dbsession.add(models.User(key=USERID))
コード例 #9
0
ファイル: test_export.py プロジェクト: stevenweaver/occams
 def test_not_owner(self, app, dbsession):
     import transaction
     from occams import models
     with transaction.manager:
         dbsession.add(models.User(key='somebody_else'))
     environ = make_environ(userid='somebody_else')
     csrf_token = get_csrf_token(app, environ)
     app.delete(self.url,
                extra_environ=environ,
                headers={'X-CSRF-Token': csrf_token},
                xhr=True,
                status=403)
コード例 #10
0
    def test_get_current_user(self, req, dbsession, config):
        """
        It should return the authenticated user's exports
        """
        import mock
        from occams import models

        req.registry.settings['studies.export.dir'] = '/tmp'

        blame = models.User(key=u'joe')
        dbsession.add(blame)
        dbsession.add(models.User(key='jane'))
        dbsession.flush()
        dbsession.info['blame'] = blame

        export1 = models.Export(
            owner_user=(
                dbsession.query(models.User)
                .filter_by(key='joe')
                .one()),
            contents=[],
            status='pending')
        export2 = models.Export(
            owner_user=(
                dbsession.query(models.User)
                .filter_by(key='jane')
                .one()),
            contents=[],
            status='pending')
        dbsession.add_all([export1, export2])
        dbsession.flush()

        config.testing_securitypolicy(userid='joe')
        req.redis = mock.Mock()
        context = models.ExportFactory(req)
        export1.__parent__ = context
        export2.__parent__ = context
        res = self._call_fut(models.ExportFactory(req), req)
        exports = res['exports']
        assert len(exports) == 1
コード例 #11
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)
コード例 #12
0
ファイル: test_export.py プロジェクト: stevenweaver/occams
    def populate(self, app, dbsession):
        import transaction
        from occams import models

        # 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)
            export = models.Export(owner_user=user)
            dbsession.add(export)
            dbsession.flush()
            self.url = self.url_fmt.format(export=export.id)
コード例 #13
0
ファイル: test_site.py プロジェクト: stevenweaver/occams
    def populate(self, app, dbsession):
        import transaction
        from occams import models

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

            dbsession.add(models.Site(name=u'ucsd', title=u'UCSD'))
            dbsession.add(models.Site(name=u'ucla', title=u'UCSD'))
コード例 #14
0
def app(request, wsgi, dbsession):
    """
    (Functional Testing) Initiates a user request against a WSGI stack

    :param request: The pytest context
    :param wsgi: An initialized WSGI stack
    :param dbsession: A database session for seting up pre-existing data

    :returns: a test app request against the WSGI instance
    """
    import transaction
    from webtest import TestApp
    from zope.sqlalchemy import mark_changed
    from occams import models as models

    # Save all changes up tho this point (dbsession does some configuration)
    with transaction.manager:
        blame = models.User(key='workflow@localhost')
        dbsession.add(blame)
        dbsession.flush()
        dbsession.info['blame'] = blame

        dbsession.add_all([
            models.State(name=u'pending-entry', title=u'Pending Entry'),
            models.State(name=u'pending-review', title=u'Pending Review'),
            models.State(name=u'pending-correction',
                         title=u'Pending Correction'),
            models.State(name=u'complete', title=u'Complete')
        ])

    app = TestApp(wsgi)

    yield app

    with transaction.manager:
        # DELETE is dramatically faster than TRUNCATE
        # http://stackoverflow.com/a/11423886/148781
        # We also have to do this as a raw query becuase SA does
        # not have a way to invoke server-side cascade
        dbsession.execute('DELETE FROM "rostersite" CASCADE')
        dbsession.execute('DELETE FROM "study" CASCADE')
        dbsession.execute('DELETE FROM "patient" CASCADE')
        dbsession.execute('DELETE FROM "site" CASCADE')
        dbsession.execute('DELETE FROM "schema" CASCADE')
        dbsession.execute('DELETE FROM "export" CASCADE')
        dbsession.execute('DELETE FROM "state" CASCADE')
        dbsession.execute('DELETE FROM "user" CASCADE')
        mark_changed(dbsession)
コード例 #15
0
    def test_ignore_expired(self, req, dbsession, config):
        """
        It should not render expired exports.
        """
        from datetime import datetime, timedelta
        import mock
        from occams import models

        EXPIRE_DAYS = 10

        req.registry.settings['studies.export.expire'] = EXPIRE_DAYS
        req.registry.settings['studies.export.dir'] = '/tmp'

        blame = models.User(key=u'joe')
        dbsession.add(blame)
        dbsession.flush()
        dbsession.info['blame'] = blame

        now = datetime.now()

        export = models.Export(
            owner_user=(
                dbsession.query(models.User)
                .filter_by(key='joe')
                .one()),
            contents=[],
            status='pending',
            create_date=now,
            modify_date=now)
        dbsession.add(export)
        dbsession.flush()

        config.testing_securitypolicy(userid='joe')
        req.redis = mock.Mock()
        context = models.ExportFactory(req)
        export.__parent__ = context
        res = self._call_fut(context, req)
        exports = res['exports']
        assert len(exports) == 1

        export.create_date = export.modify_date = \
            now - timedelta(EXPIRE_DAYS + 1)
        dbsession.flush()
        context = models.ExportFactory(req)
        export.__parent__ = context
        res = self._call_fut(context, req)
        exports = res['exports']
        assert len(exports) == 0
コード例 #16
0
ファイル: test_patient.py プロジェクト: stevenweaver/occams
    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)))
コード例 #17
0
ファイル: test_patient.py プロジェクト: stevenweaver/occams
    def populate(self, app, dbsession):
        from datetime import date

        import transaction
        from occams import models

        # 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()
            dbsession.add(
                models.Site(name=u'UCSD',
                            title=u'UCSD',
                            description=u'UCSD Campus',
                            create_date=date.today()))
            dbsession.flush()
コード例 #18
0
ファイル: test_study.py プロジェクト: stevenweaver/occams
    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()
            dbsession.add(
                models.Study(name=u'test',
                             title=u'test',
                             short_title=u'test',
                             code=u'test',
                             consent_date=date.today(),
                             is_randomized=False))
コード例 #19
0
ファイル: test_export.py プロジェクト: stevenweaver/occams
    def populate(self, request, app, dbsession):
        import os
        import transaction
        from occams import models

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

        # XXX: need to somehow get the settings so we can consitently
        #      get the correct directory
        with open('/tmp/codebook.csv', 'w+') as fp:
            self.codebook_file_name = fp.name

        def rm():
            os.unlink(self.codebook_file_name)

        request.addfinalizer(rm)
コード例 #20
0
def celery(request):
    """
    (Function Testing) Sets up a celery application for testing

    :param request: The pytest context
    """
    import shutil
    import tempfile
    import mock
    from redis import StrictRedis
    from sqlalchemy import create_engine
    from occams.celery import Session
    from occams import models as models
    from occams import tasks

    settings = {
        'studies.export.dir': tempfile.mkdtemp(),
        'celery.blame': USERID
    }

    tasks.app.userid = settings['celery.blame']
    tasks.app.redis = StrictRedis.from_url(REDIS_URL)
    tasks.app.settings = settings

    db_url = request.config.getoption('--db')
    engine = create_engine(db_url)
    Session.configure(bind=engine, info={'settings': settings})
    Session.add(models.User(key=settings['celery.blame']))
    Session.flush()

    commitmock = mock.patch('occams.tasks.Session.commit')
    commitmock.start()

    def cleanup():
        commitmock.stop()
        shutil.rmtree(settings['studies.export.dir'])
        Session.remove()

    request.addfinalizer(cleanup)
コード例 #21
0
    def test_exceed_limit(self, req, dbsession, config):
        """
        It should not let the user exceed their allocated export limit
        """
        from datetime import date
        from webob.multidict import MultiDict
        from occams import models
        from occams.exports.schema import SchemaPlan

        config.registry.settings['app.export.limit'] = 0
        req.registry.settings['studies.export.plans'] = [SchemaPlan.list_all]

        blame = models.User(key=u'joe')
        dbsession.add(blame)
        dbsession.flush()
        dbsession.info['blame'] = blame

        previous_export = models.Export(
            owner_user=(
                dbsession.query(models.User)
                .filter_by(key='joe')
                .one()),
            contents=[{
                u'name': u'vitals',
                u'title': u'Vitals',
                u'versions': [str(date.today())]}])
        dbsession.add(previous_export)
        dbsession.flush()

        # The renderer should know about it
        config.testing_securitypolicy(userid='joe')
        res = self._call_fut(models.ExportFactory(req), req)
        assert res['exceeded']

        # If the user insists, they'll get a validation error as well
        config.testing_securitypolicy(userid='joe')
        req.method = 'POST'
        req.POST = MultiDict([('contents', 'vitals')])
        assert res['exceeded']
コード例 #22
0
    def test_valid(self, req, dbsession, config, check_csrf_token):
        """
        It should add an export record and initiate an async task
        """
        from datetime import date
        import mock
        from pyramid.httpexceptions import HTTPFound
        from webob.multidict import MultiDict
        from occams import models
        from occams.exports.schema import SchemaPlan

        req.registry.settings['app.export.dir'] = '/tmp'
        req.registry.settings['studies.export.plans'] = [SchemaPlan.list_all]

        blame = models.User(key=u'joe')
        dbsession.add(blame)
        dbsession.flush()
        dbsession.info['blame'] = blame

        schema = models.Schema(
            name=u'vitals', title=u'Vitals', publish_date=date.today())
        dbsession.add(schema)
        dbsession.flush()

        config.testing_securitypolicy(userid='joe')
        req.method = 'POST'
        req.POST = MultiDict([('contents', str('vitals'))])

        # Don't invoke subtasks
        with mock.patch('occams.tasks.make_export'):
            res = self._call_fut(models.ExportFactory(req), req)

        check_csrf_token.assert_called_with(req)
        assert isinstance(res, HTTPFound)
        assert res.location == req.route_path('studies.exports_status')
        export = dbsession.query(models.Export).one()
        assert export.owner_user.key == 'joe'
コード例 #23
0
ファイル: test_export.py プロジェクト: stevenweaver/occams
    def populate(self, request, dbsession):
        import os
        import transaction
        from occams import models

        # 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)
            export = models.Export(name='myexport',
                                   status='complete',
                                   owner_user=user)
            dbsession.add(export)
            dbsession.flush()
            self.url = self.url_fmt.format(export=export.id)
            with open('/tmp/myexport', 'w+') as fp:
                self.export_file_name = fp.name

        def rm():
            os.unlink(self.export_file_name)

        request.addfinalizer(rm)