Coverage for tests/test_custom_admin_pages.py: 99%
146 statements
« prev ^ index » next coverage.py v7.2.7, created at 2023-08-03 17:57 -0700
« prev ^ index » next coverage.py v7.2.7, created at 2023-08-03 17:57 -0700
1import sys
2from importlib import reload
4from django.conf import settings
5from django.contrib import admin
6from django.contrib.auth import get_user_model
7from django.contrib.auth.models import AbstractUser, Permission
8from django.contrib.contenttypes.models import ContentType
9from django.core.exceptions import ImproperlyConfigured
10from django.shortcuts import render
11from django.test import RequestFactory
12from django.urls import clear_url_caches, reverse
13from django.utils.text import get_valid_filename, slugify
14from django.views.generic import TemplateView
16import pytest
18from ..views.admin_base_view import AdminBaseView
20User: AbstractUser = get_user_model()
22ADMIN_BASE_URL = reverse("admin:index")
23django_custom_admin_pages_URL = (
24 f"{ADMIN_BASE_URL}{settings.CUSTOM_ADMIN_DEFAULT_APP_LABEL}/"
25)
28def reload_urlconf(urlconf=None):
29 """
30 reloads urlconf, or sepecific urls.py passed in via urlconf arg.
31 """
32 urlconf = settings.ROOT_URLCONF
33 if urlconf in sys.modules:
34 clear_url_caches()
35 reload(sys.modules[urlconf])
38class AnExampleView(AdminBaseView, TemplateView):
39 view_name = "Test Name"
40 route_name = "test_route"
41 template_name = "base_custom_admin.html"
44class AnExampleAppView(AdminBaseView, TemplateView):
45 view_name = "Test App View"
46 app_label = "test_app"
47 route_name = "test_app_route"
48 template_name = "base_custom_admin.html"
49 permission_required = "test_app.test_perm"
52class AnotherExampleView(AdminBaseView, TemplateView):
53 view_name = "Test Name"
54 route_name = "test_route1"
55 template_name = "base_custom_admin.html"
58class NotInheretedView(TemplateView):
59 view_name = "Test Name"
60 route_name = "test_route"
61 template_name = "base_custom_admin.html"
64def not_a_class_based_view(request):
65 return render(request, "base_custom_admin.html", context=dict())
68class NoViewName(AdminBaseView, TemplateView):
69 route_name = "test_route2"
70 template_name = "base_custom_admin.html"
73class NoRouteName(AdminBaseView, TemplateView):
74 view_name = "Test Name"
75 template_name = "base_custom_admin.html"
78@pytest.fixture
79def superuser():
80 return User.objects.create(
81 username="Julian",
82 password="JulianTheWizard",
83 is_staff=True,
84 is_active=True,
85 is_superuser=True,
86 )
89class TestRegistration:
90 """
91 Test registering a view
92 """
94 def it_raises_when_not_class_based(self):
95 with pytest.raises(ImproperlyConfigured):
96 admin.site.register_view(not_a_class_based_view)
98 def it_raises_when_no_view_name(self):
99 with pytest.raises(ImproperlyConfigured):
100 admin.site.register_view(NoViewName)
102 def it_doesnt_raise_when_no_route_name(self):
103 admin.site.register_view(NoRouteName)
104 assert (
105 NoRouteName.route_name == get_valid_filename(NoRouteName.view_name).lower()
106 )
107 assert NoRouteName.route_path == slugify(NoRouteName.view_name).lower()
109 def it_raises_when_not_subclassed(self):
110 with pytest.raises(ImproperlyConfigured):
111 admin.site.register_view(NotInheretedView)
113 def test_register_twice(self):
114 with pytest.raises(admin.sites.AlreadyRegistered):
115 admin.site.register_view([AnExampleView, AnExampleView])
116 admin.site.unregister_view(AnExampleView)
118 def test_unregister_unregistered_raises_error(self):
119 with pytest.raises(admin.sites.NotRegistered):
120 admin.site.unregister_view(AnExampleView)
122 def test_register_multiple(self):
123 admin.site.register_view([AnExampleView, AnotherExampleView])
124 admin.site.unregister_view([AnExampleView, AnotherExampleView])
127@pytest.fixture
128def view():
129 admin.site.register_view(AnExampleView)
130 reload_urlconf()
131 yield
132 admin.site.unregister_view(AnExampleView)
135@pytest.fixture
136def app_view():
137 admin.site.register_view(AnExampleAppView)
138 reload_urlconf()
139 yield
140 admin.site.unregister_view(AnExampleAppView)
143class TestPageRendering:
144 @pytest.fixture
145 def super_client(self, client, superuser):
146 client.force_login(superuser)
147 assert superuser.is_staff
148 assert superuser.is_active
149 assert superuser.is_superuser
150 return client
152 @pytest.mark.django_db
153 def test_admin_index_newly_registered_view(self, view, super_client):
154 """
155 Verify that view is in admin custom views
156 """
158 # add route in runtime and reload urlconf
160 r = super_client.get(reverse("admin:test_route"))
161 assert r.status_code == 200
163 django_custom_admin_pages_dict: dict = list(
164 filter(
165 lambda x: x["app_label"] == "django_custom_admin_pages",
166 r.context["app_list"],
167 )
168 )[0]
169 test_view: dict = list(
170 filter(
171 lambda x: x["admin_url"] == f"{django_custom_admin_pages_URL}test-name",
172 django_custom_admin_pages_dict["models"],
173 )
174 )[0]
176 assert (
177 django_custom_admin_pages_dict["app_url"] == django_custom_admin_pages_URL
178 )
179 assert django_custom_admin_pages_dict["name"] == "Custom Admin Pages"
180 assert (
181 django_custom_admin_pages_dict["app_label"]
182 == settings.CUSTOM_ADMIN_DEFAULT_APP_LABEL
183 )
184 assert test_view["name"] == "Test Name" == test_view["object_name"]
185 assert test_view["view_only"]
187 @pytest.mark.django_db
188 def test_admin_index_newly_registered_app_view(self, app_view, super_client):
189 """
190 Verify that view is in admin custom views
191 """
193 # add route in runtime and reload urlconf
195 r = super_client.get(reverse("admin:test_app_route"))
196 assert r.status_code == 200
198 app_dict: dict = [
199 x for x in r.context["app_list"] if x["app_label"] == "test_app"
200 ][0]
202 test_view: dict = [
203 x
204 for x in app_dict["models"]
205 if x["admin_url"] == "/admin/test_app/test-app-view"
206 ][0]
208 assert app_dict["app_url"] == "/admin/test_app/"
209 assert app_dict["name"] == "Test_App"
210 assert app_dict["app_label"] == "test_app"
211 assert test_view["name"] == "Test App View" == test_view["object_name"]
212 assert test_view["view_only"]
215@pytest.mark.django_db
216def test_get_app_list(superuser, app_view):
217 request_factory = RequestFactory()
218 request = request_factory.get(reverse("admin:index"))
219 request.user = superuser
221 app_list = admin.site.get_app_list(request)
222 test_app = [x for x in app_list if x["name"] == "Test_App"][0]
223 assert len([x for x in test_app["models"] if x["name"] == "Test App View"]) == 1
226class TestPermissions:
227 @pytest.fixture
228 def test_app_ct(self):
229 return ContentType.objects.get(app_label="test_app", model="somemodel")
231 @pytest.fixture
232 def permission(self, test_app_ct):
233 return Permission.objects.create(
234 name="Test Perm", codename="test_perm", content_type=test_app_ct
235 )
237 @pytest.fixture
238 def user(self, permission):
239 u = User.objects.create(
240 username="Bill",
241 password="Billspw",
242 is_staff=True,
243 is_active=True,
244 )
245 u.user_permissions.add(permission)
246 return u
248 @pytest.mark.django_db
249 def it_shows_if_user_has_permission(sefl, user, app_view):
250 request_factory = RequestFactory()
251 request = request_factory.get(reverse("admin:index"))
252 request.user = user
254 app_list = admin.site.get_app_list(request)
255 test_app = [x for x in app_list if x["name"] == "Test_App"][0]
256 assert len([x for x in test_app["models"] if x["name"] == "Test App View"]) == 1