1
from datetime import datetime
4
from markupsafe import escape
5
from markupsafe import Markup
7
from werkzeug import exceptions
8
from werkzeug.datastructures import Headers
9
from werkzeug.datastructures import WWWAuthenticate
10
from werkzeug.exceptions import default_exceptions
11
from werkzeug.exceptions import HTTPException
12
from werkzeug.wrappers import Response
15
def test_proxy_exception():
16
orig_resp = Response("Hello World")
17
with pytest.raises(exceptions.HTTPException) as excinfo:
18
exceptions.abort(orig_resp)
19
resp = excinfo.value.get_response({})
20
assert resp is orig_resp
21
assert resp.get_data() == b"Hello World"
24
@pytest.mark.parametrize(
27
(exceptions.BadRequest, 400),
28
(exceptions.Unauthorized, 401, 'Basic "test realm"'),
29
(exceptions.Forbidden, 403),
30
(exceptions.NotFound, 404),
31
(exceptions.MethodNotAllowed, 405, ["GET", "HEAD"]),
32
(exceptions.NotAcceptable, 406),
33
(exceptions.RequestTimeout, 408),
34
(exceptions.Gone, 410),
35
(exceptions.LengthRequired, 411),
36
(exceptions.PreconditionFailed, 412),
37
(exceptions.RequestEntityTooLarge, 413),
38
(exceptions.RequestURITooLarge, 414),
39
(exceptions.UnsupportedMediaType, 415),
40
(exceptions.UnprocessableEntity, 422),
41
(exceptions.Locked, 423),
42
(exceptions.InternalServerError, 500),
43
(exceptions.NotImplemented, 501),
44
(exceptions.BadGateway, 502),
45
(exceptions.ServiceUnavailable, 503),
48
def test_aborter_general(test):
52
with pytest.raises(exc_type) as exc_info:
53
exceptions.abort(*args)
54
assert type(exc_info.value) is exc_type
57
def test_abort_description_markup():
58
with pytest.raises(HTTPException) as exc_info:
59
exceptions.abort(400, Markup("<b><</b>"))
61
assert "<b><</b>" in str(exc_info.value)
64
def test_aborter_custom():
65
myabort = exceptions.Aborter({1: exceptions.NotFound})
66
pytest.raises(LookupError, myabort, 404)
67
pytest.raises(exceptions.NotFound, myabort, 1)
69
myabort = exceptions.Aborter(extra={1: exceptions.NotFound})
70
pytest.raises(exceptions.NotFound, myabort, 404)
71
pytest.raises(exceptions.NotFound, myabort, 1)
74
def test_exception_repr():
75
exc = exceptions.NotFound()
77
"404 Not Found: The requested URL was not found on the server."
78
" If you entered the URL manually please check your spelling"
81
assert repr(exc) == "<NotFound '404: Not Found'>"
83
exc = exceptions.NotFound("Not There")
84
assert str(exc) == "404 Not Found: Not There"
85
assert repr(exc) == "<NotFound '404: Not Found'>"
87
exc = exceptions.HTTPException("An error message")
88
assert str(exc) == "??? Unknown Error: An error message"
89
assert repr(exc) == "<HTTPException '???: Unknown Error'>"
92
def test_method_not_allowed_methods():
93
exc = exceptions.MethodNotAllowed(["GET", "HEAD", "POST"])
94
h = dict(exc.get_headers({}))
95
assert h["Allow"] == "GET, HEAD, POST"
96
assert "The method is not allowed" in exc.get_description()
99
def test_unauthorized_www_authenticate():
100
basic = WWWAuthenticate("basic", {"realm": "test"})
101
digest = WWWAuthenticate("digest", {"realm": "test", "nonce": "test"})
103
exc = exceptions.Unauthorized(www_authenticate=basic)
104
h = Headers(exc.get_headers({}))
105
assert h["WWW-Authenticate"] == str(basic)
107
exc = exceptions.Unauthorized(www_authenticate=[digest, basic])
108
h = Headers(exc.get_headers({}))
109
assert h.get_all("WWW-Authenticate") == [str(digest), str(basic)]
111
exc = exceptions.Unauthorized()
112
h = Headers(exc.get_headers({}))
113
assert "WWW-Authenticate" not in h
116
def test_response_header_content_type_should_contain_charset():
117
exc = exceptions.HTTPException("An error message")
118
h = exc.get_response({})
119
assert h.headers["Content-Type"] == "text/html; charset=utf-8"
122
@pytest.mark.parametrize(
123
("cls", "value", "expect"),
125
(exceptions.TooManyRequests, 20, "20"),
127
exceptions.ServiceUnavailable,
128
datetime(2020, 1, 4, 18, 52, 16),
129
"Sat, 04 Jan 2020 18:52:16 GMT",
133
def test_retry_after_mixin(cls, value, expect):
134
e = cls(retry_after=value)
135
h = dict(e.get_headers({}))
136
assert h["Retry-After"] == expect
139
@pytest.mark.parametrize(
142
(e for e in default_exceptions.values() if e.code and e.code >= 400),
143
key=lambda e: e.code,
146
def test_passing_response(cls):
147
class TestResponse(Response):
150
exc = cls(response=TestResponse())
151
rp = exc.get_response({})
152
assert isinstance(rp, TestResponse)
155
def test_description_none():
156
HTTPException().get_response()
159
@pytest.mark.parametrize(
162
(e for e in default_exceptions.values() if e.code),
163
key=lambda e: e.code,
166
def test_response_body(cls):
168
response_body = exc.get_body()
169
assert response_body.startswith("<!doctype html>\n<html lang=en>\n")
170
assert f"{exc.code} {escape(exc.name)}" in response_body
171
assert exc.get_description() in response_body