/
test_route_by_content.py
155 lines (131 loc) · 5 KB
/
test_route_by_content.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
from unittest import mock
import httpretty
import pytest
from h_matchers import Any
from requests import Response
from requests.exceptions import (
MissingSchema,
ProxyError,
SSLError,
UnrewindableBodyError,
)
from tests.unit.conftest import assert_cache_control
from via.exceptions import BadURL, UnhandledException, UpstreamServiceError
from via.views._query_params import QueryParams
from via.views.route_by_content import route_by_content
class TestRouteByContent:
@pytest.mark.parametrize(
"content_type,redirect_url",
[
("application/pdf", "http://localhost/pdf/https://example.com"),
("application/x-pdf", "http://localhost/pdf/https://example.com"),
("text/html", "http://via.hypothes.is/https://example.com"),
],
)
def test_redirects_based_on_content_type_header(
self, make_pyramid_request, content_type, redirect_url
):
request = make_pyramid_request(
request_url="/https://example.com",
thirdparty_url="https://example.com",
content_type=content_type,
)
result = route_by_content(request)
assert result.location == redirect_url
@pytest.mark.parametrize("query_param", QueryParams.ALL_PARAMS)
def test_does_not_pass_via_query_params_to_third_parties(
self, make_pyramid_request, query_param
):
request = make_pyramid_request(
request_url="/https://example.com?"
"via.request_config_from_frame=lms.hypothes.is&via.open_sidebar=1",
thirdparty_url="https://example.com",
content_type="application/pdf",
)
route_by_content(request)
# pylint: disable=no-member
assert query_param not in httpretty.last_request().path
@pytest.mark.parametrize(
"content_type,max_age", [("application/pdf", 300), ("text/html", 60)],
)
def test_sets_correct_cache_control(
self, content_type, max_age, make_pyramid_request
):
request = make_pyramid_request(
request_url="/http://example.com",
thirdparty_url="http://example.com",
content_type=content_type,
)
result = route_by_content(request)
assert_cache_control(
result.headers,
["public", f"max-age={max_age}", "stale-while-revalidate=86400"],
)
@pytest.mark.parametrize("bad_url", ("no-schema", "glub://example.com", "http://"))
def test_invalid_urls_raise_BadURL(self, bad_url, make_pyramid_request):
request = make_pyramid_request(
request_url=f"/{bad_url}", thirdparty_url=bad_url, content_type="text/html",
)
with pytest.raises(BadURL):
route_by_content(request)
@pytest.mark.parametrize(
"request_exception,expected_exception",
(
(MissingSchema, BadURL),
(ProxyError, UpstreamServiceError),
(SSLError, UpstreamServiceError),
(UnrewindableBodyError, UnhandledException),
),
)
def test_we_catch_requests_exceptions(
self, requests, request_exception, expected_exception, make_pyramid_request
):
requests.get.side_effect = request_exception("Oh noe")
request = make_pyramid_request(
request_url="/http://example.com",
thirdparty_url="http://example.com",
content_type="text/html",
)
with pytest.raises(expected_exception):
route_by_content(request)
@pytest.mark.parametrize(
"status_code,cache",
(
(200, Any.string.containing("max-age=60")),
(401, Any.string.containing("max-age=60")),
(404, Any.string.containing("max-age=60")),
(500, "no-cache"),
(501, "no-cache"),
),
)
def test_cache_http_response_codes_appropriately(
self, status_code, cache, make_pyramid_request, requests
):
response = Response()
response.status_code = status_code
response.raw = mock.Mock()
requests.get.return_value = response
result = route_by_content(
make_pyramid_request(
request_url="/http://example.com",
thirdparty_url="http://example.com",
content_type="text/html",
)
)
assert dict(result.headers) == Any.dict.containing({"Cache-Control": cache})
@pytest.fixture
def requests(self, patch):
return patch("via.views.route_by_content.requests")
@pytest.fixture
def make_pyramid_request(self, make_pyramid_request):
def _make_pyramid_request(request_url, thirdparty_url, content_type):
httpretty.register_uri(
httpretty.GET,
thirdparty_url,
body="{}",
adding_headers={"Content-Type": content_type},
)
request = make_pyramid_request(request_url)
request.matchdict = {"url": thirdparty_url}
return request
return _make_pyramid_request