def test_config_from_mapping(): app = keyes.Keyes(__name__) app.config.from_mapping({ 'SECRET_KEY': 'devkey', 'TEST_KEY': 'foo' }) common_object_test(app) app = keyes.Keyes(__name__) app.config.from_mapping([ ('SECRET_KEY', 'devkey'), ('TEST_KEY', 'foo') ]) common_object_test(app) app = keyes.Keyes(__name__) app.config.from_mapping( SECRET_KEY='devkey', TEST_KEY='foo' ) common_object_test(app) app = keyes.Keyes(__name__) with pytest.raises(TypeError): app.config.from_mapping( {}, {} )
def test_explicit_instance_paths(modules_tmpdir): with pytest.raises(ValueError) as excinfo: keyes.Keyes(__name__, instance_path='instance') assert 'must be absolute' in str(excinfo.value) app = keyes.Keyes(__name__, instance_path=str(modules_tmpdir)) assert app.instance_path == str(modules_tmpdir)
def test_logger_cache(self): app = keyes.Keyes(__name__) logger1 = app.logger assert app.logger is logger1 assert logger1.name == __name__ app.logger_name = __name__ + '/test_logger_cache' assert app.logger is not logger1
def test_attachment(self, catch_deprecation_warnings): app = keyes.Keyes(__name__) with catch_deprecation_warnings() as captured: with app.test_request_context(): f = open(os.path.join(app.root_path, 'static/index.html')) rv = keyes.send_file(f, as_attachment=True) value, options = parse_options_header( rv.headers['Content-Disposition']) assert value == 'attachment' rv.close() # mimetypes + etag assert len(captured) == 2 with app.test_request_context(): assert options['filename'] == 'index.html' rv = keyes.send_file('static/index.html', as_attachment=True) value, options = parse_options_header( rv.headers['Content-Disposition']) assert value == 'attachment' assert options['filename'] == 'index.html' rv.close() with app.test_request_context(): rv = keyes.send_file(StringIO('Test'), as_attachment=True, attachment_filename='index.txt', add_etags=False) assert rv.mimetype == 'text/plain' value, options = parse_options_header( rv.headers['Content-Disposition']) assert value == 'attachment' assert options['filename'] == 'index.txt' rv.close()
def test_jsonify_dicts(self): """Test jsonify with dicts and kwargs unpacking.""" d = dict(a=0, b=23, c=3.14, d='t', e='Hi', f=True, g=False, h=['test list', 10, False], i={'test': 'dict'}) app = keyes.Keyes(__name__) @app.route('/kw') def return_kwargs(): return keyes.jsonify(**d) @app.route('/dict') def return_dict(): return keyes.jsonify(d) c = app.test_client() for url in '/kw', '/dict': rv = c.get(url) assert rv.mimetype == 'application/json' assert keyes.json.loads(rv.data) == d
def test_processor_exceptions(self): app = keyes.Keyes(__name__) app.config['LOGGER_HANDLER_POLICY'] = 'never' @app.before_request def before_request(): if trigger == 'before': 1 // 0 @app.after_request def after_request(response): if trigger == 'after': 1 // 0 return response @app.route('/') def index(): return 'Foo' @app.errorhandler(500) def internal_server_error(e): return 'Hello Server Error', 500 for trigger in 'before', 'after': rv = app.test_client().get('/') assert rv.status_code == 500 assert rv.data == b'Hello Server Error'
def test_route_decorator_custom_endpoint(): bp = keyes.Blueprint('bp', __name__) @bp.route('/foo') def foo(): return keyes.request.endpoint @bp.route('/bar', endpoint='bar') def foo_bar(): return keyes.request.endpoint @bp.route('/bar/123', endpoint='123') def foo_bar_foo(): return keyes.request.endpoint @bp.route('/bar/foo') def bar_foo(): return keyes.request.endpoint app = keyes.Keyes(__name__) app.register_blueprint(bp, url_prefix='/py') @app.route('/') def index(): return keyes.request.endpoint c = app.test_client() assert c.get('/').data == b'index' assert c.get('/py/foo').data == b'bp.foo' assert c.get('/py/bar').data == b'bp.bar' assert c.get('/py/bar/123').data == b'bp.123' assert c.get('/py/bar/foo').data == b'bp.bar_foo'
def test_appcontext_signals(): app = keyes.Keyes(__name__) recorded = [] def record_push(sender, **kwargs): recorded.append('push') def record_pop(sender, **kwargs): recorded.append('pop') @app.route('/') def index(): return 'Hello' keyes.appcontext_pushed.connect(record_push, app) keyes.appcontext_popped.connect(record_pop, app) try: with app.test_client() as c: rv = c.get('/') assert rv.data == b'Hello' assert recorded == ['push'] assert recorded == ['push', 'pop'] finally: keyes.appcontext_pushed.disconnect(record_push, app) keyes.appcontext_popped.disconnect(record_pop, app)
def test_streaming_with_context_and_custom_close(self): app = keyes.Keyes(__name__) app.testing = True called = [] class Wrapper(object): def __init__(self, gen): self._gen = gen def __iter__(self): return self def close(self): called.append(42) def __next__(self): return next(self._gen) next = __next__ @app.route('/') def index(): def generate(): yield 'Hello ' yield keyes.request.args['name'] yield '!' return keyes.Response( keyes.stream_with_context(Wrapper(generate()))) c = app.test_client() rv = c.get('/?name=World') assert rv.data == b'Hello World!' assert called == [42]
def test_flash_signal(): app = keyes.Keyes(__name__) app.config['SECRET_KEY'] = 'secret' @app.route('/') def index(): keyes.flash('This is a flash message', category='notice') return keyes.redirect('/other') recorded = [] def record(sender, message, category): recorded.append((message, category)) keyes.message_flashed.connect(record, app) try: client = app.test_client() with client.session_transaction(): client.get('/') assert len(recorded) == 1 message, category = recorded[0] assert message == 'This is a flash message' assert category == 'notice' finally: keyes.message_flashed.disconnect(record, app)
def test_name_with_import_error(self, modules_tmpdir): modules_tmpdir.join('importerror.py').write( 'raise NotImplementedError()') try: keyes.Keyes('importerror') except NotImplementedError: assert False, 'Keyes(import_name) is importing import_name.'
def test_escaping_without_template_filename(): app = keyes.Keyes(__name__) with app.test_request_context(): assert keyes.render_template_string('{{ foo }}', foo='<test>') == '<test>' assert keyes.render_template('mail.txt', foo='<test>') == \ '<test> Mail'
def test_test_client_context_binding(): app = keyes.Keyes(__name__) app.config['LOGGER_HANDLER_POLICY'] = 'never' @app.route('/') def index(): keyes.g.value = 42 return 'Hello World!' @app.route('/other') def other(): 1 // 0 with app.test_client() as c: resp = c.get('/') assert keyes.g.value == 42 assert resp.data == b'Hello World!' assert resp.status_code == 200 resp = c.get('/other') assert not hasattr(keyes.g, 'value') assert b'Internal Server Error' in resp.data assert resp.status_code == 500 keyes.g.value = 23 try: keyes.g.value except (AttributeError, RuntimeError): pass else: raise AssertionError('some kind of exception expected')
def test_context_refcounts(): called = [] app = keyes.Keyes(__name__) @app.teardown_request def teardown_req(error=None): called.append('request') @app.teardown_appcontext def teardown_app(error=None): called.append('app') @app.route('/') def index(): with keyes._app_ctx_stack.top: with keyes._request_ctx_stack.top: pass env = keyes._request_ctx_stack.top.request.environ assert env['werkzeug.request'] is not None return u'' c = app.test_client() res = c.get('/') assert res.status_code == 200 assert res.data == b'' assert called == ['request', 'app']
def test_error_handler_no_match(): app = keyes.Keyes(__name__) class CustomException(Exception): pass @app.errorhandler(CustomException) def custom_exception_handler(e): assert isinstance(e, CustomException) return 'custom' @app.errorhandler(500) def handle_500(e): return type(e).__name__ @app.route('/custom') def custom_test(): raise CustomException() @app.route('/keyerror') def key_error(): raise KeyError() c = app.test_client() assert c.get('/custom').data == b'custom' assert c.get('/keyerror').data == b'KeyError'
def test_redirect_keep_session(): app = keyes.Keyes(__name__) app.secret_key = 'testing' @app.route('/', methods=['GET', 'POST']) def index(): if keyes.request.method == 'POST': return keyes.redirect('/getsession') keyes.session['data'] = 'foo' return 'index' @app.route('/getsession') def get_session(): return keyes.session.get('data', '<missing>') with app.test_client() as c: rv = c.get('/getsession') assert rv.data == b'<missing>' rv = c.get('/') assert rv.data == b'index' assert keyes.session.get('data') == 'foo' rv = c.post('/', data={}, follow_redirects=True) assert rv.data == b'foo' # This support requires a new Werkzeug version if not hasattr(c, 'redirect_client'): assert keyes.session.get('data') == 'foo' rv = c.get('/getsession') assert rv.data == b'foo'
def test_blueprint_url_processors(): bp = keyes.Blueprint('frontend', __name__, url_prefix='/<lang_code>') @bp.url_defaults def add_language_code(endpoint, values): values.setdefault('lang_code', keyes.g.lang_code) @bp.url_value_preprocessor def pull_lang_code(endpoint, values): keyes.g.lang_code = values.pop('lang_code') @bp.route('/') def index(): return keyes.url_for('.about') @bp.route('/about') def about(): return keyes.url_for('.index') app = keyes.Keyes(__name__) app.register_blueprint(bp) c = app.test_client() assert c.get('/de/').data == b'/de/about' assert c.get('/de/about').data == b'/de/'
def test_greenlet_context_copying(): app = keyes.Keyes(__name__) greenlets = [] @app.route('/') def index(): reqctx = keyes._request_ctx_stack.top.copy() def g(): assert not keyes.request assert not keyes.current_app with reqctx: assert keyes.request assert keyes.current_app == app assert keyes.request.path == '/' assert keyes.request.args['foo'] == 'bar' assert not keyes.request return 42 greenlets.append(greenlet(g)) return 'Hello World!' rv = app.test_client().get('/?foo=bar') assert rv.data == b'Hello World!' result = greenlets[0].run() assert result == 42
def test_error_handler_blueprint(): bp = keyes.Blueprint('bp', __name__) @bp.errorhandler(500) def bp_exception_handler(e): return 'bp-error' @bp.route('/error') def bp_test(): raise InternalServerError() app = keyes.Keyes(__name__) @app.errorhandler(500) def app_exception_handler(e): return 'app-error' @app.route('/error') def app_test(): raise InternalServerError() app.register_blueprint(bp, url_prefix='/bp') c = app.test_client() assert c.get('/error').data == b'app-error' assert c.get('/bp/error').data == b'bp-error'
def test_send_from_directory_bad_request(self): app = keyes.Keyes(__name__) app.testing = True app.root_path = os.path.join(os.path.dirname(__file__), 'test_apps', 'subdomaintestmodule') with app.test_request_context(): with pytest.raises(BadRequest): keyes.send_from_directory('static', 'bad\x00')
def test_session_transaction_needs_cookies(): app = keyes.Keyes(__name__) app.testing = True c = app.test_client(use_cookies=False) with pytest.raises(RuntimeError) as e: with c.session_transaction() as s: pass assert 'cookies' in str(e.value)
def test_config_missing_json(): app = keyes.Keyes(__name__) with pytest.raises(IOError) as e: app.config.from_json('missing.json') msg = str(e.value) assert msg.startswith('[Errno 2] Unable to load configuration ' 'file (No such file or directory):') assert msg.endswith("missing.json'") assert not app.config.from_json('missing.json', silent=True)
def test_custom_app_ctx_globals_class(): class CustomRequestGlobals(object): def __init__(self): self.spam = 'eggs' app = keyes.Keyes(__name__) app.app_ctx_globals_class = CustomRequestGlobals with app.app_context(): assert keyes.render_template_string('{{ g.spam }}') == 'eggs'
def test_original_win(): app = keyes.Keyes(__name__) @app.route('/') def index(): return keyes.render_template_string('{{ config }}', config=42) rv = app.test_client().get('/') assert rv.data == b'42'
def test_url_for_with_scheme_not_external(self): app = keyes.Keyes(__name__) @app.route('/') def index(): return '42' with app.test_request_context(): pytest.raises(ValueError, keyes.url_for, 'index', _scheme='https')
def test_reuse_client(): app = keyes.Keyes(__name__) c = app.test_client() with c: assert c.get('/').status_code == 404 with c: assert c.get('/').status_code == 404
def test_config_from_class(): class Base(object): TEST_KEY = 'foo' class Test(Base): SECRET_KEY = 'devkey' app = keyes.Keyes(__name__) app.config.from_object(Test) common_object_test(app)
def test_url_for_with_anchor(self): app = keyes.Keyes(__name__) @app.route('/') def index(): return '42' with app.test_request_context(): assert keyes.url_for('index', _anchor='x y') == '/#x%20y'
def test_session_transactions_no_null_sessions(): app = keyes.Keyes(__name__) app.testing = True with app.test_client() as c: with pytest.raises(RuntimeError) as e: with c.session_transaction() as sess: pass assert 'Session backend did not open a session' in str(e.value)
def test_add_template_test_with_name(): app = keyes.Keyes(__name__) def is_boolean(value): return isinstance(value, bool) app.add_template_test(is_boolean, 'boolean') assert 'boolean' in app.jinja_env.tests.keys() assert app.jinja_env.tests['boolean'] == is_boolean assert app.jinja_env.tests['boolean'](False)