diff --git a/CHANGES b/CHANGES index 207da344..cc763166 100644 --- a/CHANGES +++ b/CHANGES @@ -97,6 +97,8 @@ Major release, unreleased - ``Request.module`` - use ``Request.blueprint`` instead. - The ``request.json`` property is no longer deprecated. (`#1421`_) +- Support passing an existing ``EnvironBuilder`` or ``dict`` to + ``test_client.open``. (`#2412`_) .. _#1421: https://github.com/pallets/flask/issues/1421 .. _#1489: https://github.com/pallets/flask/pull/1489 @@ -124,6 +126,7 @@ Major release, unreleased .. _#2374: https://github.com/pallets/flask/pull/2374 .. _#2373: https://github.com/pallets/flask/pull/2373 .. _#2385: https://github.com/pallets/flask/issues/2385 +.. _#2412: https://github.com/pallets/flask/pull/2412 Version 0.12.2 -------------- diff --git a/flask/testing.py b/flask/testing.py index f73454af..d5109ce1 100644 --- a/flask/testing.py +++ b/flask/testing.py @@ -144,19 +144,41 @@ class FlaskClient(Client): self.cookie_jar.extract_wsgi(c.request.environ, headers) def open(self, *args, **kwargs): - kwargs.setdefault('environ_overrides', {}) \ - ['flask._preserve_context'] = self.preserve_context - kwargs.setdefault('environ_base', self.environ_base) - 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) - return Client.open(self, builder, - as_tuple=as_tuple, - buffered=buffered, - follow_redirects=follow_redirects) + if ( + not kwargs and len(args) == 1 + and isinstance(args[0], (EnvironBuilder, dict)) + ): + environ = self.environ_base.copy() + + if isinstance(args[0], EnvironBuilder): + environ.update(args[0].get_environ()) + else: + environ.update(args[0]) + + environ['flask._preserve_context'] = self.preserve_context + else: + kwargs.setdefault('environ_overrides', {}) \ + ['flask._preserve_context'] = self.preserve_context + kwargs.setdefault('environ_base', self.environ_base) + builder = make_test_environ_builder( + self.application, *args, **kwargs + ) + + try: + environ = builder.get_environ() + finally: + builder.close() + + return Client.open( + self, environ, + as_tuple=as_tuple, + buffered=buffered, + follow_redirects=follow_redirects + ) def __enter__(self): if self.preserve_context: diff --git a/tests/test_testing.py b/tests/test_testing.py index 068eb209..e94da483 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -15,6 +15,7 @@ import werkzeug from flask._compat import text_type from flask.json import jsonify +from flask.testing import make_test_environ_builder def test_environ_defaults_from_config(app, client): @@ -74,6 +75,23 @@ def test_environ_base_modified(app, client, app_ctx): assert flask.g.user_agent == 'Bar' +def test_client_open_environ(app, client, request): + @app.route('/index') + def index(): + return flask.request.remote_addr + + builder = make_test_environ_builder(app, path='/index', method='GET') + request.addfinalizer(builder.close) + + rv = client.open(builder) + assert rv.data == b'127.0.0.1' + + environ = builder.get_environ() + client.environ_base['REMOTE_ADDR'] = '127.0.0.2' + rv = client.open(environ) + assert rv.data == b'127.0.0.2' + + def test_specify_url_scheme(app, client): @app.route('/') def index():