2017-01-28 04:05:46 +00:00
|
|
|
import pytest as pytest
|
|
|
|
|
2016-11-25 07:10:25 +00:00
|
|
|
from sanic import Sanic
|
2017-02-02 21:24:16 +00:00
|
|
|
from sanic.exceptions import InvalidUsage
|
2016-11-25 07:10:25 +00:00
|
|
|
from sanic.response import text, HTTPResponse
|
2017-02-02 21:24:16 +00:00
|
|
|
from sanic.views import HTTPMethodView, CompositionView
|
2016-11-25 07:10:25 +00:00
|
|
|
from sanic.blueprints import Blueprint
|
|
|
|
from sanic.request import Request
|
2017-01-28 04:05:46 +00:00
|
|
|
from sanic.constants import HTTP_METHODS
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
|
2017-01-28 04:05:46 +00:00
|
|
|
@pytest.mark.parametrize('method', HTTP_METHODS)
|
|
|
|
def test_methods(method):
|
2016-11-25 07:10:25 +00:00
|
|
|
app = Sanic('test_methods')
|
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
class DummyView(HTTPMethodView):
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2017-03-14 18:53:58 +00:00
|
|
|
async def get(self, request):
|
2017-01-28 04:13:16 +00:00
|
|
|
return text('', headers={'method': 'GET'})
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
def post(self, request):
|
2017-01-28 04:13:16 +00:00
|
|
|
return text('', headers={'method': 'POST'})
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2017-03-14 18:53:58 +00:00
|
|
|
async def put(self, request):
|
2017-01-28 04:13:16 +00:00
|
|
|
return text('', headers={'method': 'PUT'})
|
2017-01-28 04:05:46 +00:00
|
|
|
|
|
|
|
def head(self, request):
|
2017-01-28 04:13:16 +00:00
|
|
|
return text('', headers={'method': 'HEAD'})
|
2017-01-28 04:05:46 +00:00
|
|
|
|
|
|
|
def options(self, request):
|
2017-01-28 04:13:16 +00:00
|
|
|
return text('', headers={'method': 'OPTIONS'})
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2017-03-14 18:53:58 +00:00
|
|
|
async def patch(self, request):
|
2017-01-28 04:13:16 +00:00
|
|
|
return text('', headers={'method': 'PATCH'})
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
def delete(self, request):
|
2017-01-28 04:13:16 +00:00
|
|
|
return text('', headers={'method': 'DELETE'})
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2017-01-07 04:30:23 +00:00
|
|
|
app.add_route(DummyView.as_view(), '/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2017-02-14 19:51:20 +00:00
|
|
|
request, response = getattr(app.test_client, method.lower())('/')
|
2017-01-28 04:13:16 +00:00
|
|
|
assert response.headers['method'] == method
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_unexisting_methods():
|
|
|
|
app = Sanic('test_unexisting_methods')
|
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
class DummyView(HTTPMethodView):
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
def get(self, request):
|
2016-11-25 07:10:25 +00:00
|
|
|
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('/')
|
2016-11-25 07:10:25 +00:00
|
|
|
assert response.text == 'I am get method'
|
2017-02-14 19:51:20 +00:00
|
|
|
request, response = app.test_client.post('/')
|
2016-11-25 07:10:25 +00:00
|
|
|
assert response.text == 'Error: Method POST not allowed for URL /'
|
|
|
|
|
|
|
|
|
|
|
|
def test_argument_methods():
|
|
|
|
app = Sanic('test_argument_methods')
|
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
class DummyView(HTTPMethodView):
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
def get(self, request, my_param_here):
|
2016-11-25 07:10:25 +00:00
|
|
|
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>')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2017-02-14 19:51:20 +00:00
|
|
|
request, response = app.test_client.get('/test123')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
assert response.text == 'I am get method with test123'
|
|
|
|
|
|
|
|
|
|
|
|
def test_with_bp():
|
|
|
|
app = Sanic('test_with_bp')
|
|
|
|
bp = Blueprint('test_text')
|
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
class DummyView(HTTPMethodView):
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
def get(self, request):
|
2016-11-25 07:10:25 +00:00
|
|
|
return text('I am get method')
|
|
|
|
|
2017-01-07 04:30:23 +00:00
|
|
|
bp.add_route(DummyView.as_view(), '/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
app.blueprint(bp)
|
2017-02-14 19:51:20 +00:00
|
|
|
request, response = app.test_client.get('/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
assert response.text == 'I am get method'
|
|
|
|
|
|
|
|
|
|
|
|
def test_with_bp_with_url_prefix():
|
|
|
|
app = Sanic('test_with_bp_with_url_prefix')
|
|
|
|
bp = Blueprint('test_text', url_prefix='/test1')
|
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
class DummyView(HTTPMethodView):
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
def get(self, request):
|
2016-11-25 07:10:25 +00:00
|
|
|
return text('I am get method')
|
|
|
|
|
2017-01-07 04:30:23 +00:00
|
|
|
bp.add_route(DummyView.as_view(), '/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
app.blueprint(bp)
|
2017-02-14 19:51:20 +00:00
|
|
|
request, response = app.test_client.get('/test1/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
assert response.text == 'I am get method'
|
|
|
|
|
|
|
|
|
|
|
|
def test_with_middleware():
|
|
|
|
app = Sanic('test_with_middleware')
|
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
class DummyView(HTTPMethodView):
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
def get(self, request):
|
2016-11-25 07:10:25 +00:00
|
|
|
return text('I am get method')
|
|
|
|
|
2017-01-07 04:30:23 +00:00
|
|
|
app.add_route(DummyView.as_view(), '/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
results = []
|
|
|
|
|
|
|
|
@app.middleware
|
|
|
|
async def handler(request):
|
|
|
|
results.append(request)
|
|
|
|
|
2017-02-14 19:51:20 +00:00
|
|
|
request, response = app.test_client.get('/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
assert response.text == 'I am get method'
|
|
|
|
assert type(results[0]) is Request
|
|
|
|
|
|
|
|
|
|
|
|
def test_with_middleware_response():
|
|
|
|
app = Sanic('test_with_middleware_response')
|
|
|
|
|
|
|
|
results = []
|
|
|
|
|
|
|
|
@app.middleware('request')
|
|
|
|
async def process_response(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-25 07:10:25 +00:00
|
|
|
|
2016-11-26 06:45:08 +00:00
|
|
|
def get(self, request):
|
2016-11-25 07:10:25 +00:00
|
|
|
return text('I am get method')
|
|
|
|
|
2017-01-07 04:30:23 +00:00
|
|
|
app.add_route(DummyView.as_view(), '/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
2017-02-14 19:51:20 +00:00
|
|
|
request, response = app.test_client.get('/')
|
2016-11-25 07:10:25 +00:00
|
|
|
|
|
|
|
assert response.text == 'I am get method'
|
|
|
|
assert type(results[0]) is Request
|
|
|
|
assert type(results[1]) is Request
|
2017-01-27 10:11:29 +00:00
|
|
|
assert isinstance(results[2], HTTPResponse)
|
2017-01-07 05:13:49 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_with_custom_class_methods():
|
|
|
|
app = Sanic('test_with_custom_class_methods')
|
|
|
|
|
|
|
|
class DummyView(HTTPMethodView):
|
|
|
|
global_var = 0
|
|
|
|
|
|
|
|
def _iternal_method(self):
|
|
|
|
self.global_var += 10
|
|
|
|
|
|
|
|
def get(self, request):
|
|
|
|
self._iternal_method()
|
|
|
|
return text('I am get method and global var is {}'.format(self.global_var))
|
|
|
|
|
|
|
|
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'
|
|
|
|
|
|
|
|
|
|
|
|
def test_with_decorator():
|
|
|
|
app = Sanic('test_with_decorator')
|
|
|
|
|
|
|
|
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)
|
|
|
|
def test_composition_view_runs_methods_as_expected(method):
|
2017-02-02 21:24:16 +00:00
|
|
|
app = Sanic('test_composition_view')
|
|
|
|
|
|
|
|
view = CompositionView()
|
|
|
|
view.add(['GET', 'POST', 'PUT'], lambda x: text('first method'))
|
|
|
|
view.add(['DELETE', 'PATCH'], lambda x: text('second 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-02 21:24:16 +00:00
|
|
|
assert response.text == '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'
|
|
|
|
|
2017-02-13 16:45:55 +00:00
|
|
|
|
2017-02-13 16:50:09 +00:00
|
|
|
@pytest.mark.parametrize('method', HTTP_METHODS)
|
|
|
|
def test_composition_view_rejects_invalid_methods(method):
|
2017-02-02 21:24:16 +00:00
|
|
|
app = Sanic('test_composition_view')
|
|
|
|
|
|
|
|
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
|