sanic/tests/test_views.py

261 lines
7.0 KiB
Python
Raw Normal View History

import pytest as pytest
2017-02-02 21:24:16 +00:00
from sanic.exceptions import InvalidUsage
from sanic.response import text, HTTPResponse
2017-02-02 21:24:16 +00:00
from sanic.views import HTTPMethodView, CompositionView
from sanic.blueprints import Blueprint
from sanic.request import Request
from sanic.constants import HTTP_METHODS
@pytest.mark.parametrize('method', HTTP_METHODS)
2018-08-26 15:43:14 +01:00
def test_methods(app, method):
2016-11-26 06:45:08 +00:00
class DummyView(HTTPMethodView):
2017-03-14 18:53:58 +00:00
async def get(self, request):
assert request.stream is None
return text('', headers={'method': 'GET'})
2016-11-26 06:45:08 +00:00
def post(self, request):
return text('', headers={'method': 'POST'})
2017-03-14 18:53:58 +00:00
async def put(self, request):
return text('', headers={'method': 'PUT'})
def head(self, request):
return text('', headers={'method': 'HEAD'})
def options(self, request):
return text('', headers={'method': 'OPTIONS'})
2017-03-14 18:53:58 +00:00
async def patch(self, request):
return text('', headers={'method': 'PATCH'})
2016-11-26 06:45:08 +00:00
def delete(self, request):
return text('', headers={'method': 'DELETE'})
2017-01-07 04:30:23 +00:00
app.add_route(DummyView.as_view(), '/')
assert app.is_request_stream is False
2017-02-14 19:51:20 +00:00
request, response = getattr(app.test_client, method.lower())('/')
assert response.headers['method'] == method
2018-08-26 15:43:14 +01:00
def test_unexisting_methods(app):
2016-11-26 06:45:08 +00:00
class DummyView(HTTPMethodView):
2016-11-26 06:45:08 +00:00
def get(self, request):
return text('I am get method')
2017-01-07 04:30:23 +00:00
app.add_route(DummyView.as_view(), '/')
2017-02-14 19:51:20 +00:00
request, response = app.test_client.get('/')
assert response.text == 'I am get method'
2017-02-14 19:51:20 +00:00
request, response = app.test_client.post('/')
assert response.text == 'Error: Method POST not allowed for URL /'
2018-08-26 15:43:14 +01:00
def test_argument_methods(app):
2016-11-26 06:45:08 +00:00
class DummyView(HTTPMethodView):
2016-11-26 06:45:08 +00:00
def get(self, request, my_param_here):
return text('I am get method with %s' % my_param_here)
2017-01-07 04:30:23 +00:00
app.add_route(DummyView.as_view(), '/<my_param_here>')
2017-02-14 19:51:20 +00:00
request, response = app.test_client.get('/test123')
assert response.text == 'I am get method with test123'
2018-08-26 15:43:14 +01:00
def test_with_bp(app):
bp = Blueprint('test_text')
2016-11-26 06:45:08 +00:00
class DummyView(HTTPMethodView):
2016-11-26 06:45:08 +00:00
def get(self, request):
assert request.stream is None
return text('I am get method')
2017-01-07 04:30:23 +00:00
bp.add_route(DummyView.as_view(), '/')
app.blueprint(bp)
2017-02-14 19:51:20 +00:00
request, response = app.test_client.get('/')
assert app.is_request_stream is False
assert response.text == 'I am get method'
2018-08-26 15:43:14 +01:00
def test_with_bp_with_url_prefix(app):
bp = Blueprint('test_text', url_prefix='/test1')
2016-11-26 06:45:08 +00:00
class DummyView(HTTPMethodView):
2016-11-26 06:45:08 +00:00
def get(self, request):
return text('I am get method')
2017-01-07 04:30:23 +00:00
bp.add_route(DummyView.as_view(), '/')
app.blueprint(bp)
2017-02-14 19:51:20 +00:00
request, response = app.test_client.get('/test1/')
assert response.text == 'I am get method'
2018-08-26 15:43:14 +01:00
def test_with_middleware(app):
2016-11-26 06:45:08 +00:00
class DummyView(HTTPMethodView):
2016-11-26 06:45:08 +00:00
def get(self, request):
return text('I am get method')
2017-01-07 04:30:23 +00:00
app.add_route(DummyView.as_view(), '/')
results = []
@app.middleware
async def handler(request):
results.append(request)
2017-02-14 19:51:20 +00:00
request, response = app.test_client.get('/')
assert response.text == 'I am get method'
assert type(results[0]) is Request
2018-08-26 15:43:14 +01:00
def test_with_middleware_response(app):
results = []
@app.middleware('request')
2018-10-22 21:25:38 +01:00
async def process_request(request):
results.append(request)
@app.middleware('response')
async def process_response(request, response):
results.append(request)
results.append(response)
2016-11-26 06:45:08 +00:00
class DummyView(HTTPMethodView):
2016-11-26 06:45:08 +00:00
def get(self, request):
return text('I am get method')
2017-01-07 04:30:23 +00:00
app.add_route(DummyView.as_view(), '/')
2017-02-14 19:51:20 +00:00
request, response = app.test_client.get('/')
assert response.text == 'I am get method'
assert type(results[0]) is Request
assert type(results[1]) is Request
assert isinstance(results[2], HTTPResponse)
2017-01-07 05:13:49 +00:00
2018-08-26 15:43:14 +01:00
def test_with_custom_class_methods(app):
2017-01-07 05:13:49 +00:00
class DummyView(HTTPMethodView):
global_var = 0
def _iternal_method(self):
self.global_var += 10
def get(self, request):
self._iternal_method()
2018-10-22 21:25:38 +01:00
return text('I am get method and global var '
'is {}'.format(self.global_var))
2017-01-07 05:13:49 +00:00
app.add_route(DummyView.as_view(), '/')
2017-02-14 19:51:20 +00:00
request, response = app.test_client.get('/')
2017-01-07 05:13:49 +00:00
assert response.text == 'I am get method and global var is 10'
2018-08-26 15:43:14 +01:00
def test_with_decorator(app):
2017-01-07 05:13:49 +00:00
results = []
def stupid_decorator(view):
def decorator(*args, **kwargs):
results.append(1)
return view(*args, **kwargs)
return decorator
class DummyView(HTTPMethodView):
decorators = [stupid_decorator]
def get(self, request):
return text('I am get method')
app.add_route(DummyView.as_view(), '/')
2017-02-14 19:51:20 +00:00
request, response = app.test_client.get('/')
2017-01-07 05:13:49 +00:00
assert response.text == 'I am get method'
assert results[0] == 1
2017-02-02 21:24:16 +00:00
def test_composition_view_rejects_incorrect_methods():
def foo(request):
return text('Foo')
view = CompositionView()
with pytest.raises(InvalidUsage) as e:
view.add(['GET', 'FOO'], foo)
assert str(e.value) == 'FOO is not a valid HTTP method.'
def test_composition_view_rejects_duplicate_methods():
def foo(request):
return text('Foo')
view = CompositionView()
with pytest.raises(InvalidUsage) as e:
view.add(['GET', 'POST', 'GET'], foo)
assert str(e.value) == 'Method GET is already registered.'
2017-02-13 16:50:09 +00:00
@pytest.mark.parametrize('method', HTTP_METHODS)
2018-08-26 15:43:14 +01:00
def test_composition_view_runs_methods_as_expected(app, method):
2017-02-02 21:24:16 +00:00
view = CompositionView()
def first(request):
assert request.stream is None
return text('first method')
view.add(['GET', 'POST', 'PUT'], first)
2017-02-02 21:24:16 +00:00
view.add(['DELETE', 'PATCH'], lambda x: text('second method'))
app.add_route(view, '/')
assert app.is_request_stream is False
2017-02-02 21:24:16 +00:00
2017-02-13 16:50:09 +00:00
if method in ['GET', 'POST', 'PUT']:
2017-02-14 19:51:20 +00:00
request, response = getattr(app.test_client, method.lower())('/')
2017-02-02 21:24:16 +00:00
assert response.text == 'first method'
2018-12-13 17:50:50 +00:00
response = view(request)
assert response.body.decode() == 'first method'
2017-02-13 16:50:09 +00:00
if method in ['DELETE', 'PATCH']:
2017-02-14 19:51:20 +00:00
request, response = getattr(app.test_client, method.lower())('/')
2017-02-02 21:24:16 +00:00
assert response.text == 'second method'
2018-12-13 17:50:50 +00:00
response = view(request)
assert response.body.decode() == 'second method'
2017-02-13 16:45:55 +00:00
2017-02-13 16:50:09 +00:00
@pytest.mark.parametrize('method', HTTP_METHODS)
2018-08-26 15:43:14 +01:00
def test_composition_view_rejects_invalid_methods(app, method):
2017-02-02 21:24:16 +00:00
view = CompositionView()
view.add(['GET', 'POST', 'PUT'], lambda x: text('first method'))
app.add_route(view, '/')
2017-02-13 16:50:09 +00:00
if method in ['GET', 'POST', 'PUT']:
2017-02-14 19:51:20 +00:00
request, response = getattr(app.test_client, method.lower())('/')
2017-02-13 16:50:09 +00:00
assert response.status == 200
assert response.text == 'first method'
if method in ['DELETE', 'PATCH']:
2017-02-14 19:51:20 +00:00
request, response = getattr(app.test_client, method.lower())('/')
2017-02-02 21:24:16 +00:00
assert response.status == 405