def test_init_settings(): settings_dict = { "foo": { "enable_foo": True, "engine": "ADVANCED" }, "bar": { "space": "huge", "security": False }, } class App(morepath.App): pass App.init_settings(settings_dict) morepath.commit(App) app = App() assert app.settings.foo.enable_foo is True assert app.settings.foo.engine == "ADVANCED" assert app.settings.bar.space == "huge" assert app.settings.bar.security is False
def test_init_settings(): settings_dict = { 'foo': { 'enable_foo': True, 'engine': 'ADVANCED' }, 'bar': { 'space': 'huge', 'security': False } } class App(morepath.App): pass App.init_settings(settings_dict) morepath.commit(App) app = App() assert app.settings.foo.enable_foo is True assert app.settings.foo.engine == 'ADVANCED' assert app.settings.bar.space == 'huge' assert app.settings.bar.security is False
def test_app_extends_settings(): class Alpha(morepath.App): pass class Beta(Alpha): pass Alpha.init_settings({"foo": {"enable_foo": True, "engine": "ADVANCED"}}) Beta.init_settings({"bar": {"space": "huge", "security": False}}) morepath.commit(Alpha, Beta) alpha_inst = Alpha() settings = alpha_inst.settings assert settings.foo.engine == "ADVANCED" with pytest.raises(AttributeError): settings.bar.space beta_inst = Beta() settings = beta_inst.settings assert settings.foo.engine == "ADVANCED" assert settings.bar.space == "huge"
def test_extentions_settings(): settings_dict = settings_file.settings class App(morepath.App): pass App.init_settings(settings_dict) morepath.commit(App) app = App() assert app.settings.chameleon.debug is True assert app.settings.jinja2.auto_reload is False assert app.settings.jinja2.autoescape is True assert app.settings.jinja2.extensions == [ 'jinja2.ext.autoescape', 'jinja2.ext.i18n' ] assert app.settings.jwtauth.algorithm == 'ES256' assert app.settings.jwtauth.leeway == 20 assert app.settings.jwtauth.public_key == \ 'MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBWcJwPEAnS/k4kFgUhxNF7J0SQQhZG'\ '+nNgy+/mXwhQ5PZIUmId1a1TjkNXiKzv6DpttBqduHbz/V0EtH+QfWy0B4BhZ5MnT'\ 'yDGjcz1DQqKdexebhzobbhSIZjpYd5aU48o9rXp/OnAnrajddpGsJ0bNf4rtMLBqF'\ 'YJN6LOslAB7xTBRg=' assert app.settings.sqlalchemy.url == 'sqlite:///morepath.db' assert app.settings.transaction.attempts == 2
def test_refresh_with_invalid_token(): class App(morepath.App): pass class Refresh(object): pass @App.path(model=Refresh, path='refresh') def get_refresh(): return Refresh() @App.json(model=Refresh) def refresh(self, request): verify_refresh_request(request) refresh_nonce_handler = 'more.jwtauth.tests.handler.refresh_nonce_handler' @App.setting_section(section="jwtauth") def get_jwtauth_settings(): return { 'master_secret': 'secret', 'allow_refresh': True, 'refresh_delta': 3, 'refresh_nonce_handler': refresh_nonce_handler } token = 'Invalid Token' headers = {'Authorization': 'JWT ' + token} morepath.commit(App) c = Client(App()) with pytest.raises(DecodeError) as excinfo: c.get('/refresh', headers=headers) assert 'Token could not be decoded' in str(excinfo.value)
def setup_module(module): engine = sqlalchemy.create_engine('sqlite:///:memory:') Session.configure(bind=engine) Base.metadata.create_all(engine) morepath.scan(morepath_sqlalchemy) morepath.commit(App)
def test_jwt_forget(): class App(morepath.App): pass @App.path(path='{id}') class Model(object): def __init__(self, id): self.id = id @App.view(model=Model) def default(self, request): # will not actually do anything as it's a no-op for JWT # auth, but at least won't crash response = Response(content_type='text/plain') morepath.forget_identity(response, request, lookup=request.lookup) return response @App.identity_policy() def get_identity_policy(): return JWTIdentityPolicy() morepath.commit(App) c = Client(App()) response = c.get('/foo', status=200) assert response.body == b''
def test_webasset_path(current_path): current_path = os.path.dirname(os.path.realpath(__file__)) class App(WebassetsApp): pass @App.webasset_path() def get_path(): return './fixtures' @App.webasset_path() def get_overlapping_path(): return os.path.join(current_path, './fixtures') @App.webasset_path() def get_current_path(): return '.' @App.webasset_path() def get_parent_path(): return '..' morepath.commit(App) app = App() assert app.config.webasset_registry.paths == [ os.path.normpath(os.path.join(current_path, '..')), os.path.normpath(os.path.join(current_path, '.')), os.path.normpath(os.path.join(current_path, 'fixtures')), os.path.normpath(os.path.join(current_path, 'fixtures')), ]
def test_global_filter_is_only_a_default_with_bundle(tempdir, fixtures_path): class App(WebassetsApp): pass @App.webasset_path() def get_path(): return fixtures_path @App.webasset_output() def get_output_path(): return tempdir @App.webasset('jquery', filters={'js': None}) def get_jquery_asset(): yield 'jquery.js' @App.webasset('common') def get_common_asset(): yield 'jquery' @App.webasset_filter('js') def get_js_filter(): return 'rjsmin' morepath.commit(App) bundles = list(App().config.webasset_registry.get_bundles('common')) assert len(bundles) == 1 assert not bundles[0].filters bundles = list(App().config.webasset_registry.get_bundles('jquery')) assert len(bundles) == 1 assert not bundles[0].filters
def test_refresh_without_token(): class App(morepath.App): pass class Refresh(object): pass @App.path(model=Refresh, path='refresh') def get_refresh(): return Refresh() @App.json(model=Refresh) def refresh(self, request): verify_refresh_request(request) refresh_nonce_handler = 'more.jwtauth.tests.handler.refresh_nonce_handler' @App.setting_section(section="jwtauth") def get_jwtauth_settings(): return { 'master_secret': 'secret', 'allow_refresh': True, 'refresh_delta': 3, 'refresh_nonce_handler': refresh_nonce_handler } morepath.commit(App) c = Client(App()) with pytest.raises(InvalidTokenError) as excinfo: c.get('/refresh') assert 'Token not found' in str(excinfo.value)
def test_app_extends_settings(): class Alpha(morepath.App): pass class Beta(Alpha): pass Alpha.init_settings({ 'foo': { 'enable_foo': True, 'engine': 'ADVANCED' }, }) Beta.init_settings({ 'bar': { 'space': 'huge', 'security': False } }) morepath.commit(Alpha, Beta) alpha_inst = Alpha() settings = alpha_inst.settings assert settings.foo.engine == 'ADVANCED' with pytest.raises(AttributeError): settings.bar.space beta_inst = Beta() settings = beta_inst.settings assert settings.foo.engine == 'ADVANCED' assert settings.bar.space == 'huge'
def test_app_overrides_settings(): class Alpha(morepath.App): pass class Beta(Alpha): pass Alpha.init_settings({ 'foo': { 'enable_foo': True, 'engine': 'ADVANCED' }, 'bar': { 'space': 'huge', 'security': False } }) Beta.init_settings({'bar': {'space': 'tiny', 'security': True}}) morepath.commit(Alpha, Beta) alpha_inst = Alpha() settings = alpha_inst.settings assert settings.foo.engine == 'ADVANCED' assert settings.bar.space == 'huge' beta_inst = Beta() settings = beta_inst.settings assert settings.foo.engine == 'ADVANCED' assert settings.bar.space == 'tiny'
def test_webasset_mixed_bundles(tempdir, fixtures_path): class App(WebassetsApp): pass @App.webasset_path() def get_path(): return fixtures_path @App.webasset_output() def get_output_path(): return tempdir @App.webasset('common') def get_jquery_asset(): yield 'jquery.js' yield 'extra.css' morepath.commit(App) bundles = list(App().config.webasset_registry.get_bundles('common')) assert len(bundles) == 2 assert bundles[0].output.endswith('jquery.js.bundle.js') assert bundles[0].contents == (os.path.join(fixtures_path, 'jquery.js'), ) assert bundles[1].output.endswith('extra.css.bundle.css') assert bundles[1].contents == (os.path.join(fixtures_path, 'extra.css'), )
def create_app(app, settings, sqlalchemy_session=Session, sqlalchemy_bases=None): sqlalchemy_bases = sqlalchemy_bases or [] register_session(sqlalchemy_session) # initialize SQLAlchemy if 'sqlalchemy' in settings: cwd = os.getcwd() engine = sqlalchemy.create_engine(settings['sqlalchemy']['dburi'] % {'here': cwd}) sqlalchemy_session.configure(bind=engine) # initialize app app.init_settings(settings) morepath.commit(app) morepath.autoscan() app.commit() application = app() # create tables if 'sqlalchemy' in settings: for base in sqlalchemy_bases: base.metadata.create_all(engine) return application
def test_webasset_mixed_bundles(tempdir, fixtures_path): class App(WebassetsApp): pass @App.webasset_path() def get_path(): return fixtures_path @App.webasset_output() def get_output_path(): return tempdir @App.webasset('common') def get_jquery_asset(): yield 'jquery.js' yield 'extra.css' morepath.commit(App) bundles = list(App().config.webasset_registry.get_bundles('common')) assert len(bundles) == 2 assert bundles[0].output.endswith('jquery.js.bundle.js') assert bundles[0].contents == ( os.path.join(fixtures_path, 'jquery.js'), ) assert bundles[1].output.endswith('extra.css.bundle.css') assert bundles[1].contents == ( os.path.join(fixtures_path, 'extra.css'), )
def test_app_extends_settings(): class Alpha(morepath.App): pass class Beta(Alpha): pass Alpha.init_settings({ 'foo': { 'enable_foo': True, 'engine': 'ADVANCED' }, }) Beta.init_settings({'bar': {'space': 'huge', 'security': False}}) morepath.commit(Alpha, Beta) alpha_inst = Alpha() settings = alpha_inst.settings assert settings.foo.engine == 'ADVANCED' with pytest.raises(AttributeError): settings.bar.space beta_inst = Beta() settings = beta_inst.settings assert settings.foo.engine == 'ADVANCED' assert settings.bar.space == 'huge'
def test_alternate_id_property(es_url, postgres_dsn): class App(Framework, ElasticsearchApp): pass Base = declarative_base() class User(Base, ORMSearchable): __tablename__ = 'users' name = Column(Text, primary_key=True) fullname = Column(Text, nullable=False) @property def es_suggestion(self): return self.name es_id = 'name' es_properties = { 'fullname': {'type': 'string'}, } es_language = 'en' es_public = True scan_morepath_modules(App) morepath.commit(App) app = App() app.configure_application( dsn=postgres_dsn, base=Base, elasticsearch_hosts=[es_url] ) app.namespace = 'users' app.set_application_id('users/corporate') session = app.session() session.add(User( name="root", fullname="Lil' Root" )) session.add(User( name="user", fullname="Lil' User" )) transaction.commit() app.es_indexer.process() app.es_client.indices.refresh(index='_all') assert app.es_search().count() == 2 assert app.es_search().query('match', fullname='Root').count() == 1 assert app.es_search().execute().query(type='users').count() == 2 assert len(app.es_search().execute().load()) == 2 root = app.es_search().query('match', fullname='Root').execute()[0] assert root.query().count() == 1 assert root.load().name == 'root' assert root.load().fullname == "Lil' Root"
def get_client(app): class Tapp(app): pass morepath.autoscan() morepath.commit(Tapp) c = Client(Tapp()) return c
def test_webasset_filter_chain(fixtures_path): class App(WebassetsApp): pass @App.webasset_path() def get_path(): return fixtures_path @App.webasset_filter('js', produces='css') def foo_filter(): return 'jsmin' @App.webasset_filter('css') def bar_filter(): return 'cssmin' @App.webasset('common') def get_common_assets(): yield 'jquery.js' morepath.commit(App) common = list(App().config.webasset_registry.get_bundles('common')) assert len(common) == 1 assert common[0].filters[0].name == 'jsmin' assert common[0].filters[1].name == 'cssmin'
def test_mapbox_token_tween(temporary_directory, redis_url): class App(Framework, MapboxApp): pass @App.webasset_output() def get_output_path(): return temporary_directory @App.path(path='') class Root(object): pass @App.html(model=Root) def view_root(self, request): return '<body></body>' scan_morepath_modules(App) morepath.commit(App) app = App() app.configure_application(mapbox_token='pk.asdf', redis_url=redis_url) app.namespace = 'foo' app.set_application_id('foo/bar') assert '<body data-mapbox-token="pk.asdf"></body>' in Client(app).get('/')
def test_webasset_compiled_bundle(tempdir, fixtures_path): class App(WebassetsApp): pass @App.webasset_path() def get_path(): return fixtures_path @App.webasset_output() def get_output_path(): return tempdir @App.webasset_filter('scss') def get_scss_filter(): return 'pyscss' @App.webasset('theme') def get_jquery_asset(): yield 'main.scss' yield 'extra.css' morepath.commit(App) bundles = list(App().config.webasset_registry.get_bundles('theme')) assert len(bundles) == 2 assert bundles[0].output.endswith('main.scss.bundle.css') assert bundles[0].contents == (os.path.join(fixtures_path, 'main.scss'), ) assert bundles[1].output.endswith('extra.css.bundle.css') assert bundles[1].contents == (os.path.join(fixtures_path, 'extra.css'), )
def test_app_overrides_settings(): class Alpha(morepath.App): pass class Beta(Alpha): pass Alpha.init_settings({ "foo": { "enable_foo": True, "engine": "ADVANCED" }, "bar": { "space": "huge", "security": False }, }) Beta.init_settings({"bar": {"space": "tiny", "security": True}}) morepath.commit(Alpha, Beta) alpha_inst = Alpha() settings = alpha_inst.settings assert settings.foo.engine == "ADVANCED" assert settings.bar.space == "huge" beta_inst = Beta() settings = beta_inst.settings assert settings.foo.engine == "ADVANCED" assert settings.bar.space == "tiny"
def test_jwt_custom_settings(): class App(morepath.App): pass @App.setting_section(section="jwtauth") def get_jwtauth_settings(): return { 'public_key': 'MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBWcJwPEAnS/k4kFgUhxNF7J0SQQhZG+nNgy+' '/mXwhQ5PZIUmId1a1TjkNXiKzv6DpttBqduHbz/V0EtH+QfWy0B4BhZ5MnTyDGjcz1DQqKd' 'exebhzobbhSIZjpYd5aU48o9rXp/OnAnrajddpGsJ0bNf4rtMLBqFYJN6LOslAB7xTBRg=', 'algorithm': "ES256", 'leeway': 20 } morepath.commit(App) app = App() lookup = app.lookup assert settings(lookup=lookup).jwtauth.algorithm == "ES256" assert settings(lookup=lookup).jwtauth.leeway == 20 assert settings( lookup=lookup).jwtauth.public_key == 'MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBWcJwPEAnS/k4kFgUhxNF7J0SQQhZG+nNgy+'\ '/mXwhQ5PZIUmId1a1TjkNXiKzv6DpttBqduHbz/V0EtH+QfWy0B4BhZ5MnTyDGjcz1DQqKd'\ 'exebhzobbhSIZjpYd5aU48o9rXp/OnAnrajddpGsJ0bNf4rtMLBqFYJN6LOslAB7xTBRg='
def test_root(): morepath.scan(synonymista_api) morepath.commit(synonymista_api.App) client = Client(synonymista_api.App()) root = client.get('/') assert root.status_code == 200 assert len(root.json['greetings']) == 2
def app(request, postgres_dsn, temporary_path, redis_url): with (temporary_path / 'bust').open('w') as f: f.write('\n'.join(( f'#!/bin/bash', f'touch {temporary_path}/$1' ))) signing_services = (temporary_path / 'signing-services') signing_services.mkdir() cert_file = module_path('onegov.file', 'tests/fixtures/test.crt') cert_key = module_path('onegov.file', 'tests/fixtures/test.crt') with (signing_services / '__default__.yml').open('w') as f: f.write(textwrap.dedent(f""" name: swisscom_ais parameters: customer: foo key_static: bar cert_file: {cert_file} cert_key: {cert_key} """)) os.chmod(temporary_path / 'bust', 0o775) backend = request.param class App(Framework, DepotApp): anonymous_access = False @App.permission_rule(model=object, permission=object, identity=None) def test_has_permission_not_logged_in(app, identity, model, permission): if app.anonymous_access: return True return has_permission_not_logged_in(app, identity, model, permission) scan_morepath_modules(App) morepath.commit(App) app = App() app.configure_application( dsn=postgres_dsn, depot_backend=backend, depot_storage_path=str(temporary_path), frontend_cache_buster=f'{temporary_path}/bust', redis_url=redis_url, signing_services=str(signing_services), yubikey_client_id='foo', yubikey_secret_key='dGhlIHdvcmxkIGlzIGNvbnRyb2xsZWQgYnkgbGl6YXJkcyE=' ) app.namespace = 'apps' app.set_application_id('apps/my-app') return app
def query_tool(): """Usa dectate.query_tool() para consultar las rutas de la API.""" morepath.autoscan() # Cargamos la configuración de la aplicación with open('settings.json') as config: settings_dict = json.load(config) App.init_settings(settings_dict) morepath.commit(App) dectate.query_tool(App.commit())
def test_root(): morepath.scan(rassle) morepath.commit(rassle.App) client = Client(rassle.App()) root = client.get('/') assert root.status_code == 200 assert '/greeting/world' in root assert '/greeting/mundo' in root
def test_town_create(onboarding_app, temporary_directory, smtp): c = Client(onboarding_app) a = c.get('/for-towns/1') a.form['name'] = 'New York' a.form['user'] = '******' a.form['color'] = '#ff00ff' a = a.form.submit().follow() assert 'New York' in a assert '*****@*****.**' in a assert '#f0f' in a assert 'new-york.example.org' in a a = a.form.submit() assert 'https://new-york.example.org' in a assert '*****@*****.**' in a assert len(smtp.outbox) == 1 username = '******' password = a.pyquery('.product dd:nth-child(4)').text() scan_morepath_modules(onegov.town.TownApp) morepath.commit(onegov.town.TownApp) town = TownApp() town.namespace = onboarding_app.onboarding['onegov.town']['namespace'] town.configure_application( dsn=onboarding_app.dsn, filestorage='fs.osfs.OSFS', filestorage_options={ 'root_path': temporary_directory, 'create': True }, identity_secure=False, disable_memcached=True, enable_elasticsearch=False, depot_backend='depot.io.memory.MemoryFileStorage' ) town.set_application_id(town.namespace + '/' + 'new_york') town.settings.cronjobs = Bunch(enabled=False) c = Client(town) p = c.get('/') assert "Willkommen bei OneGov" in p assert "New York" in p p = c.get('/auth/login') p.forms[1]['username'] = username p.forms[1]['password'] = password p = p.forms[1].submit().follow() assert 'Benutzerprofil' in p
def test_setup_database(postgres_dsn): Base = declarative_base() class App(Framework, LibresIntegration): pass class Document(Base): __tablename__ = 'documents' id = Column(Integer, primary_key=True) @App.path(path='/') class Root(object): pass @App.json(model=Root) def get_root(self, request): return [] # this is required for the transactions to actually work, usually this # would be onegov.server's job scan_morepath_modules(App) morepath.commit(App) app = App() app.configure_application(dsn=postgres_dsn, base=Base) app.namespace = 'libres' app.set_application_id('libres/foo') c = Client(app) c.get('/') tables = app.session().execute( "SELECT table_name FROM information_schema.tables " "WHERE table_schema = 'public'" ) assert not tables.fetchall() tables = app.session().execute( "SELECT table_name FROM information_schema.tables " "WHERE table_schema = 'libres-foo'" ) tables = set(r[0] for r in tables.fetchall()) assert tables == { 'documents', 'resources', 'allocations', 'reserved_slots', 'reservations' } app.session_manager.dispose()
def test_root(): morepath.scan(ntv.api) morepath.commit(ntv.api.App) client = Client(ntv.api.App()) root = client.get('/') assert root.status_code == 200 assert len(root.json) == 1 resource = root.json[0] assert '@id' in resource
def test_webasset_directive(tempdir, fixtures_path): class App(WebassetsApp): pass @App.webasset_path() def get_path(): return fixtures_path @App.webasset_output() def get_output_path(): return tempdir @App.webasset('common') def get_common_assets(): yield 'jquery.js' yield 'underscore.js' morepath.commit(App) app = App() assert app.config.webasset_registry.assets == { 'jquery.js': Asset(name='jquery.js', assets=(os.path.join(fixtures_path, 'jquery.js'), ), filters={}), 'underscore.js': Asset(name='underscore.js', assets=(os.path.join(fixtures_path, 'underscore.js'), ), filters={}), 'common': Asset(name='common', assets=('jquery.js', 'underscore.js'), filters={}) } common = list(app.config.webasset_registry.get_bundles('common')) assert len(common) == 1 assert common[0].output.endswith('common.bundle.js') assert common[0].contents == (os.path.join(fixtures_path, 'jquery.js'), os.path.join(fixtures_path, 'underscore.js')) jquery = list(app.config.webasset_registry.get_bundles('jquery.js')) assert len(jquery) == 1 assert jquery[0].output.endswith('jquery.js.bundle.js') assert jquery[0].contents == (os.path.join(fixtures_path, 'jquery.js'), ) underscore = list( app.config.webasset_registry.get_bundles('underscore.js')) assert len(underscore) == 1 assert underscore[0].output.endswith('underscore.js.bundle.js') assert underscore[0].contents == (os.path.join(fixtures_path, 'underscore.js'), )
def test_town_create(onboarding_app, temporary_directory, smtp, redis_url): c = Client(onboarding_app) a = c.get('/for-towns/1') a.form['name'] = 'New York' a.form['user'] = '******' a.form['color'] = '#ff00ff' a = a.form.submit().follow() assert 'New York' in a assert '*****@*****.**' in a assert '#f0f' in a assert 'new-york.example.org' in a a = a.form.submit() assert 'https://new-york.example.org' in a assert '*****@*****.**' in a assert len(smtp.outbox) == 1 username = '******' password = a.pyquery('.product dd:nth-child(4)').text() scan_morepath_modules(onegov.town.TownApp) morepath.commit(onegov.town.TownApp) town = TownApp() town.namespace = onboarding_app.onboarding['onegov.town']['namespace'] town.configure_application( dsn=onboarding_app.dsn, filestorage='fs.osfs.OSFS', filestorage_options={ 'root_path': temporary_directory, 'create': True }, identity_secure=False, redis_url=redis_url, enable_elasticsearch=False, depot_backend='depot.io.memory.MemoryFileStorage') town.set_application_id(town.namespace + '/' + 'new_york') town.settings.cronjobs = Bunch(enabled=False) c = Client(town) p = c.get('/') assert "Willkommen bei der OneGov Cloud" in p assert "New York" in p p = c.get('/auth/login') p.forms[1]['username'] = username p.forms[1]['password'] = password p = p.forms[1].submit().follow() assert 'Benutzerprofil' in p
def test_get_game_tags(): """ Test retrieving tags for a game """ morepath.scan(falchion) morepath.commit(falchion.App) api_client = Client(falchion.App()) response = api_client.get('/games/10') assert response.status_code == 200 assert 'jrpg' in response.json['tags']
def get_client(app, config='settings.yml'): if isinstance(config, str): with open(os.path.join(os.path.dirname(__file__), config)) as f: settings = yaml.load(f) or {} else: settings = config morepath.autoscan() app.init_settings(settings) morepath.commit(app) c = Client(app()) return c
def test_get_game_achievements(): """ Test retrieving achievements for a game """ morepath.scan(falchion) morepath.commit(falchion.App()) api_client = Client(falchion.App()) response = api_client.get('/games/10') assert response.status_code == 200 assert len(response.json['achievements']) == 2
def test_get_game_by_id(): """ Test getting a single game by ID """ morepath.scan(falchion) morepath.commit(falchion.App) api_client = Client(falchion.App()) response = api_client.get('/games/1') assert response.status_code == 200 assert response.json['name'] == 'Shovel Knight'
def test_get_game_status(): """ Test retrieving status for a game """ morepath.scan(falchion) morepath.commit(falchion.App()) api_client = Client(falchion.App()) response = api_client.get('/games/2') assert response.status_code == 200 assert response.json['status'] == 'unfinished'
def test_get_games(): """ Test getting a collection of games """ morepath.scan(falchion) morepath.commit(falchion.App) api_client = Client(falchion.App()) response = api_client.get('/games') assert response.status_code == 200 assert len(response.json['games']) == 14
def onboarding_app(postgres_dsn, temporary_directory, smtp, es_url, redis_url): scan_morepath_modules(onegov.onboarding.OnboardingApp) morepath.commit(onegov.onboarding.OnboardingApp) app = onegov.onboarding.OnboardingApp() app.namespace = 'test_' + uuid4().hex app.configure_application( dsn=postgres_dsn, filestorage='fs.osfs.OSFS', filestorage_options={ 'root_path': os.path.join(temporary_directory, 'file-storage'), 'create': True }, identity_secure=False, depot_backend='depot.io.memory.MemoryFileStorage', redis_url=redis_url, onboarding={ 'onegov.town': { 'namespace': 'town_' + uuid4().hex, 'domain': 'example.org', 'configuration': { 'depot_backend': 'depot.io.memory.MemoryFileStorage' } } }, elasticsearch_hosts=[es_url] ) app.set_application_id(app.namespace + '/' + 'test') app.mail = { 'marketing': { 'host': smtp.address[0], 'port': smtp.address[1], 'force_tls': False, 'username': None, 'password': None, 'use_directory': False, 'sender': '*****@*****.**' }, 'transactional': { 'host': smtp.address[0], 'port': smtp.address[1], 'force_tls': False, 'username': None, 'password': None, 'use_directory': False, 'sender': '*****@*****.**' } } yield app
def test_webasset_relative(current_path): class App(WebassetsApp): pass @App.webasset_path() def get_relative_path(): return 'fixtures' morepath.commit(App) assert App().config.webasset_registry.paths == [ os.path.join(current_path, 'fixtures') ]
def test_no_secret_keys(temporary_directory): class App(Framework, MapboxApp): pass @App.webasset_output() def get_output_path(): return temporary_directory morepath.commit(App) app = App() with pytest.raises(AssertionError): app.configure_application(mapbox_token='sk.asdf')
def test_webasset_path_inheritance(tempdir, current_path): os.mkdir(os.path.join(tempdir, 'A')) os.mkdir(os.path.join(tempdir, 'B')) os.mkdir(os.path.join(tempdir, 'C')) class A(WebassetsApp): pass @A.webasset_path() def get_path_a(): return os.path.join(tempdir, 'A') class B(WebassetsApp): pass @B.webasset_path() def get_path_b(): return os.path.join(tempdir, 'B') class C(B, A): pass @C.webasset_path() def get_path_c(): return os.path.join(tempdir, 'C') class D(A, B): pass @D.webasset_path() def get_path_c_2(): return os.path.join(tempdir, 'C') # the order of A and B is defined by the order they are scanned with morepath.commit(A, B, C, D) assert C().config.webasset_registry.paths == [ os.path.join(tempdir, 'C'), os.path.join(tempdir, 'B'), os.path.join(tempdir, 'A'), ] assert D().config.webasset_registry.paths == [ os.path.join(tempdir, 'C'), os.path.join(tempdir, 'B'), os.path.join(tempdir, 'A'), ]
def test_transaction_integration(postgres_dsn): Base = declarative_base() class App(Framework, LibresIntegration): pass class Document(Base): __tablename__ = "documents" id = Column(Integer, primary_key=True) @App.path(path="/") class Root(object): pass @App.json(model=Root) def handle_root(self, request): collection = ResourceCollection(request.app.libres_context) resource = collection.add("Test", "Europe/Zurich") scheduler = resource.get_scheduler(request.app.libres_context) scheduler.allocate((datetime(2015, 7, 30, 11), datetime(2015, 7, 30, 12))) # this will fail and then abort everything request.app.session().add(Document(id=1)) request.app.session().add(Document(id=1)) # this is required for the transactions to actually work, usually this # would be onegov.server's job scan_morepath_modules(App) morepath.commit(App) app = App() app.configure_application(dsn=postgres_dsn, base=Base) app.namespace = "libres" app.set_application_id("libres/foo") c = Client(app) try: c.get("/", expect_errors=True) except: pass collection = ResourceCollection(app.libres_context) assert collection.query().count() == 0
def test_setup_database(postgres_dsn): Base = declarative_base() class App(Framework, LibresIntegration): pass class Document(Base): __tablename__ = "documents" id = Column(Integer, primary_key=True) @App.path(path="/") class Root(object): pass @App.json(model=Root) def get_root(self, request): return [] # this is required for the transactions to actually work, usually this # would be onegov.server's job scan_morepath_modules(App) morepath.commit(App) app = App() app.configure_application(dsn=postgres_dsn, base=Base) app.namespace = "libres" app.set_application_id("libres/foo") c = Client(app) c.get("/") tables = app.session().execute("SELECT table_name FROM information_schema.tables " "WHERE table_schema = 'public'") assert not tables.fetchall() tables = app.session().execute( "SELECT table_name FROM information_schema.tables " "WHERE table_schema = 'libres-foo'" ) tables = set(r[0] for r in tables.fetchall()) assert tables == {"documents", "resources", "allocations", "reserved_slots", "reservations"} app.session_manager.dispose()
def test_webasset_filter(): class Base(WebassetsApp): pass @Base.webasset_filter('js') def get_base_js_filter(): return 'jsmin' class App(WebassetsApp): pass @App.webasset_filter('js') def get_js_filter(): return 'rjsmin' morepath.commit(App) assert App().config.webasset_registry.filters == {'js': 'rjsmin'}
def test_app_overrides_settings(): class Alpha(morepath.App): pass class Beta(Alpha): pass Alpha.init_settings({ 'foo': { 'enable_foo': True, 'engine': 'ADVANCED' }, 'bar': { 'space': 'huge', 'security': False } }) Beta.init_settings({ 'bar': { 'space': 'tiny', 'security': True } }) morepath.commit(Alpha, Beta) alpha_inst = Alpha() settings = alpha_inst.settings assert settings.foo.engine == 'ADVANCED' assert settings.bar.space == 'huge' beta_inst = Beta() settings = beta_inst.settings assert settings.foo.engine == 'ADVANCED' assert settings.bar.space == 'tiny'
def test_webasset_override_filter_through_bundle(tempdir, fixtures_path): class App(WebassetsApp): pass @App.webasset_path() def get_path(): return fixtures_path @App.webasset_output() def get_output_path(): return tempdir @App.webasset('jquery') def get_jquery_asset(): yield 'jquery.js' @App.webasset_filter('js') def get_js_filter(): return 'rjsmin' class DebugApp(App): pass @DebugApp.webasset('common', filters={'js': None}) def get_debug_js_filter(): yield 'jquery' morepath.commit(DebugApp, App) bundles = list(App().config.webasset_registry.get_bundles('jquery')) assert len(bundles) == 1 assert bundles[0].filters[0].name == 'rjsmin' bundles = list(DebugApp().config.webasset_registry.get_bundles('common')) assert len(bundles) == 1 assert not bundles[0].filters
def test_jwt_remember(): class App(morepath.App): pass @App.path(path='{id}', variables=lambda model: {'id': model.id}) class Model(object): def __init__(self, id): self.id = id @App.view(model=Model) def default(self, request): response = Response() morepath.remember_identity(response, request, Identity('foo'), lookup=request.lookup) return response @App.setting_section(section="jwtauth") def get_jwtauth_settings(): return { 'master_secret': 'secret', } @App.identity_policy() def get_identity_policy(settings): jwtauth_settings = settings.jwtauth.__dict__.copy() return JWTIdentityPolicy(**jwtauth_settings) morepath.commit(App) c = Client(App()) response = c.get('/foo', status=200) assert response.body == b'' assert isinstance(response.headers['Authorization'], str) assert response.headers['Authorization'][:7] == 'JWT eyJ'
def test_webasset_compiled_bundle(tempdir, fixtures_path): class App(WebassetsApp): pass @App.webasset_path() def get_path(): return fixtures_path @App.webasset_output() def get_output_path(): return tempdir @App.webasset_filter('scss') def get_scss_filter(): return 'pyscss' @App.webasset('theme') def get_jquery_asset(): yield 'main.scss' yield 'extra.css' morepath.commit(App) bundles = list(App().config.webasset_registry.get_bundles('theme')) assert len(bundles) == 2 assert bundles[0].output.endswith('main.scss.bundle.css') assert bundles[0].contents == ( os.path.join(fixtures_path, 'main.scss'), ) assert bundles[1].output.endswith('extra.css.bundle.css') assert bundles[1].contents == ( os.path.join(fixtures_path, 'extra.css'), )
def onboarding_app(postgres_dsn, temporary_directory, smtp): scan_morepath_modules(onegov.onboarding.OnboardingApp) morepath.commit(onegov.onboarding.OnboardingApp) app = onegov.onboarding.OnboardingApp() app.namespace = 'test_' + uuid4().hex app.configure_application( dsn=postgres_dsn, filestorage='fs.osfs.OSFS', filestorage_options={ 'root_path': os.path.join(temporary_directory, 'file-storage'), 'create': True }, identity_secure=False, disable_memcached=True, depot_backend='depot.io.memory.MemoryFileStorage', onboarding={ 'onegov.town': { 'namespace': 'town_' + uuid4().hex, 'domain': 'example.org' } }, ) app.set_application_id(app.namespace + '/' + 'test') app.mail_host, app.mail_port = smtp.address app.mail_sender = '*****@*****.**' app.mail_force_tls = False app.mail_username = None app.mail_password = None app.mail_use_directory = False app.smtp = smtp yield app
def test_section_settings_conflict(): settings = { 'foo': { 'enable_foo': True, 'engine': 'ADVANCED' }, 'bar': { 'space': 'huge', 'security': False } } class App(morepath.App): pass App.init_settings(settings) @App.setting('foo', 'engine') def get_foo_setting(): return 'STANDARD' with pytest.raises(ConflictError): morepath.commit(App)
def test_search_query(es_url, postgres_dsn): class App(Framework, ElasticsearchApp): pass Base = declarative_base() class Document(Base, ORMSearchable): __tablename__ = 'documents' id = Column(Integer, primary_key=True) title = Column(Text, nullable=False) body = Column(Text, nullable=True) public = Column(Boolean, nullable=False) language = Column(Text, nullable=False) es_properties = { 'title': {'type': 'localized'}, 'body': {'type': 'localized'} } @property def es_suggestion(self): return self.title @property def es_public(self): return self.public @property def es_language(self): return self.language scan_morepath_modules(App) morepath.commit(App) app = App() app.configure_application( dsn=postgres_dsn, base=Base, elasticsearch_hosts=[es_url] ) app.namespace = 'documents' app.set_application_id('documents/home') session = app.session() session.add(Document( title="Public", body="This document can be seen by anyone", language='en', public=True )) session.add(Document( title="Private", body="This document is a secret", language='en', public=False )) session.add(Document( title="Öffentlich", body="Dieses Dokument kann jeder sehen", language='de', public=True )) session.add(Document( title="Privat", body="Dieses Dokument ist geheim", language='de', public=False )) transaction.commit() app.es_indexer.process() app.es_client.indices.refresh(index='_all') assert app.es_search().execute().hits.total == 2 assert app.es_search(include_private=True).execute().hits.total == 4 result = app.es_search(languages=['en']).execute() assert result.hits.total == 1 result = app.es_search(languages=['de'], include_private=True).execute() assert result.hits.total == 2 search = app.es_search(languages=['de']) assert search.query('match', body='Dokumente').execute().hits.total == 1 search = app.es_search(languages=['de'], include_private=True) assert search.query('match', body='Dokumente').execute().hits.total == 2 # test result loading in one query result = app.es_search(languages=['de'], include_private=True).execute() records = result.load() assert len(records) == 2 assert isinstance(records[0], Document) assert True in (records[0].es_public, records[1].es_public) assert False in (records[0].es_public, records[1].es_public) # test result loading query result = app.es_search(languages=['de'], include_private=True).execute() query = result.query(type='documents') assert query.count() == 2 assert query.filter(Document.public == True).count() == 1 # test single result loading document = app.es_search(languages=['de']).execute()[0].load() assert document.title == "Öffentlich" assert document.public # test single result query document = app.es_search(languages=['de']).execute()[0].query().one() assert document.title == "Öffentlich" assert document.public
def test_orm_integration(es_url, postgres_dsn): class App(Framework, ElasticsearchApp): pass Base = declarative_base() class Document(Base, ORMSearchable): __tablename__ = 'documents' id = Column(Integer, primary_key=True) title = Column(Text, nullable=False) body = Column(Text, nullable=True) @property def es_suggestion(self): return self.title es_public = True es_language = 'en' es_properties = { 'title': {'type': 'localized'}, 'body': {'type': 'localized'} } @App.path(path='/') class Root(object): pass @App.json(model=Root) def view_documents(self, request): # make sure the changes are propagated in testing request.app.es_client.indices.refresh(index='_all') query = request.params.get('q') if query: return request.app.es_client.search(index='_all', body={ 'query': { 'multi_match': { 'query': query, 'fields': ['title', 'body'] } } }) else: return request.app.es_client.search(index='_all') @App.json(model=Root, name='new') def view_add_document(self, request): session = request.app.session() session.add(Document( id=request.params.get('id'), title=request.params.get('title'), body=request.params.get('body') )) @App.json(model=Root, name='update') def view_update_document(self, request): session = request.app.session() query = session.query(Document) query = query.filter(Document.id == request.params.get('id')) document = query.one() document.title = request.params.get('title'), document.body = request.params.get('body'), @App.json(model=Root, name='delete') def view_delete_document(self, request): session = request.app.session() query = session.query(Document) query = query.filter(Document.id == request.params.get('id')) query.delete('fetch') scan_morepath_modules(App) morepath.commit(App) app = App() app.configure_application( dsn=postgres_dsn, base=Base, elasticsearch_hosts=[es_url] ) app.namespace = 'documents' app.set_application_id('documents/home') client = Client(app) client.get('/new?id=1&title=Shop&body=We sell things and stuff') client.get('/new?id=2&title=About&body=We are a company') client.get('/new?id=3&title=Terms&body=Stuff we pay lawyers for') documents = client.get('/').json assert documents['hits']['total'] == 3 documents = client.get('/?q=stuff').json assert documents['hits']['total'] == 2 documents = client.get('/?q=company').json assert documents['hits']['total'] == 1 client.get('/delete?id=3') documents = client.get('/?q=stuff').json assert documents['hits']['total'] == 1 client.get('/update?id=2&title=About&body=We are a business') documents = client.get('/?q=company').json assert documents['hits']['total'] == 0 documents = client.get('/?q=business').json assert documents['hits']['total'] == 1
def test_orm_polymorphic(es_url, postgres_dsn): class App(Framework, ElasticsearchApp): pass Base = declarative_base() class Page(Base, ORMSearchable): __tablename__ = 'pages' es_properties = { 'content': {'type': 'localized'} } es_language = 'en' es_public = True @property def es_suggestion(self): return self.content id = Column(Integer, primary_key=True) content = Column(Text, nullable=True) type = Column(Text, nullable=False) __mapper_args__ = { "polymorphic_on": 'type' } class Topic(Page): __mapper_args__ = {'polymorphic_identity': 'topic'} es_type_name = 'topic' class News(Page): __mapper_args__ = {'polymorphic_identity': 'news'} es_type_name = 'news' class Breaking(News): __mapper_args__ = {'polymorphic_identity': 'breaking'} es_type_name = 'breaking' scan_morepath_modules(App) morepath.commit() app = App() app.configure_application( dsn=postgres_dsn, base=Base, elasticsearch_hosts=[es_url] ) app.namespace = 'pages' app.set_application_id('pages/site') session = app.session() session.add(Topic(content="Topic", type='topic')) session.add(News(content="News", type='news')) session.add(Breaking(content="Breaking", type='breaking')) def update(): transaction.commit() app.es_indexer.process() app.es_client.indices.refresh(index='_all') update() assert app.es_search().count() == 3 newsitem = session.query(Page).filter(Page.type == 'news').one() assert isinstance(newsitem, News) newsitem.content = 'Story' update() assert app.es_search().query('match', content='story').count() == 1 session.query(Page).filter(Page.type == 'news').delete() update() assert app.es_search().count() == 2 session.delete(session.query(Page).filter(Page.type == 'breaking').one()) update() assert app.es_search().count() == 1 session.query(Page).delete() update() assert app.es_search().count() == 0
def setup_module(module): morepath.scan(app) morepath.commit(App)
def test_suggestions(es_url, postgres_dsn): class App(Framework, ElasticsearchApp): pass Base = declarative_base() class Document(Base, ORMSearchable): __tablename__ = 'documents' id = Column(Integer, primary_key=True) title = Column(Text, nullable=False) public = Column(Boolean, nullable=False) language = Column(Text, nullable=False) es_properties = { 'title': {'type': 'localized'} } @property def es_public(self): return self.public @property def es_language(self): return self.language class Person(Base, ORMSearchable): __tablename__ = 'people' id = Column(Integer, primary_key=True) first_name = Column(Text, nullable=False) last_name = Column(Text, nullable=False) @property def title(self): return ' '.join((self.first_name, self.last_name)) es_properties = {'title': {'type': 'localized'}} es_public = True es_language = 'en' @property def es_suggestion(self): return [ ' '.join((self.first_name, self.last_name)), ' '.join((self.last_name, self.first_name)) ] scan_morepath_modules(App) morepath.commit() app = App() app.configure_application( dsn=postgres_dsn, base=Base, elasticsearch_hosts=[es_url] ) app.namespace = 'documents' app.set_application_id('documents/home') session = app.session() session.add(Document( title="Public Document", language='en', public=True )) session.add(Document( title="Private Document", language='en', public=False )) session.add(Document( title="Öffentliches Dokument", language='de', public=True )) session.add(Document( title="Privates Dokument", language='de', public=False )) session.add(Person( first_name='Jeff', last_name='Winger' )) transaction.commit() app.es_indexer.process() app.es_client.indices.refresh(index='_all') assert set(app.es_suggestions(query='p')) == {"Public Document"} assert set(app.es_suggestions(query='p', include_private=True)) == { "Public Document", "Private Document", "Privates Dokument" } assert set(app.es_suggestions(query='ö', languages=['de'])) == { "Öffentliches Dokument", } assert set(app.es_suggestions( query='ö', languages=['de'], include_private=True)) == { "Öffentliches Dokument", } assert set(app.es_suggestions( query='p', languages=['de'], include_private=True)) == { "Privates Dokument", } assert set(app.es_suggestions(query='j', languages=['en'])) == { 'Jeff Winger' } assert set(app.es_suggestions(query='w', languages=['en'])) == { 'Jeff Winger' }