diff --git a/flask/app.py b/flask/app.py index 51b50d34..efcc8ee0 100644 --- a/flask/app.py +++ b/flask/app.py @@ -2017,10 +2017,19 @@ class Flask(_PackageBoundObject): def test_request_context(self, *args, **kwargs): """Creates a WSGI environment from the given values (see :class:`werkzeug.test.EnvironBuilder` for more information, this - function accepts the same arguments). + function accepts the same arguments plus two additional). + + Additional arguments (only if ``base_url`` is not specified): + + :param subdomain: subdomain to use for route matching + :param url_scheme: scheme for the request, default + ``PREFERRED_URL_SCHEME`` or ``http``. """ + 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: diff --git a/flask/testing.py b/flask/testing.py index 31600245..86e433bc 100644 --- a/flask/testing.py +++ b/flask/testing.py @@ -21,19 +21,37 @@ except ImportError: from urlparse import urlsplit as url_parse -def make_test_environ_builder(app, path='/', base_url=None, *args, **kwargs): +def make_test_environ_builder( + app, path='/', base_url=None, subdomain=None, url_scheme=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') + + assert ( + not (base_url or subdomain or url_scheme) + or (base_url is not None) != bool(subdomain or url_scheme) + ), 'Cannot pass "subdomain" or "url_scheme" with "base_url".' + if base_url is None: + http_host = app.config.get('SERVER_NAME') or 'localhost' + app_root = app.config.get('APPLICATION_ROOT') or '/' + + if subdomain: + http_host = '{0}.{1}'.format(subdomain, http_host) + + if url_scheme is None: + url_scheme = app.config.get('PREFERRED_URL_SCHEME') or 'http' + url = url_parse(path) - base_url = 'http://%s/' % (url.netloc or http_host or 'localhost') - if app_root: - base_url += app_root.lstrip('/') - if url.netloc: - path = url.path - if url.query: - path += '?' + url.query + base_url = '{0}://{1}/{2}'.format( + url_scheme, url.netloc or http_host, app_root.lstrip('/') + ) + path = url.path + + if url.query: + sep = b'?' if isinstance(url.query, bytes) else '?' + path += sep + url.query + return EnvironBuilder(path, base_url, *args, **kwargs) diff --git a/tests/test_testing.py b/tests/test_testing.py index 7ec0c993..0c8ddebe 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -73,6 +73,38 @@ def test_environ_base_modified(app, client, app_ctx): 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'