Skip to content

Commit 019719a

Browse files
authored
Tests: run tests with the ext-theme (#11383)
* Tests: run tests with the ext-theme * Fix tests * Run tests in another job * Fix proxito tests * Comment * Update common * Use custom 401 for proxito only * Move 401 to errors/proxito * Change working to match ext-theme * One more template * One more * Use log in instead of sign in This matches ext-theme * Comment
1 parent f80d64e commit 019719a

File tree

20 files changed

+176
-91
lines changed

20 files changed

+176
-91
lines changed

.circleci/config.yml

+26-1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ jobs:
99
docker:
1010
- image: 'cimg/python:3.10'
1111
environment:
12+
# Don't skip search tests.
1213
TOX_POSARGS: ''
1314
PYTEST_COVERAGE: --cov-report=xml --cov-config .coveragerc --cov=. --cov-append
1415
- image: 'docker.elastic.co/elasticsearch/elasticsearch:8.10.2'
@@ -25,10 +26,33 @@ jobs:
2526
- run: git submodule update --init
2627
- run: sudo apt update
2728
- run: sudo apt install -y rclone
28-
- run: pip install --user 'tox<5'
29+
- run: pip install --user tox
2930
- run: tox -e py310
3031
- codecov/upload
3132

33+
tests-ext-theme:
34+
docker:
35+
- image: 'cimg/python:3.10'
36+
environment:
37+
# Don't skip search tests.
38+
TOX_POSARGS: ''
39+
- image: 'docker.elastic.co/elasticsearch/elasticsearch:8.10.2'
40+
name: search
41+
environment:
42+
discovery.type: single-node
43+
ES_JAVA_OPTS: -Xms750m -Xmx750m
44+
ELASTIC_PASSWORD: password
45+
# Disabled SSL for testing.
46+
xpack.security.transport.ssl.enabled: 'false'
47+
steps:
48+
- checkout
49+
- run: git submodule sync
50+
- run: git submodule update --init
51+
- run: sudo apt update
52+
- run: sudo apt install -y rclone
53+
- run: pip install --user tox
54+
- run: tox -e ext-theme
55+
3256
tests-embedapi:
3357
docker:
3458
- image: 'cimg/python:3.10'
@@ -75,6 +99,7 @@ workflows:
7599
jobs:
76100
- checks
77101
- tests
102+
- tests-ext-theme
78103
- tests-embedapi:
79104
requires:
80105
- checks

readthedocs/core/views/__init__.py

+9-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import structlog
99
from django.conf import settings
10-
from django.http import JsonResponse
10+
from django.http import Http404, JsonResponse
1111
from django.shortcuts import redirect
1212
from django.urls import reverse
1313
from django.views.generic import TemplateView, View
@@ -148,6 +148,14 @@ def get(self, request, *args, **kwargs):
148148
return self.render_to_response(context, status=418)
149149

150150

151+
class PageNotFoundView(View):
152+
153+
"""Just a 404 view that ignores all URL parameters."""
154+
155+
def get(self, request, *args, **kwargs):
156+
raise Http404()
157+
158+
151159
def do_not_track(request):
152160
dnt_header = request.headers.get("Dnt")
153161

readthedocs/organizations/tests/test_privacy_urls.py

+2
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ class AuthUserOrganizationsTest(OrganizationMixin, TestCase):
6666
"/organizations/{slug}/teams/{team}/members/{member}/revoke/": {
6767
"status_code": 405
6868
},
69+
# Placeholder URL.
70+
"/organizations/{slug}/authorization/": {"status_code": 404},
6971
}
7072

7173
def login(self):

readthedocs/organizations/urls/private.py

+9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""URLs that require login."""
22
from django.urls import path, re_path
33

4+
from readthedocs.core.views import PageNotFoundView
45
from readthedocs.organizations.views import private as views
56

67
urlpatterns = [
@@ -81,4 +82,12 @@
8182
views.DeleteOrganizationTeamMember.as_view(),
8283
name="organization_team_member_delete",
8384
),
85+
# Placeholder URL, so that we can test the new templates
86+
# with organizations enabled from our community codebase.
87+
# TODO: migrate this functionality from corporate to community.
88+
re_path(
89+
r"^(?P<slug>[\w.-]+)/authorization/$",
90+
PageNotFoundView.as_view(),
91+
name="organization_sso",
92+
),
8493
]

readthedocs/projects/urls/private.py

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
"""Project URLs for authenticated users."""
2-
32
from django.conf import settings
43
from django.contrib.auth.decorators import login_required
54
from django.urls import path, re_path
65
from django.views.generic.base import RedirectView
76

87
from readthedocs.constants import pattern_opts
8+
from readthedocs.core.views import PageNotFoundView
99
from readthedocs.projects.backends.views import ImportWizardView
1010
from readthedocs.projects.views import private
1111
from readthedocs.projects.views.private import (
@@ -191,6 +191,19 @@
191191
TrafficAnalyticsView.as_view(),
192192
name="projects_traffic_analytics",
193193
),
194+
# Placeholder URLs, so that we can test the new templates
195+
# with organizations enabled from our community codebase.
196+
# TODO: migrate these functionalities from corporate to community.
197+
re_path(
198+
r"^(?P<project_slug>{project_slug})/sharing/$".format(**pattern_opts),
199+
PageNotFoundView.as_view(),
200+
name="projects_temporary_access_list",
201+
),
202+
re_path(
203+
(r"^(?P<project_slug>{project_slug})/keys/$".format(**pattern_opts)),
204+
PageNotFoundView.as_view(),
205+
name="projects_keys",
206+
),
194207
]
195208

196209
# TODO move this up to the list above when it's not a conditional URL.

readthedocs/proxito/tests/handler_404_urls.py

+12-10
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
"""
1313
from functools import wraps
1414

15+
from django.http import Http404
16+
1517
from readthedocs.proxito.urls import * # noqa
18+
from readthedocs.proxito.urls import handler404 as proxito_handler404
1619
from readthedocs.proxito.views.serve import ServeError404
1720

1821

@@ -21,18 +24,17 @@
2124
def map_proxito_path(view_func):
2225
@wraps(view_func)
2326
def inner_view(request, *args, **kwargs):
24-
return view_func(
25-
request,
26-
proxito_path=request.path,
27-
)
27+
try:
28+
return view_func(
29+
request,
30+
proxito_path=request.path,
31+
)
32+
except Http404 as e:
33+
# Fall back to our custom 404 handler,
34+
# if a 404 was raised by proxito's 404 view.
35+
return proxito_handler404(request, exception=e)
2836

2937
return inner_view
3038

3139

3240
handler404 = map_proxito_path(ServeError404.as_view())
33-
34-
# Patch URLs that call the `fast_404` view directly.
35-
for pattern in urlpatterns:
36-
if getattr(pattern, "name", None) == "docs_detail_directory_indexing":
37-
pattern.callback = handler404
38-
break

readthedocs/proxito/tests/test_old_redirects.py

+48-49
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99
"""
1010

1111
import django_dynamic_fixture as fixture
12-
import pytest
13-
from django.http import Http404
1412
from django.test.utils import override_settings
1513

1614
from readthedocs.builds.constants import EXTERNAL
@@ -196,8 +194,8 @@ def test_disabled_redirect(self):
196194
redirect.enabled = False
197195
redirect.save()
198196

199-
with self.assertRaises(Http404):
200-
self.client.get(url, headers={"host": "project.dev.readthedocs.io"})
197+
r = self.client.get(url, headers={"host": "project.dev.readthedocs.io"})
198+
self.assertEqual(r.status_code, 404)
201199

202200
def test_redirect_order(self):
203201
redirect_a = fixture.get(
@@ -267,8 +265,8 @@ def test_redirect_ignored_on_external_domain(self):
267265
slug="22",
268266
type=EXTERNAL,
269267
)
270-
with self.assertRaises(Http404):
271-
self.client.get(url, headers={"host": "project--22.readthedocs.build"})
268+
r = self.client.get(url, headers={"host": "project--22.readthedocs.build"})
269+
self.assertEqual(r.status_code, 404)
272270

273271
def test_infinite_redirect(self):
274272
host = "project.dev.readthedocs.io"
@@ -279,11 +277,11 @@ def test_infinite_redirect(self):
279277
from_url="/en/latest/install.html",
280278
to_url="/en/latest/install.html",
281279
)
282-
with pytest.raises(Http404):
283-
self.client.get("/en/latest/install.html", headers={"host": host})
280+
r = self.client.get("/en/latest/install.html", headers={"host": host})
281+
self.assertEqual(r.status_code, 404)
284282

285-
with pytest.raises(Http404):
286-
self.client.get("/en/latest/install.html?foo=bar", headers={"host": host})
283+
r = self.client.get("/en/latest/install.html?foo=bar", headers={"host": host})
284+
self.assertEqual(r.status_code, 404)
287285

288286
def test_infinite_redirect_changing_protocol(self):
289287
host = "project.dev.readthedocs.io"
@@ -294,11 +292,12 @@ def test_infinite_redirect_changing_protocol(self):
294292
from_url="/en/latest/install.html",
295293
to_url=f"https://{host}/en/latest/install.html",
296294
)
297-
with pytest.raises(Http404):
298-
self.client.get("/en/latest/install.html", headers={"host": host})
299295

300-
with pytest.raises(Http404):
301-
self.client.get("/en/latest/install.html?foo=bar", headers={"host": host})
296+
r = self.client.get("/en/latest/install.html", headers={"host": host})
297+
self.assertEqual(r.status_code, 404)
298+
299+
r = self.client.get("/en/latest/install.html?foo=bar", headers={"host": host})
300+
self.assertEqual(r.status_code, 404)
302301

303302
def test_exact_redirect_avoid_infinite_redirect(self):
304303
"""
@@ -335,10 +334,10 @@ def test_exact_redirect_avoid_infinite_redirect(self):
335334
"http://project.dev.readthedocs.io/en/latest/redirect/",
336335
)
337336

338-
with self.assertRaises(Http404):
339-
self.client.get(
340-
"/en/latest/redirect/", headers={"host": "project.dev.readthedocs.io"}
341-
)
337+
r = self.client.get(
338+
"/en/latest/redirect/", headers={"host": "project.dev.readthedocs.io"}
339+
)
340+
self.assertEqual(r.status_code, 404)
342341

343342
fixture.get(
344343
Redirect,
@@ -356,11 +355,11 @@ def test_exact_redirect_avoid_infinite_redirect(self):
356355
"http://project.dev.readthedocs.io/en/latest/subdir/redirect.html",
357356
)
358357

359-
with self.assertRaises(Http404):
360-
self.client.get(
361-
"/en/latest/subdir/redirect.html",
362-
headers={"host": "project.dev.readthedocs.io"},
363-
)
358+
r = self.client.get(
359+
"/en/latest/subdir/redirect.html",
360+
headers={"host": "project.dev.readthedocs.io"},
361+
)
362+
self.assertEqual(r.status_code, 404)
364363

365364
def test_page_redirect_avoid_infinite_redirect(self):
366365
fixture.get(
@@ -379,11 +378,11 @@ def test_page_redirect_avoid_infinite_redirect(self):
379378
"http://project.dev.readthedocs.io/en/latest/subdir/redirect.html",
380379
)
381380

382-
with self.assertRaises(Http404):
383-
self.client.get(
384-
"/en/latest/subdir/redirect.html",
385-
headers={"host": "project.dev.readthedocs.io"},
386-
)
381+
r = self.client.get(
382+
"/en/latest/subdir/redirect.html",
383+
headers={"host": "project.dev.readthedocs.io"},
384+
)
385+
self.assertEqual(r.status_code, 404)
387386

388387
fixture.get(
389388
Redirect,
@@ -402,11 +401,11 @@ def test_page_redirect_avoid_infinite_redirect(self):
402401
"http://project.dev.readthedocs.io/en/latest/dir/subdir/redirect.html",
403402
)
404403

405-
with self.assertRaises(Http404):
406-
self.client.get(
407-
"/en/latest/dir/subdir/redirect.html",
408-
headers={"host": "project.dev.readthedocs.io"},
409-
)
404+
r = self.client.get(
405+
"/en/latest/dir/subdir/redirect.html",
406+
headers={"host": "project.dev.readthedocs.io"},
407+
)
408+
self.assertEqual(r.status_code, 404)
410409

411410
def test_exact_redirect_to_parent_path(self):
412411
self.project.versioning_scheme = SINGLE_VERSION_WITHOUT_TRANSLATIONS
@@ -497,11 +496,11 @@ def test_redirect_root(self):
497496
)
498497

499498
# Prefix redirects should match the whole path.
500-
with self.assertRaises(Http404):
501-
self.client.get(
502-
"/en/latest/woot/faq.html",
503-
headers={"host": "project.dev.readthedocs.io"},
504-
)
499+
r = self.client.get(
500+
"/en/latest/woot/faq.html",
501+
headers={"host": "project.dev.readthedocs.io"},
502+
)
503+
self.assertEqual(r.status_code, 404)
505504

506505
def test_redirect_page(self):
507506
Redirect.objects.create(
@@ -860,11 +859,11 @@ def test_redirect_html_root_index(self):
860859
)
861860

862861
with override_settings(PYTHON_MEDIA=True):
863-
with self.assertRaises(Http404):
864-
# File does not exist in storage media
865-
r = self.client.get(
866-
"/en/latest/", headers={"host": "project.dev.readthedocs.io"}
867-
)
862+
# File does not exist in storage media
863+
r = self.client.get(
864+
"/en/latest/", headers={"host": "project.dev.readthedocs.io"}
865+
)
866+
self.assertEqual(r.status_code, 404)
868867

869868
def test_redirect_html_index(self):
870869
fixture.get(
@@ -924,12 +923,12 @@ def test_not_found_page_without_trailing_slash(self):
924923
to_url="/en/latest/:splat",
925924
)
926925

927-
with self.assertRaises(Http404):
928-
# Avoid infinite redirect
929-
r = self.client.get(
930-
"/en/latest/section/file-not-found",
931-
headers={"host": "project.dev.readthedocs.io"},
932-
)
926+
# Avoid infinite redirect
927+
r = self.client.get(
928+
"/en/latest/section/file-not-found",
929+
headers={"host": "project.dev.readthedocs.io"},
930+
)
931+
self.assertEqual(r.status_code, 404)
933932

934933
def test_page_redirect_with_and_without_trailing_slash(self):
935934
fixture.get(

readthedocs/proxito/views/mixins.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ def _serve_file_from_python(self, request, path, storage):
270270
return serve(request, path, root_path)
271271

272272
def _serve_401(self, request, project):
273-
res = render(request, "401.html")
273+
res = render(request, "errors/proxito/401.html")
274274
res.status_code = 401
275275
log.debug("Unauthorized access to documentation.", project_slug=project.slug)
276276
return res

0 commit comments

Comments
 (0)