| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | # -*- coding: utf-8 -*- | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2014-09-01 03:54:45 +08:00
										 |  |  |     tests.reqctx | 
					
						
							| 
									
										
										
										
											2014-09-21 22:47:38 +08:00
										 |  |  |     ~~~~~~~~~~~~ | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     Tests the request context. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-23 04:09:09 +08:00
										 |  |  |     :copyright: 2010 Pallets | 
					
						
							|  |  |  |     :license: BSD-3-Clause | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-02 11:26:52 +08:00
										 |  |  | import pytest | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | import flask | 
					
						
							| 
									
										
										
										
											2017-04-23 04:39:54 +08:00
										 |  |  | from flask.sessions import SessionInterface | 
					
						
							| 
									
										
										
										
											2014-09-21 22:47:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | try: | 
					
						
							|  |  |  |     from greenlet import greenlet | 
					
						
							|  |  |  | except ImportError: | 
					
						
							|  |  |  |     greenlet = None | 
					
						
							| 
									
										
										
										
											2014-09-04 03:02:03 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | def test_teardown_on_pop(app): | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |     buffer = [] | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | def test_teardown_with_previous_exception(app): | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |     buffer = [] | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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] | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | def test_teardown_with_handled_exception(app): | 
					
						
							| 
									
										
										
										
											2015-03-23 23:17:19 +08:00
										 |  |  |     buffer = [] | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 23:17:19 +08:00
										 |  |  |     @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] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | def test_proper_test_request_context(app): | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |     app.config.update( | 
					
						
							|  |  |  |         SERVER_NAME='localhost.localdomain:5000' | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |     @app.route('/') | 
					
						
							|  |  |  |     def index(): | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2013-10-17 02:12:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |     @app.route('/', subdomain='foo') | 
					
						
							|  |  |  |     def sub(): | 
					
						
							|  |  |  |         return None | 
					
						
							| 
									
										
										
										
											2013-10-17 02:12:20 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |     with app.test_request_context('/'): | 
					
						
							|  |  |  |         assert flask.url_for('index', _external=True) == \ | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  |                'http://localhost.localdomain:5000/' | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |     with app.test_request_context('/'): | 
					
						
							|  |  |  |         assert flask.url_for('sub', _external=True) == \ | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  |                'http://foo.localhost.localdomain:5000/' | 
					
						
							| 
									
										
										
										
											2014-09-02 11:26:52 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-06-08 04:23:13 +08:00
										 |  |  |     # suppress Werkzeug 0.15 warning about name mismatch | 
					
						
							|  |  |  |     with pytest.warns(None): | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |         with app.test_request_context('/', environ_overrides={'HTTP_HOST': 'localhost'}): | 
					
						
							| 
									
										
										
										
											2014-09-02 11:26:52 +08:00
										 |  |  |             pass | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | def test_context_binding(app): | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |     @app.route('/') | 
					
						
							|  |  |  |     def index(): | 
					
						
							|  |  |  |         return 'Hello %s!' % flask.request.args['name'] | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 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: | 
					
						
							| 
									
										
										
										
											2013-05-14 18:00:04 +08:00
										 |  |  |         ctx.pop() | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +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() | 
					
						
							| 
									
										
										
										
											2016-03-04 19:30:40 +08:00
										 |  |  |     with pytest.raises(RuntimeError): | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  |         index() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | @pytest.mark.skipif(greenlet is None, reason='greenlet not installed') | 
					
						
							| 
									
										
										
										
											2017-05-24 07:51:50 +08:00
										 |  |  | class TestGreenletContextCopying(object): | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:51:50 +08:00
										 |  |  |     def test_greenlet_context_copying(self, app, client): | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |         greenlets = [] | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |         @app.route('/') | 
					
						
							|  |  |  |         def index(): | 
					
						
							|  |  |  |             reqctx = flask._request_ctx_stack.top.copy() | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |             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 not flask.request | 
					
						
							|  |  |  |                 return 42 | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |             greenlets.append(greenlet(g)) | 
					
						
							|  |  |  |             return 'Hello World!' | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |         rv = client.get('/?foo=bar') | 
					
						
							|  |  |  |         assert rv.data == b'Hello World!' | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |         result = greenlets[0].run() | 
					
						
							|  |  |  |         assert result == 42 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:51:50 +08:00
										 |  |  |     def test_greenlet_context_copying_api(self, app, client): | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |         greenlets = [] | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |         @app.route('/') | 
					
						
							|  |  |  |         def index(): | 
					
						
							|  |  |  |             reqctx = flask._request_ctx_stack.top.copy() | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |             @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' | 
					
						
							|  |  |  |                 return 42 | 
					
						
							| 
									
										
										
										
											2017-05-24 06:18:39 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |             greenlets.append(greenlet(g)) | 
					
						
							|  |  |  |             return 'Hello World!' | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |         rv = client.get('/?foo=bar') | 
					
						
							|  |  |  |         assert rv.data == b'Hello World!' | 
					
						
							| 
									
										
										
										
											2014-09-04 02:56:10 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-05-24 07:13:19 +08:00
										 |  |  |         result = greenlets[0].run() | 
					
						
							|  |  |  |         assert result == 42 | 
					
						
							| 
									
										
										
										
											2017-04-23 04:39:54 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 |