sanic/tests/test_exceptions.py

205 lines
6.3 KiB
Python
Raw Permalink Normal View History

import pytest
2017-01-13 00:54:34 +00:00
from bs4 import BeautifulSoup
from sanic import Sanic
2016-10-14 23:36:58 +01:00
from sanic.response import text
from sanic.exceptions import InvalidUsage, ServerError, NotFound, Unauthorized
from sanic.exceptions import Forbidden, abort
class SanicExceptionTestException(Exception):
pass
@pytest.fixture(scope='module')
def exception_app():
app = Sanic('test_exceptions')
@app.route('/')
def handler(request):
return text('OK')
@app.route('/error')
def handler_error(request):
raise ServerError("OK")
@app.route('/404')
def handler_404(request):
raise NotFound("OK")
@app.route('/403')
def handler_403(request):
raise Forbidden("Forbidden")
@app.route('/401')
def handler_401(request):
raise Unauthorized("Unauthorized")
@app.route('/401/basic')
def handler_401_basic(request):
raise Unauthorized("Unauthorized", scheme="Basic", realm="Sanic")
@app.route('/401/digest')
def handler_401_digest(request):
raise Unauthorized("Unauthorized",
scheme="Digest",
realm="Sanic",
qop="auth, auth-int",
algorithm="MD5",
nonce="abcdef",
opaque="zyxwvu")
@app.route('/401/bearer')
def handler_401_bearer(request):
raise Unauthorized("Unauthorized", scheme="Bearer")
@app.route('/invalid')
def handler_invalid(request):
raise InvalidUsage("OK")
@app.route('/abort/401')
def handler_401_error(request):
abort(401)
2017-05-20 22:43:57 +01:00
@app.route('/abort')
def handler_500_error(request):
2017-05-20 22:43:57 +01:00
abort(500)
2017-05-21 03:30:08 +01:00
return text("OK")
2017-05-20 22:43:57 +01:00
@app.route('/divide_by_zero')
def handle_unhandled_exception(request):
1 / 0
@app.route('/error_in_error_handler_handler')
def custom_error_handler(request):
raise SanicExceptionTestException('Dummy message!')
@app.exception(SanicExceptionTestException)
def error_in_error_handler_handler(request, exception):
1 / 0
return app
2017-03-08 00:22:23 +00:00
def test_catch_exception_list():
app = Sanic('exception_list')
2017-03-08 00:22:23 +00:00
@app.exception([SanicExceptionTestException, NotFound])
def exception_list(request, exception):
return text("ok")
@app.route('/')
def exception(request):
raise SanicExceptionTestException("You won't see me")
request, response = app.test_client.get('/random')
assert response.text == 'ok'
request, response = app.test_client.get('/')
assert response.text == 'ok'
2017-05-21 03:30:08 +01:00
def test_no_exception(exception_app):
"""Test that a route works without an exception"""
2017-02-14 19:51:20 +00:00
request, response = exception_app.test_client.get('/')
2016-10-14 23:36:58 +01:00
assert response.status == 200
assert response.text == 'OK'
def test_server_error_exception(exception_app):
"""Test the built-in ServerError exception works"""
2017-02-14 19:51:20 +00:00
request, response = exception_app.test_client.get('/error')
2016-10-14 23:36:58 +01:00
assert response.status == 500
2017-05-21 03:30:08 +01:00
def test_invalid_usage_exception(exception_app):
"""Test the built-in InvalidUsage exception works"""
2017-05-21 03:30:08 +01:00
request, response = exception_app.test_client.get('/invalid')
assert response.status == 400
2016-10-14 23:36:58 +01:00
def test_not_found_exception(exception_app):
"""Test the built-in NotFound exception works"""
2017-02-14 19:51:20 +00:00
request, response = exception_app.test_client.get('/404')
2016-10-14 23:36:58 +01:00
assert response.status == 404
def test_forbidden_exception(exception_app):
"""Test the built-in Forbidden exception"""
request, response = exception_app.test_client.get('/403')
assert response.status == 403
def test_unauthorized_exception(exception_app):
"""Test the built-in Unauthorized exception"""
request, response = exception_app.test_client.get('/401')
assert response.status == 401
request, response = exception_app.test_client.get('/401/basic')
assert response.status == 401
assert response.headers.get('WWW-Authenticate') is not None
assert response.headers.get('WWW-Authenticate') == "Basic realm='Sanic'"
request, response = exception_app.test_client.get('/401/digest')
assert response.status == 401
auth_header = response.headers.get('WWW-Authenticate')
assert auth_header is not None
assert auth_header.startswith('Digest')
assert "qop='auth, auth-int'" in auth_header
assert "algorithm='MD5'" in auth_header
assert "nonce='abcdef'" in auth_header
assert "opaque='zyxwvu'" in auth_header
request, response = exception_app.test_client.get('/401/bearer')
assert response.status == 401
assert response.headers.get('WWW-Authenticate') == "Bearer"
def test_handled_unhandled_exception(exception_app):
"""Test that an exception not built into sanic is handled"""
2017-02-14 19:51:20 +00:00
request, response = exception_app.test_client.get('/divide_by_zero')
assert response.status == 500
2017-01-13 00:54:34 +00:00
soup = BeautifulSoup(response.body, 'html.parser')
assert soup.h1.text == 'Internal Server Error'
message = " ".join(soup.p.text.split())
assert message == (
"The server encountered an internal error and "
"cannot complete your request.")
2017-05-21 03:30:08 +01:00
def test_exception_in_exception_handler(exception_app):
"""Test that an exception thrown in an error handler is handled"""
2017-02-14 19:51:20 +00:00
request, response = exception_app.test_client.get(
'/error_in_error_handler_handler')
assert response.status == 500
assert response.body == b'An error occurred while handling an error'
def test_exception_in_exception_handler_debug_off(exception_app):
"""Test that an exception thrown in an error handler is handled"""
2017-02-14 19:51:20 +00:00
request, response = exception_app.test_client.get(
'/error_in_error_handler_handler',
debug=False)
assert response.status == 500
assert response.body == b'An error occurred while handling an error'
def test_exception_in_exception_handler_debug_on(exception_app):
"""Test that an exception thrown in an error handler is handled"""
2017-02-14 19:51:20 +00:00
request, response = exception_app.test_client.get(
'/error_in_error_handler_handler',
debug=True)
assert response.status == 500
assert response.body.startswith(b'Exception raised in exception ')
2017-05-21 03:30:08 +01:00
def test_abort(exception_app):
"""Test the abort function"""
request, response = exception_app.test_client.get('/abort/401')
assert response.status == 401
2017-05-21 03:30:08 +01:00
request, response = exception_app.test_client.get('/abort')
assert response.status == 500