Newer
Older
Eliot Berriot
committed
import time
import pytest
Eliot Berriot
committed
from django.http import HttpResponse
from funkwhale_api.common import middleware
Eliot Berriot
committed
from funkwhale_api.common import throttling
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
def test_spa_fallback_middleware_no_404(mocker):
get_response = mocker.Mock()
get_response.return_value = mocker.Mock(status_code=200)
request = mocker.Mock(path="/")
m = middleware.SPAFallbackMiddleware(get_response)
assert m(request) == get_response.return_value
def test_spa_middleware_calls_should_fallback_false(mocker):
get_response = mocker.Mock()
get_response.return_value = mocker.Mock(status_code=404)
should_falback = mocker.patch.object(
middleware, "should_fallback_to_spa", return_value=False
)
request = mocker.Mock(path="/")
m = middleware.SPAFallbackMiddleware(get_response)
assert m(request) == get_response.return_value
should_falback.assert_called_once_with(request.path)
def test_spa_middleware_should_fallback_true(mocker):
get_response = mocker.Mock()
get_response.return_value = mocker.Mock(status_code=404)
request = mocker.Mock(path="/")
mocker.patch.object(middleware, "should_fallback_to_spa", return_value=True)
serve_spa = mocker.patch.object(middleware, "serve_spa")
m = middleware.SPAFallbackMiddleware(get_response)
assert m(request) == serve_spa.return_value
serve_spa.assert_called_once_with(request)
@pytest.mark.parametrize(
"path,expected",
[("/", True), ("/federation", False), ("/api", False), ("/an/spa/path/", True)],
)
def test_should_fallback(path, expected, mocker):
assert middleware.should_fallback_to_spa(path) is expected
def test_serve_spa_from_cache(mocker, settings, preferences, no_api_auth):
request = mocker.Mock(path="/")
get_spa_html = mocker.patch.object(
middleware, "get_spa_html", return_value="<html><head></head></html>"
)
mocker.patch.object(
middleware,
"get_default_head_tags",
return_value=[
{"tag": "meta", "property": "og:title", "content": "default title"},
{"tag": "meta", "property": "og:site_name", "content": "default site name"},
],
)
get_request_head_tags = mocker.patch.object(
middleware,
"get_request_head_tags",
return_value=[
{"tag": "meta", "property": "og:title", "content": "custom title"},
{
"tag": "meta",
"property": "og:description",
"content": "custom description",
},
],
)
response = middleware.serve_spa(request)
assert response.status_code == 200
expected = [
"<html><head>",
'<meta content="custom title" property="og:title" />',
'<meta content="custom description" property="og:description" />',
'<meta content="default site name" property="og:site_name" />',
"</head></html>",
]
get_spa_html.assert_called_once_with(settings.FUNKWHALE_SPA_HTML_ROOT)
get_request_head_tags.assert_called_once_with(request)
assert response.content == "\n".join(expected).encode()
def test_get_default_head_tags(preferences, settings):
settings.APP_NAME = "Funkwhale"
preferences["instance__name"] = "Hello"
preferences["instance__short_description"] = "World"
expected = [
{"tag": "meta", "property": "og:type", "content": "website"},
{"tag": "meta", "property": "og:site_name", "content": "Hello - Funkwhale"},
{"tag": "meta", "property": "og:description", "content": "World"},
{
"tag": "meta",
"property": "og:image",
"content": settings.FUNKWHALE_URL + "/front/favicon.png",
},
{"tag": "meta", "property": "og:url", "content": settings.FUNKWHALE_URL + "/"},
]
assert middleware.get_default_head_tags("/") == expected
def test_get_spa_html_from_cache(local_cache):
local_cache.set("spa-html:http://test", "hello world")
assert middleware.get_spa_html("http://test") == "hello world"
def test_get_spa_html_from_http(local_cache, r_mock, mocker, settings):
cache_set = mocker.spy(local_cache, "set")
url = "http://test"
r_mock.get(url + "/index.html", text="hello world")
assert middleware.get_spa_html("http://test") == "hello world"
cache_set.assert_called_once_with(
"spa-html:{}".format(url),
"hello world",
settings.FUNKWHALE_SPA_HTML_CACHE_DURATION,
)
Eliot Berriot
committed
def test_get_spa_html_from_disk(tmpfile):
with open(tmpfile.name, "wb") as f:
f.write(b"hello world")
assert middleware.get_spa_html(tmpfile.name) == "hello world"
def test_get_route_head_tags(mocker, settings):
match = mocker.Mock(args=[], kwargs={"pk": 42}, func=mocker.Mock())
resolve = mocker.patch("django.urls.resolve", return_value=match)
request = mocker.Mock(path="/tracks/42")
tags = middleware.get_request_head_tags(request)
assert tags == match.func.return_value
match.func.assert_called_once_with(request, *[], **{"pk": 42})
resolve.assert_called_once_with(request.path, urlconf=settings.SPA_URLCONF)
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
def test_serve_spa_includes_custom_css(mocker, no_api_auth):
request = mocker.Mock(path="/")
mocker.patch.object(
middleware,
"get_spa_html",
return_value="<html><head></head><body></body></html>",
)
mocker.patch.object(middleware, "get_default_head_tags", return_value=[])
mocker.patch.object(middleware, "get_request_head_tags", return_value=[])
get_custom_css = mocker.patch.object(
middleware, "get_custom_css", return_value="body { background: black; }"
)
response = middleware.serve_spa(request)
assert response.status_code == 200
expected = [
"<html><head>\n\n</head><body>",
"<style>body { background: black; }</style>",
"</body></html>",
]
get_custom_css.assert_called_once_with()
assert response.content == "\n".join(expected).encode()
@pytest.mark.parametrize(
"custom_css, expected",
[
("body { background: black; }", "body { background: black; }"),
(
"body { injection: </style> & Hello",
"body { injection: </style> & Hello",
),
(
'body { background: url("image/url"); }',
'body { background: url("image/url"); }',
),
],
)
def test_get_custom_css(preferences, custom_css, expected):
preferences["ui__custom_css"] = custom_css
assert middleware.get_custom_css() == expected
Eliot Berriot
committed
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
def test_throttle_status_middleware_includes_info_in_response_headers(mocker):
get_response = mocker.Mock()
response = HttpResponse()
get_response.return_value = response
request = mocker.Mock(
path="/",
_api_request=mocker.Mock(
_throttle_status={
"num_requests": 42,
"duration": 3600,
"scope": "hello",
"history": [time.time() - 1600, time.time() - 1800],
}
),
)
m = middleware.ThrottleStatusMiddleware(get_response)
assert m(request) == response
assert response["X-RateLimit-Limit"] == "42"
assert response["X-RateLimit-Remaining"] == "40"
assert response["X-RateLimit-Duration"] == "3600"
assert response["X-RateLimit-Scope"] == "hello"
assert response["X-RateLimit-Reset"] == str(int(time.time()) + 2000)
assert response["X-RateLimit-ResetSeconds"] == str(2000)
assert response["Retry-After"] == str(1800)
def test_throttle_status_middleware_returns_proper_response(mocker):
get_response = mocker.Mock(side_effect=throttling.TooManyRequests())
request = mocker.Mock(path="/", _api_request=None, _throttle_status=None)
m = middleware.ThrottleStatusMiddleware(get_response)
response = m(request)
assert response.status_code == 429