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

1import sys 

2from importlib import reload 

3 

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 

15 

16import pytest 

17 

18from ..views.admin_base_view import AdminBaseView 

19 

20User: AbstractUser = get_user_model() 

21 

22ADMIN_BASE_URL = reverse("admin:index") 

23django_custom_admin_pages_URL = ( 

24 f"{ADMIN_BASE_URL}{settings.CUSTOM_ADMIN_DEFAULT_APP_LABEL}/" 

25) 

26 

27 

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]) 

36 

37 

38class AnExampleView(AdminBaseView, TemplateView): 

39 view_name = "Test Name" 

40 route_name = "test_route" 

41 template_name = "base_custom_admin.html" 

42 

43 

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" 

50 

51 

52class AnotherExampleView(AdminBaseView, TemplateView): 

53 view_name = "Test Name" 

54 route_name = "test_route1" 

55 template_name = "base_custom_admin.html" 

56 

57 

58class NotInheretedView(TemplateView): 

59 view_name = "Test Name" 

60 route_name = "test_route" 

61 template_name = "base_custom_admin.html" 

62 

63 

64def not_a_class_based_view(request): 

65 return render(request, "base_custom_admin.html", context=dict()) 

66 

67 

68class NoViewName(AdminBaseView, TemplateView): 

69 route_name = "test_route2" 

70 template_name = "base_custom_admin.html" 

71 

72 

73class NoRouteName(AdminBaseView, TemplateView): 

74 view_name = "Test Name" 

75 template_name = "base_custom_admin.html" 

76 

77 

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 ) 

87 

88 

89class TestRegistration: 

90 """ 

91 Test registering a view 

92 """ 

93 

94 def it_raises_when_not_class_based(self): 

95 with pytest.raises(ImproperlyConfigured): 

96 admin.site.register_view(not_a_class_based_view) 

97 

98 def it_raises_when_no_view_name(self): 

99 with pytest.raises(ImproperlyConfigured): 

100 admin.site.register_view(NoViewName) 

101 

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() 

108 

109 def it_raises_when_not_subclassed(self): 

110 with pytest.raises(ImproperlyConfigured): 

111 admin.site.register_view(NotInheretedView) 

112 

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) 

117 

118 def test_unregister_unregistered_raises_error(self): 

119 with pytest.raises(admin.sites.NotRegistered): 

120 admin.site.unregister_view(AnExampleView) 

121 

122 def test_register_multiple(self): 

123 admin.site.register_view([AnExampleView, AnotherExampleView]) 

124 admin.site.unregister_view([AnExampleView, AnotherExampleView]) 

125 

126 

127@pytest.fixture 

128def view(): 

129 admin.site.register_view(AnExampleView) 

130 reload_urlconf() 

131 yield 

132 admin.site.unregister_view(AnExampleView) 

133 

134 

135@pytest.fixture 

136def app_view(): 

137 admin.site.register_view(AnExampleAppView) 

138 reload_urlconf() 

139 yield 

140 admin.site.unregister_view(AnExampleAppView) 

141 

142 

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 

151 

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 """ 

157 

158 # add route in runtime and reload urlconf 

159 

160 r = super_client.get(reverse("admin:test_route")) 

161 assert r.status_code == 200 

162 

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] 

175 

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"] 

186 

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 """ 

192 

193 # add route in runtime and reload urlconf 

194 

195 r = super_client.get(reverse("admin:test_app_route")) 

196 assert r.status_code == 200 

197 

198 app_dict: dict = [ 

199 x for x in r.context["app_list"] if x["app_label"] == "test_app" 

200 ][0] 

201 

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] 

207 

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"] 

213 

214 

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 

220 

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 

224 

225 

226class TestPermissions: 

227 @pytest.fixture 

228 def test_app_ct(self): 

229 return ContentType.objects.get(app_label="test_app", model="somemodel") 

230 

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 ) 

236 

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 

247 

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 

253 

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