flask/tests/test_reqctx.py

286 lines
7.3 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""
2014-09-01 03:54:45 +08:00
tests.reqctx
2014-09-21 22:47:38 +08:00
~~~~~~~~~~~~
Tests the request context.
:copyright: © 2010 by the Pallets team.
:license: BSD, see LICENSE for more details.
"""
2014-09-02 11:26:52 +08:00
import pytest
import flask
from flask.sessions import SessionInterface
2014-09-21 22:47:38 +08:00
try:
from greenlet import greenlet
except ImportError:
greenlet = None
2014-09-04 03:02:03 +08:00
def test_teardown_on_pop(app):
2014-09-04 02:56:10 +08:00
buffer = []
2014-09-04 02:56:10 +08:00
@app.teardown_request
def end_of_request(exception):
buffer.append(exception)
ctx = app.test_request_context()
ctx.push()
assert buffer == []
ctx.pop()
assert buffer == [None]
def test_teardown_with_previous_exception(app):
2014-09-04 02:56:10 +08:00
buffer = []
2014-09-04 02:56:10 +08:00
@app.teardown_request
def end_of_request(exception):
buffer.append(exception)
try:
raise Exception('dummy')
except Exception:
pass
with app.test_request_context():
assert buffer == []
assert buffer == [None]
def test_teardown_with_handled_exception(app):
buffer = []
@app.teardown_request
def end_of_request(exception):
buffer.append(exception)
with app.test_request_context():
assert buffer == []
try:
raise Exception('dummy')
except Exception:
pass
assert buffer == [None]
def test_proper_test_request_context(app):
2014-09-04 02:56:10 +08:00
app.config.update(
SERVER_NAME='localhost.localdomain:5000'
)
2014-09-04 02:56:10 +08:00
@app.route('/')
def index():
return None
2014-09-04 02:56:10 +08:00
@app.route('/', subdomain='foo')
def sub():
return None
2014-09-04 02:56:10 +08:00
with app.test_request_context('/'):
assert flask.url_for('index', _external=True) == \
'http://localhost.localdomain:5000/'
2014-09-04 02:56:10 +08:00
with app.test_request_context('/'):
assert flask.url_for('sub', _external=True) == \
'http://foo.localhost.localdomain:5000/'
2014-09-02 11:26:52 +08:00
2014-09-04 02:56:10 +08:00
try:
with app.test_request_context('/', environ_overrides={'HTTP_HOST': 'localhost'}):
2014-09-02 11:26:52 +08:00
pass
2014-09-04 02:56:10 +08:00
except ValueError as e:
assert str(e) == (
"the server name provided "
"('localhost.localdomain:5000') does not match the "
"server name from the WSGI environment ('localhost')"
)
2014-09-04 02:56:10 +08:00
app.config.update(SERVER_NAME='localhost')
with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost'}):
pass
app.config.update(SERVER_NAME='localhost:80')
with app.test_request_context('/', environ_overrides={'SERVER_NAME': 'localhost:80'}):
pass
def test_context_binding(app):
2014-09-04 02:56:10 +08:00
@app.route('/')
def index():
return 'Hello %s!' % flask.request.args['name']
2014-09-04 02:56:10 +08:00
@app.route('/meh')
def meh():
return flask.request.url
with app.test_request_context('/?name=World'):
2014-09-02 11:26:52 +08:00
assert index() == 'Hello World!'
2014-09-04 02:56:10 +08:00
with app.test_request_context('/meh'):
assert meh() == 'http://localhost/meh'
assert flask._request_ctx_stack.top is None
def test_context_test(app):
2014-09-04 02:56:10 +08:00
assert not flask.request
assert not flask.has_request_context()
ctx = app.test_request_context()
ctx.push()
try:
assert flask.request
assert flask.has_request_context()
finally:
ctx.pop()
2014-09-04 02:56:10 +08:00
def test_manual_context_binding(app):
2014-09-04 02:56:10 +08:00
@app.route('/')
def index():
return 'Hello %s!' % flask.request.args['name']
ctx = app.test_request_context('/?name=World')
ctx.push()
assert index() == 'Hello World!'
ctx.pop()
with pytest.raises(RuntimeError):
2014-09-04 02:56:10 +08:00
index()
2014-09-04 02:56:10 +08:00
@pytest.mark.skipif(greenlet is None, reason='greenlet not installed')
class TestGreenletContextCopying(object):
2014-09-04 02:56:10 +08:00
def test_greenlet_context_copying(self, app, client):
greenlets = []
@app.route('/')
def index():
flask.session['fizz'] = 'buzz'
reqctx = flask._request_ctx_stack.top.copy()
def g():
assert not flask.request
assert not flask.current_app
with reqctx:
assert flask.request
assert flask.current_app == app
assert flask.request.path == '/'
assert flask.request.args['foo'] == 'bar'
assert flask.session.get('fizz') == 'buzz'
assert not flask.request
return 42
2014-09-04 02:56:10 +08:00
greenlets.append(greenlet(g))
return 'Hello World!'
2014-09-04 02:56:10 +08:00
rv = client.get('/?foo=bar')
assert rv.data == b'Hello World!'
2014-09-04 02:56:10 +08:00
result = greenlets[0].run()
assert result == 42
def test_greenlet_context_copying_api(self, app, client):
greenlets = []
2014-09-04 02:56:10 +08:00
@app.route('/')
def index():
flask.session['fizz'] = 'buzz'
reqctx = flask._request_ctx_stack.top.copy()
@flask.copy_current_request_context
def g():
assert flask.request
assert flask.current_app == app
assert flask.request.path == '/'
assert flask.request.args['foo'] == 'bar'
assert flask.session.get('fizz') == 'buzz'
return 42
greenlets.append(greenlet(g))
return 'Hello World!'
2014-09-04 02:56:10 +08:00
rv = client.get('/?foo=bar')
assert rv.data == b'Hello World!'
2014-09-04 02:56:10 +08:00
result = greenlets[0].run()
assert result == 42
def test_session_error_pops_context():
class SessionError(Exception):
pass
class FailingSessionInterface(SessionInterface):
def open_session(self, app, request):
raise SessionError()
class CustomFlask(flask.Flask):
session_interface = FailingSessionInterface()
app = CustomFlask(__name__)
@app.route('/')
def index():
# shouldn't get here
assert False
response = app.test_client().get('/')
assert response.status_code == 500
assert not flask.request
assert not flask.current_app
def test_bad_environ_raises_bad_request():
app = flask.Flask(__name__)
# We cannot use app.test_client() for the Unicode-rich Host header,
# because werkzeug enforces latin1 on Python 2.
# However it works when actually passed to the server.
from flask.testing import make_test_environ_builder
builder = make_test_environ_builder(app)
environ = builder.get_environ()
# use a non-printable character in the Host - this is key to this test
environ['HTTP_HOST'] = u'\x8a'
with app.request_context(environ):
response = app.full_dispatch_request()
assert response.status_code == 400
def test_environ_for_valid_idna_completes():
app = flask.Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
# We cannot use app.test_client() for the Unicode-rich Host header,
# because werkzeug enforces latin1 on Python 2.
# However it works when actually passed to the server.
from flask.testing import make_test_environ_builder
builder = make_test_environ_builder(app)
environ = builder.get_environ()
# these characters are all IDNA-compatible
environ['HTTP_HOST'] = u'ąśźäüжŠßя.com'
with app.request_context(environ):
response = app.full_dispatch_request()
assert response.status_code == 200
def test_normal_environ_completes():
app = flask.Flask(__name__)
@app.route('/')
def index():
return 'Hello World!'
response = app.test_client().get('/', headers={'host': 'xn--on-0ia.com'})
assert response.status_code == 200