コード例 #1
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
コード例 #2
0
    def test_file(self, req, dbsession):
        """
        It should return the json rows for the codebook fragment
        """
        from datetime import date
        from webob.multidict import MultiDict
        from occams import models
        from occams.exports.schema import SchemaPlan

        dbsession.add(models.Schema(
            name=u'aform',
            title=u'',
            publish_date=date.today(),
            attributes={
                u'myfield': models.Attribute(
                    name=u'myfield',
                    title=u'',
                    type=u'string',
                    order=0
                    )
            }
        ))
        dbsession.flush()

        req.GET = MultiDict([('file', 'aform')])
        req.registry.settings['studies.export.plans'] = [SchemaPlan.list_all]
        res = self._call_fut(models.ExportFactory(req), req)
        assert res is not None
コード例 #3
0
 def test_post_empty(self, req, dbsession):
     """
     It should raise validation errors on empty imput
     """
     from webob.multidict import MultiDict
     from occams import models
     from occams.exports.schema import SchemaPlan
     req.registry.settings['studies.export.plans'] = [SchemaPlan.list_all]
     req.method = 'POST'
     req.POST = MultiDict()
     res = self._call_fut(models.ExportFactory(req), req)
     assert res['errors'] is not None
コード例 #4
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
コード例 #5
0
 def test_post_non_existent_schema(self, req, dbsession, config):
     """
     It should raise validation errors for non-existent schemata
     """
     from webob.multidict import MultiDict
     from occams import models
     from occams.exports.schema import SchemaPlan
     config.testing_securitypolicy(userid='tester', permissive=True)
     req.registry.settings['studies.export.plans'] = [SchemaPlan.list_all]
     req.method = 'POST'
     req.POST = MultiDict([('contents', 'does_not_exist')])
     res = self._call_fut(models.ExportFactory(req), req)
     assert 'not a valid choice' in res['errors']['contents']
コード例 #6
0
    def test_get_exportables(self, req, dbsession):
        """
        It should render only published schemata
        """
        from datetime import date
        from occams import models

        # No schemata
        res = self._call_fut(models.ExportFactory(req), req)
        assert len(res['exportables']) == 3  # Only pre-cooked

        # Not-yet-published schemata
        schema = models.Schema(name=u'vitals', title=u'Vitals')
        dbsession.add(schema)
        dbsession.flush()
        res = self._call_fut(models.ExportFactory(req), req)
        assert len(res['exportables']) == 3

        # Published schemata
        schema.publish_date = date.today()
        dbsession.flush()
        res = self._call_fut(models.ExportFactory(req), req)
        assert len(res['exportables']) == 4
コード例 #7
0
 def test_download(self, req, dbsession, config):
     """
     It should allow downloading of entire codebook file
     """
     import os
     from pyramid.response import FileResponse
     from occams.exports.codebook import FILE_NAME
     from occams import models
     req.registry.settings['studies.export.dir'] = '/tmp'
     name = '/tmp/' + FILE_NAME
     with open(name, 'w+b'):
         config.testing_securitypolicy(userid='jane')
         res = self._call_fut(models.ExportFactory(req), req)
         assert isinstance(res, FileResponse)
     os.remove(name)
コード例 #8
0
    def test_file_not_exists(self, req, dbsession):
        """
        It should return 404 if the file does not exist
        """
        from pyramid.httpexceptions import HTTPBadRequest
        from webob.multidict import MultiDict
        import pytest
        from occams import models
        from occams.exports.schema import SchemaPlan

        req.GET = MultiDict([('file', 'i_dont_exist')])
        req.registry.settings['studies.export.plans'] = [SchemaPlan.list_all]

        with pytest.raises(HTTPBadRequest):
            self._call_fut(models.ExportFactory(req), req)
コード例 #9
0
    def test_ignore_nonmessages(self, req, dbsession, config):
        """
        It should not yield other types of pubsub broadcasts
        """
        import mock
        from occams import models

        def listen():
            return [{
                'type': 'misc',
                'data': 'random data'
            }]

        req.redis = mock.Mock(pubsub=lambda: mock.Mock(listen=listen))

        res = self._call_fut(models.ExportFactory(req), req)

        notifications = list(res.app_iter)

        assert not notifications
コード例 #10
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']
コード例 #11
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'
コード例 #12
0
    def test_yield_pubsub_owner_messages(self, req, dbsession, config):
        """
        It should only yield pubsub "message" broadcasts to the owner
        """
        import json
        import mock
        from occams import models

        config.testing_securitypolicy(userid='jane')

        def listen():
            return [{
                'type': 'message',
                'data': json.dumps({'owner_user': '******', 'export_id': 123})
            }]

        req.redis = mock.Mock(pubsub=lambda: mock.Mock(listen=listen))

        res = self._call_fut(models.ExportFactory(req), req)

        notifications = list(res.app_iter)

        assert notifications
        assert '"export_id": 123' in notifications[0]
コード例 #13
0
    def test_ignore_nonowner(self, req, dbsession, config):
        """
        It should not yield pubsub "message" broadcasts if they
        don't belong to the autheticated user.
        """
        import json
        import mock
        from occams import models

        config.testing_securitypolicy(userid='somoneelse')

        def listen():
            return [{
                'type': 'message',
                'data': json.dumps({'owner_user': '******', 'export_id': 123})
            }]

        req.redis = mock.Mock(pubsub=lambda: mock.Mock(listen=listen))

        res = self._call_fut(models.ExportFactory(req), req)

        notifications = list(res.app_iter)

        assert not notifications