diff options
| author | SiHyunLee <antoliny0919@gmail.com> | 2026-02-20 23:43:41 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-02-20 09:43:41 -0500 |
| commit | 283ea9e9e014adf0013c18700c36b98efa2f0aac (patch) | |
| tree | b8725eb30bae3e1f3e81d9538f74db419f07432e /tests/admin_views | |
| parent | 96984b9b0f1d88f096985a908ee67dc6f2b9a682 (diff) | |
Fixed #36127 -- Applied default empty display value to links otherwise containing only whitespace in admin.
Diffstat (limited to 'tests/admin_views')
| -rw-r--r-- | tests/admin_views/admin.py | 2 | ||||
| -rw-r--r-- | tests/admin_views/tests.py | 184 |
2 files changed, 183 insertions, 3 deletions
diff --git a/tests/admin_views/admin.py b/tests/admin_views/admin.py index 8e8f7a32cc..6f7cd79e50 100644 --- a/tests/admin_views/admin.py +++ b/tests/admin_views/admin.py @@ -709,6 +709,8 @@ class CoverLetterAdmin(admin.ModelAdmin): For testing fix for ticket #14529. """ + formfield_overrides = {models.CharField: {"strip": False}} + def get_queryset(self, request): return super().get_queryset(request).defer("date_written") diff --git a/tests/admin_views/tests.py b/tests/admin_views/tests.py index fa9d9a2dc6..ea657fbf9f 100644 --- a/tests/admin_views/tests.py +++ b/tests/admin_views/tests.py @@ -2862,7 +2862,9 @@ class AdminViewPermissionsTest(TestCase): self.assertContains(response, "<h1>Select article to view</h1>") self.assertEqual(response.context["title"], "Select article to view") response = self.client.get(article_change_url) - self.assertContains(response, "<title>View article | Django site admin</title>") + self.assertContains( + response, "<title>- | View article | Django site admin</title>" + ) self.assertContains(response, "<h1>View article</h1>") self.assertContains(response, "<label>Extra form field:</label>") self.assertContains( @@ -2891,7 +2893,7 @@ class AdminViewPermissionsTest(TestCase): self.assertEqual(response.context["title"], "Change article") self.assertContains( response, - "<title>Change article | Django site admin</title>", + "<title>- | Change article | Django site admin</title>", ) self.assertContains(response, "<h1>Change article</h1>") post = self.client.post(article_change_url, change_dict) @@ -3016,7 +3018,9 @@ class AdminViewPermissionsTest(TestCase): self.client.force_login(self.viewuser) response = self.client.get(change_url) self.assertEqual(response.context["title"], "View article") - self.assertContains(response, "<title>View article | Django site admin</title>") + self.assertContains( + response, "<title>- | View article | Django site admin</title>" + ) self.assertContains(response, "<h1>View article</h1>") self.assertContains( response, @@ -3608,6 +3612,180 @@ class AdminViewPermissionsTest(TestCase): ) +@override_settings(ROOT_URLCONF="admin_views.urls") +class AdminConsecutiveWhiteSpaceObjectDisplayTest(TestCase): + @classmethod + def setUpTestData(cls): + cls.user = User.objects.create_superuser( + username=" ", password="secret", email="super@example.com" + ) + cls.obj = CoverLetter.objects.create(author=" ") + cls.change_link = reverse( + "admin:admin_views_coverletter_change", args=(cls.obj.pk,) + ) + + def setUp(self): + self.client.force_login(self.user) + + def test_display_consecutive_whitespace_object_in_breadcrumbs(self): + user_change_link = reverse("admin:auth_user_change", args=(self.user.pk,)) + cases = [ + ( + self.change_link, + '<li><a href="/test_admin/admin/admin_views/coverletter/">' + 'Cover letters</a></li><li aria-current="page">-</li>', + ), + ( + reverse("admin:admin_views_coverletter_delete", args=(self.obj.pk,)), + f'<li><a href="{self.change_link}">-</a></li><li aria-current="page">' + "Delete</li>", + ), + ( + reverse("admin:admin_views_coverletter_history", args=(self.obj.pk,)), + f'<li><a href="{self.change_link}">-</a></li><li aria-current="page">' + "History</li>", + ), + ( + reverse("admin:auth_user_password_change", args=(self.user.pk,)), + f'<li><a href="{user_change_link}">-</a></li><li aria-current="page">' + "Change password</li>", + ), + ] + for url, expected_breadcrumbs in cases: + with self.subTest(url=url, expected_breadcrumbs=expected_breadcrumbs): + response = self.client.get(url) + self.assertContains(response, expected_breadcrumbs, html=True) + + def test_display_consecutive_whitespace_object_in_delete_confirmation_page(self): + response = self.client.get( + reverse("admin:admin_views_coverletter_delete", args=(self.obj.pk,)) + ) + self.assertContains( + response, + "Are you sure you want to delete the cover letter “-”?", + ) + + # delete protected case + q = Question.objects.create(question=" ") + Answer.objects.create(question=q, answer="Because.") + response = self.client.get( + reverse("admin:admin_views_question_delete", args=(q.pk,)) + ) + self.assertContains( + response, + "Deleting the question “-” would require deleting the following protected " + "related objects", + ) + + # delete forbidden case + no_perms_user = User.objects.create_user( + username="no-perm", password="secret", is_staff=True + ) + no_perms_user.user_permissions.add( + get_perm(Question, get_permission_codename("view", Question._meta)) + ) + no_perms_user.user_permissions.add( + get_perm(Question, get_permission_codename("delete", Question._meta)) + ) + self.client.force_login(no_perms_user) + response = self.client.get( + reverse("admin:admin_views_question_delete", args=(q.pk,)) + ) + self.assertContains( + response, + "Deleting the question “-” would result in deleting related objects, " + "but your account doesn't have permission to delete " + "the following types of objects", + ) + + def test_display_consecutive_whitespace_object_in_changelist(self): + response = self.client.get(reverse("admin:admin_views_coverletter_changelist")) + self.assertContains(response, f'<a href="{self.change_link}">-</a>') + + def test_display_consecutive_whitespace_object_in_deleted_object(self): + response = self.client.get( + reverse("admin:admin_views_coverletter_delete", args=(self.obj.pk,)) + ) + self.assertContains( + response, + '<ul id="deleted-objects">' + f'<li>Cover letter: <a href="{self.change_link}">-</a></li></ul>', + html=True, + ) + + def test_display_consecutive_whitespace_object_in_recent_action(self): + for action in [ADDITION, DELETION]: + LogEntry.objects.log_actions( + user_id=self.user.pk, + queryset=[self.obj], + action_flag=action, + change_message=[], + single_object=True, + ) + + response = self.client.get(reverse("admin:index")) + self.assertContains( + response, + '<li class="addlink"><span class="visually-hidden">Added:</span>' + f'<a href="{self.change_link}">-</a><br><span class="mini quiet">' + "Cover letter</span></li>", + html=True, + ) + self.assertContains( + response, + '<li class="deletelink">' + '<span class="visually-hidden">Deleted:</span>-' + '<br><span class="mini quiet">Cover letter</span></li>', + html=True, + ) + + def test_display_consecutive_whitespace_object_in_messages(self): + buttons = ["_save", "_continue", "_addanother"] + for button in buttons: + body = {"author": self.obj.author, button: "1"} + with self.subTest(obj=self.obj, button=button): + response = self.client.post( + reverse("admin:admin_views_coverletter_add"), body, follow=True + ) + latest_cl = CoverLetter.objects.latest("id") + change_link = reverse( + "admin:admin_views_coverletter_change", args=(latest_cl.pk,) + ) + self.assertContains( + response, + f'The cover letter “<a href="{change_link}">-</a>” ' + "was added successfully.", + ) + response = self.client.post( + reverse( + "admin:admin_views_coverletter_change", args=(latest_cl.pk,) + ), + {**body, "author": " "}, + follow=True, + ) + self.assertContains( + response, + f'The cover letter “<a href="{change_link}">-</a>” ' + "was changed successfully.", + ) + + new_obj = CoverLetter.objects.create(author=self.obj.author) + response = self.client.post( + reverse("admin:admin_views_coverletter_delete", args=(new_obj.pk,)), + {"post": "yes"}, + follow=True, + ) + self.assertContains(response, "The cover letter “-” was deleted successfully.") + + def test_display_consecutive_whitespace_object_in_sub_title(self): + response = self.client.get(self.change_link) + self.assertContains(response, "<h2>-</h2>") + response = self.client.get( + reverse("admin:admin_views_coverletter_history", args=(self.obj.pk,)) + ) + self.assertContains(response, "<h1>Change history: -</h1>") + + @override_settings( ROOT_URLCONF="admin_views.urls", TEMPLATES=[ |
