From e853a0f73959ad12cdabc2d74324cdc9329ae794 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 25 Aug 2011 20:47:50 +0100 Subject: [PATCH] The test client and test_request_context are now both using the same logic internally for creating the environ. Also they use APPLICATION_ROOT now. --- CHANGES | 3 +++ docs/api.rst | 2 +- flask/app.py | 21 +++++++-------------- flask/testing.py | 26 ++++++++++++-------------- tests/flask_tests.py | 15 +++++++++++++++ 5 files changed, 38 insertions(+), 29 deletions(-) diff --git a/CHANGES b/CHANGES index a451b978..6727e98f 100644 --- a/CHANGES +++ b/CHANGES @@ -35,6 +35,9 @@ Relase date to be decided, codename to be chosen. - Added the ``APPLICATION_ROOT`` configuration variable. - Implemented :meth:`~flask.testing.TestClient.session_transaction` to easily modify sessions from the test environment. +- Refactored test client internally. The ``APPLICATION_ROOT`` configuration + variable as well as ``SERVER_NAME`` are now properly used by the test client + as defaults. Version 0.7.3 ------------- diff --git a/docs/api.rst b/docs/api.rst index f4fab86f..1dc25eb1 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -223,7 +223,7 @@ Test Client .. currentmodule:: flask.testing -.. autoclass:: TestClient +.. autoclass:: FlaskClient :members: diff --git a/flask/app.py b/flask/app.py index 20cbca52..b4ae64a5 100644 --- a/flask/app.py +++ b/flask/app.py @@ -706,7 +706,7 @@ class Flask(_PackageBoundObject): rv = c.get('/?vodka=42') assert request.args['vodka'] == '42' - See :class:`~flask.testing.TestClient` for more information. + See :class:`~flask.testing.FlaskClient` for more information. .. versionchanged:: 0.4 added support for `with` block usage for the client. @@ -1481,19 +1481,12 @@ class Flask(_PackageBoundObject): :func:`werkzeug.test.EnvironBuilder` for more information, this function accepts the same arguments). """ - from werkzeug.test import create_environ - environ_overrides = kwargs.setdefault('environ_overrides', {}) - if self.config.get('SERVER_NAME'): - server_name = self.config.get('SERVER_NAME') - if ':' not in server_name: - http_host, http_port = server_name, '80' - else: - http_host, http_port = server_name.split(':', 1) - - environ_overrides.setdefault('SERVER_NAME', server_name) - environ_overrides.setdefault('HTTP_HOST', server_name) - environ_overrides.setdefault('SERVER_PORT', http_port) - return self.request_context(create_environ(*args, **kwargs)) + from flask.testing import make_test_environ_builder + builder = make_test_environ_builder(self, *args, **kwargs) + try: + return self.request_context(builder.get_environ()) + finally: + builder.close() def wsgi_app(self, environ, start_response): """The actual WSGI application. This is not implemented in diff --git a/flask/testing.py b/flask/testing.py index dfdaff57..c4d18ca2 100644 --- a/flask/testing.py +++ b/flask/testing.py @@ -15,6 +15,17 @@ from werkzeug.test import Client, EnvironBuilder from flask import _request_ctx_stack +def make_test_environ_builder(app, path='/', base_url=None, *args, **kwargs): + """Creates a new test builder with some application defaults thrown in.""" + http_host = app.config.get('SERVER_NAME') + app_root = app.config.get('APPLICATION_ROOT') + if base_url is None: + base_url = 'http://%s/' % (http_host or 'localhost') + if app_root: + base_url += app_root.lstrip('/') + return EnvironBuilder(path, base_url, *args, **kwargs) + + class FlaskClient(Client): """Works like a regular Werkzeug test client but has some knowledge about how Flask works to defer the cleanup of the request context stack to the @@ -83,21 +94,8 @@ class FlaskClient(Client): as_tuple = kwargs.pop('as_tuple', False) buffered = kwargs.pop('buffered', False) follow_redirects = kwargs.pop('follow_redirects', False) + builder = make_test_environ_builder(self.application, *args, **kwargs) - builder = EnvironBuilder(*args, **kwargs) - - if self.application.config.get('SERVER_NAME'): - server_name = self.application.config.get('SERVER_NAME') - if ':' not in server_name: - http_host, http_port = server_name, None - else: - http_host, http_port = server_name.split(':', 1) - if builder.base_url == 'http://localhost/': - # Default Generated Base URL - if http_port != None: - builder.host = http_host + ':' + http_port - else: - builder.host = http_host old = _request_ctx_stack.top try: return Client.open(self, builder, diff --git a/tests/flask_tests.py b/tests/flask_tests.py index 62814882..aa8f2cf3 100644 --- a/tests/flask_tests.py +++ b/tests/flask_tests.py @@ -1042,6 +1042,21 @@ class BasicFunctionalityTestCase(FlaskTestCase): class TestToolsTestCase(FlaskTestCase): + def test_environ_defaults_from_config(self): + app = flask.Flask(__name__) + app.testing = True + 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() + self.assertEqual(ctx.request.url, 'http://example.com:1234/foo/') + with app.test_client() as c: + rv = c.get('/') + self.assertEqual(rv.data, 'http://example.com:1234/foo/') + def test_session_transactions(self): app = flask.Flask(__name__) app.testing = True