1
+
from selenium.common.exceptions import NoSuchElementException
2
+
1
3
from django.contrib.admin import ModelAdmin, TabularInline
2
4
from django.contrib.admin.helpers import InlineAdminForm
3
5
from django.contrib.admin.tests import AdminSeleniumTestCase
@@ -862,6 +864,98 @@ def test_inline_change_fk_all_perms(self):
862
864
)
863
865
864
866
867
+
@override_settings(ROOT_URLCONF='admin_inlines.urls')
868
+
class TestReadOnlyChangeViewInlinePermissions(TestCase):
869
+
870
+
@classmethod
871
+
def setUpTestData(cls):
872
+
cls.user = User.objects.create_user('testing', password='password', is_staff=True)
873
+
cls.user.user_permissions.add(
874
+
Permission.objects.get(codename='view_poll', content_type=ContentType.objects.get_for_model(Poll))
875
+
)
876
+
cls.user.user_permissions.add(
877
+
*Permission.objects.filter(
878
+
codename__endswith="question", content_type=ContentType.objects.get_for_model(Question)
879
+
).values_list('pk', flat=True)
880
+
)
881
+
882
+
cls.poll = Poll.objects.create(name="Survey")
883
+
cls.add_url = reverse('admin:admin_inlines_poll_add')
884
+
cls.change_url = reverse('admin:admin_inlines_poll_change', args=(cls.poll.id,))
885
+
886
+
def setUp(self):
887
+
self.client.force_login(self.user)
888
+
889
+
def test_add_url_not_allowed(self):
890
+
response = self.client.get(self.add_url)
891
+
self.assertEqual(response.status_code, 403)
892
+
893
+
response = self.client.post(self.add_url, {})
894
+
self.assertEqual(response.status_code, 403)
895
+
896
+
def test_post_to_change_url_not_allowed(self):
897
+
response = self.client.post(self.change_url, {})
898
+
self.assertEqual(response.status_code, 403)
899
+
900
+
def test_get_to_change_url_is_allowed(self):
901
+
response = self.client.get(self.change_url)
902
+
self.assertEqual(response.status_code, 200)
903
+
904
+
def test_main_model_is_rendered_as_read_only(self):
905
+
response = self.client.get(self.change_url)
906
+
self.assertContains(
907
+
response,
908
+
'<div class="readonly">%s</div>' % self.poll.name,
909
+
html=True
910
+
)
911
+
input = '<input type="text" name="name" value="%s" class="vTextField" maxlength="40" required id="id_name">'
912
+
self.assertNotContains(
913
+
response,
914
+
input % self.poll.name,
915
+
html=True
916
+
)
917
+
918
+
def test_inlines_are_rendered_as_read_only(self):
919
+
question = Question.objects.create(text="How will this be rendered?", poll=self.poll)
920
+
response = self.client.get(self.change_url)
921
+
self.assertContains(
922
+
response,
923
+
'<td class="field-text"><p>%s</p></td>' % question.text,
924
+
html=True
925
+
)
926
+
self.assertNotContains(response, 'id="id_question_set-0-text"')
927
+
self.assertNotContains(response, 'id="id_related_objs-0-DELETE"')
928
+
929
+
def test_submit_line_shows_only_close_button(self):
930
+
response = self.client.get(self.change_url)
931
+
self.assertContains(
932
+
response,
933
+
'<a href="/admin/admin_inlines/poll/" class="closelink">Close</a>',
934
+
html=True
935
+
)
936
+
delete_link = '<p class="deletelink-box"><a href="/admin/admin_inlines/poll/%s/delete/" class="deletelink">Delete</a></p>' # noqa
937
+
self.assertNotContains(
938
+
response,
939
+
delete_link % self.poll.id,
940
+
html=True
941
+
)
942
+
self.assertNotContains(response, '<input type="submit" value="Save and add another" name="_addanother">')
943
+
self.assertNotContains(response, '<input type="submit" value="Save and continue editing" name="_continue">')
944
+
945
+
def test_inline_delete_buttons_are_not_shown(self):
946
+
Question.objects.create(text="How will this be rendered?", poll=self.poll)
947
+
response = self.client.get(self.change_url)
948
+
self.assertNotContains(
949
+
response,
950
+
'<input type="checkbox" name="question_set-0-DELETE" id="id_question_set-0-DELETE">',
951
+
html=True
952
+
)
953
+
954
+
def test_extra_inlines_are_not_shown(self):
955
+
response = self.client.get(self.change_url)
956
+
self.assertNotContains(response, 'id="id_question_set-0-text"')
957
+
958
+
865
959
@override_settings(ROOT_URLCONF='admin_inlines.urls')
866
960
class SeleniumTests(AdminSeleniumTestCase):
867
961
@@ -965,6 +1059,24 @@ def test_add_inlines(self):
965
1059
self.assertEqual(ProfileCollection.objects.all().count(), 1)
966
1060
self.assertEqual(Profile.objects.all().count(), 3)
967
1061
1062
+
def test_add_inline_link_absent_for_view_only_parent_model(self):
1063
+
user = User.objects.create_user('testing', password='password', is_staff=True)
1064
+
user.user_permissions.add(
1065
+
Permission.objects.get(codename='view_poll', content_type=ContentType.objects.get_for_model(Poll))
1066
+
)
1067
+
user.user_permissions.add(
1068
+
*Permission.objects.filter(
1069
+
codename__endswith="question", content_type=ContentType.objects.get_for_model(Question)
1070
+
).values_list('pk', flat=True)
1071
+
)
1072
+
self.admin_login(username='testing', password='password')
1073
+
poll = Poll.objects.create(name="Survey")
1074
+
change_url = reverse('admin:admin_inlines_poll_change', args=(poll.id,))
1075
+
self.selenium.get(self.live_server_url + change_url)
1076
+
with self.disable_implicit_wait():
1077
+
with self.assertRaises(NoSuchElementException):
1078
+
self.selenium.find_element_by_link_text('Add another Question')
1079
+
968
1080
def test_delete_inlines(self):
969
1081
self.admin_login(username='super', password='secret')
970
1082
self.selenium.get(self.live_server_url + reverse('admin:admin_inlines_profilecollection_add'))
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4