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