# -*- coding: utf-8 -*- """ tests.testing ~~~~~~~~~~~~~ Test client and more. :copyright: (c) 2015 by Armin Ronacher. :license: BSD, see LICENSE for more details. """ import pytest import flask import werkzeug from flask._compat import text_type def test_environ_defaults_from_config(app, client): app.config['SERVER_NAME'] = 'example.com:1234' app.config['APPLICATION_ROOT'] = '/foo' @app.route('/') def index(): return flask.request.url ctx = app.test_request_context() assert ctx.request.url == 'http://example.com:1234/foo/' rv = client.get('/') assert rv.data == b'http://example.com:1234/foo/' def test_environ_defaults(app, client, app_ctx, req_ctx): @app.route('/') def index(): return flask.request.url ctx = app.test_request_context() assert ctx.request.url == 'http://localhost/' with client: rv = client.get('/') assert rv.data == b'http://localhost/' def test_environ_base_default(app, client, app_ctx): @app.route('/') def index(): flask.g.user_agent = flask.request.headers["User-Agent"] return flask.request.remote_addr rv = client.get('/') assert rv.data == b'127.0.0.1' assert flask.g.user_agent == 'werkzeug/' + werkzeug.__version__ def test_environ_base_modified(app, client, app_ctx): @app.route('/') def index(): flask.g.user_agent = flask.request.headers["User-Agent"] return flask.request.remote_addr client.environ_base['REMOTE_ADDR'] = '0.0.0.0' client.environ_base['HTTP_USER_AGENT'] = 'Foo' rv = client.get('/') assert rv.data == b'0.0.0.0' assert flask.g.user_agent == 'Foo' client.environ_base['REMOTE_ADDR'] = '0.0.0.1' client.environ_base['HTTP_USER_AGENT'] = 'Bar' rv = client.get('/') assert rv.data == b'0.0.0.1' assert flask.g.user_agent == 'Bar' def test_specify_url_scheme(app, client): @app.route('/') def index(): return flask.request.url ctx = app.test_request_context(url_scheme='https') assert ctx.request.url == 'https://localhost/' rv = client.get('/', url_scheme='https') assert rv.data == b'https://localhost/' def test_blueprint_with_subdomain(app, client): app.config['SERVER_NAME'] = 'example.com:1234' app.config['APPLICATION_ROOT'] = '/foo' bp = flask.Blueprint('company', __name__, subdomain='xxx') @bp.route('/') def index(): return flask.request.url app.register_blueprint(bp) ctx = app.test_request_context('/', subdomain='xxx') assert ctx.request.url == 'http://xxx.example.com:1234/foo/' assert ctx.request.blueprint == bp.name rv = client.get('/', subdomain='xxx') assert rv.data == b'http://xxx.example.com:1234/foo/' def test_redirect_keep_session(app, client, app_ctx): app.secret_key = 'testing' @app.route('/', methods=['GET', 'POST']) def index(): if flask.request.method == 'POST': return flask.redirect('/getsession') flask.session['data'] = 'foo' return 'index' @app.route('/getsession') def get_session(): return flask.session.get('data', '') with client: rv = client.get('/getsession') assert rv.data == b'' rv = client.get('/') assert rv.data == b'index' assert flask.session.get('data') == 'foo' rv = client.post('/', data={}, follow_redirects=True) assert rv.data == b'foo' # This support requires a new Werkzeug version if not hasattr(client, 'redirect_client'): assert flask.session.get('data') == 'foo' rv = client.get('/getsession') assert rv.data == b'foo' def test_session_transactions(app, client): app.secret_key = 'testing' @app.route('/') def index(): return text_type(flask.session['foo']) with client: with client.session_transaction() as sess: assert len(sess) == 0 sess['foo'] = [42] assert len(sess) == 1 rv = client.get('/') assert rv.data == b'[42]' with client.session_transaction() as sess: assert len(sess) == 1 assert sess['foo'] == [42] def test_session_transactions_no_null_sessions(): app = flask.Flask(__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_session_transactions_keep_context(app, client, req_ctx): app.secret_key = 'testing' rv = client.get('/') req = flask.request._get_current_object() assert req is not None with client.session_transaction(): assert req is flask.request._get_current_object() def test_session_transaction_needs_cookies(app): 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_test_client_context_binding(app, client): app.config['LOGGER_HANDLER_POLICY'] = 'never' app.testing = False @app.route('/') def index(): flask.g.value = 42 return 'Hello World!' @app.route('/other') def other(): 1 // 0 with client: resp = client.get('/') assert flask.g.value == 42 assert resp.data == b'Hello World!' assert resp.status_code == 200 resp = client.get('/other') assert not hasattr(flask.g, 'value') assert b'Internal Server Error' in resp.data assert resp.status_code == 500 flask.g.value = 23 try: flask.g.value except (AttributeError, RuntimeError): pass else: raise AssertionError('some kind of exception expected') def test_reuse_client(client): c = client with c: assert client.get('/').status_code == 404 with c: assert client.get('/').status_code == 404 def test_test_client_calls_teardown_handlers(app, client): called = [] @app.teardown_request def remember(error): called.append(error) with client: assert called == [] client.get('/') assert called == [] assert called == [None] del called[:] with client: assert called == [] client.get('/') assert called == [] client.get('/') assert called == [None] assert called == [None, None] def test_full_url_request(app, client): @app.route('/action', methods=['POST']) def action(): return 'x' with client: rv = client.post('http://domain.com/action?vodka=42', data={'gin': 43}) assert rv.status_code == 200 assert 'gin' in flask.request.form assert 'vodka' in flask.request.args def test_subdomain(app, client): app.config['SERVER_NAME'] = 'example.com' @app.route('/', subdomain='') def view(company_id): return company_id with app.test_request_context(): url = flask.url_for('view', company_id='xxx') with client: response = client.get(url) assert 200 == response.status_code assert b'xxx' == response.data def test_nosubdomain(app, client): app.config['SERVER_NAME'] = 'example.com' @app.route('/') def view(company_id): return company_id with app.test_request_context(): url = flask.url_for('view', company_id='xxx') with client: response = client.get(url) assert 200 == response.status_code assert b'xxx' == response.data