From e03c41250776612468226597a077ba1fc2d9b865 Mon Sep 17 00:00:00 2001 From: Neeraj P Yetheendran Date: Wed, 7 Feb 2024 10:01:02 +0530 Subject: [PATCH] Fix inconsistent use of model verbose_name in permissions UI - Fixes #10982 - Rework of #11203 - Modify the sanitized `permission_action` name - Relates to work around for the known Django issue https://code.djangoproject.com/ticket/26756 --- CHANGELOG.txt | 1 + docs/releases/6.1.md | 1 + .../migrations/0034_modelwithverbosename.py | 31 +++++++++++++++++++ wagtail/test/testapp/models.py | 9 ++++++ .../users/templatetags/wagtailusers_tags.py | 10 +++--- wagtail/users/tests/test_admin_views.py | 29 +++++++++++++++++ 6 files changed, 76 insertions(+), 5 deletions(-) create mode 100644 wagtail/test/testapp/migrations/0034_modelwithverbosename.py diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 84f9550ea4..537ce299a9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -14,6 +14,7 @@ Changelog * Fix: Ensure that unit tests correctly check for migrations in all core Wagtail apps (Matt Westcott) * Fix: Correctly handle `date` objects on `human_readable_date` template tag (Jhonatan Lopes) * Fix: Ensure re-ordering buttons work correctly when using a nested InlinePanel (Adrien Hamraoui) + * Fix: Resolve inconsistent use of model `verbose_name` in group edit view when listing custom permissions (Neeraj Yetheendran, Omkar Jadhav) * Docs: Add contributing development documentation on how to work with a fork of Wagtail (Nix Asteri, Dan Braghis) * Docs: Make sure the settings panel is listed in tabbed interface examples (Tibor Leupold) * Docs: Update multiple pages in the reference sections and multiple page names to their US spelling instead of UK spelling (Victoria Poromon) diff --git a/docs/releases/6.1.md b/docs/releases/6.1.md index ea01e77330..70f8cdf79f 100644 --- a/docs/releases/6.1.md +++ b/docs/releases/6.1.md @@ -27,6 +27,7 @@ depth: 1 * Ensure that unit tests correctly check for migrations in all core Wagtail apps (Matt Westcott) * Correctly handle `date` objects on `human_readable_date` template tag (Jhonatan Lopes) * Ensure re-ordering buttons work correctly when using a nested InlinePanel (Adrien Hamraoui) + * Resolve inconsistent use of model `verbose_name` in group edit view when listing custom permissions (Neeraj Yetheendran, Omkar Jadhav) ### Documentation diff --git a/wagtail/test/testapp/migrations/0034_modelwithverbosename.py b/wagtail/test/testapp/migrations/0034_modelwithverbosename.py new file mode 100644 index 0000000000..28a566f70d --- /dev/null +++ b/wagtail/test/testapp/migrations/0034_modelwithverbosename.py @@ -0,0 +1,31 @@ +# Generated by Django 4.2.7 on 2024-02-12 22:02 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("tests", "0033_customcopyformpage"), + ] + + operations = [ + migrations.CreateModel( + name="ModelWithVerboseName", + fields=[ + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ], + options={ + "verbose_name": "Custom verbose name", + "verbose_name_plural": "Custom verbose names", + }, + ), + ] diff --git a/wagtail/test/testapp/models.py b/wagtail/test/testapp/models.py index 4ff07c90e3..10b378c079 100644 --- a/wagtail/test/testapp/models.py +++ b/wagtail/test/testapp/models.py @@ -1921,6 +1921,15 @@ class TableBlockStreamPage(Page): content_panels = [FieldPanel("table")] +class ModelWithVerboseName(ClusterableModel): + class Meta: + verbose_name = "Custom verbose name" + verbose_name_plural = "Custom verbose names" + + +register_snippet(ModelWithVerboseName) + + class UserProfile(models.Model): # Wagtail's schema must be able to coexist alongside a custom UserProfile model user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) diff --git a/wagtail/users/templatetags/wagtailusers_tags.py b/wagtail/users/templatetags/wagtailusers_tags.py index 4e43d9d6a5..9fdc154b5c 100644 --- a/wagtail/users/templatetags/wagtailusers_tags.py +++ b/wagtail/users/templatetags/wagtailusers_tags.py @@ -1,5 +1,4 @@ import itertools -import re from django import template @@ -85,7 +84,10 @@ def format_permissions(permission_bound_field): checkbox = checkboxes_by_id[perm.id] # identify the main categories of permission, and assign to # the relevant dict key, else bung in the 'custom_perms' list - permission_action = perm.codename.split("_")[0] + permission_action = perm.codename.split("_", maxsplit=1) + permission_action = permission_action[permission_action[0].lower() == "can"] + permission_action = permission_action.rsplit(maxsplit=1)[0] + if permission_action in main_permission_names: if permission_action in extra_perms_exist: extra_perms_exist[permission_action] = True @@ -98,9 +100,7 @@ def format_permissions(permission_bound_field): custom_perms.append( { "perm": perm, - "name": re.sub( - f"{perm.content_type.name}$", "", perm.name, flags=re.I - ).strip(), + "name": f"Can {permission_action}", "selected": checkbox.data["selected"], } ) diff --git a/wagtail/users/tests/test_admin_views.py b/wagtail/users/tests/test_admin_views.py index e08f3462b4..7b227a4722 100644 --- a/wagtail/users/tests/test_admin_views.py +++ b/wagtail/users/tests/test_admin_views.py @@ -1567,6 +1567,35 @@ class TestGroupCreateView(AdminTemplateTestUtils, WagtailTestUtils, TestCase): # Should not show inputs for publish permissions on models without DraftStateMixin self.assertNotInHTML("Can publish advert", html) + def test_view_permission_if_model_has_verbose(self): + """ + Tests for bug #10982 + https://github.com/wagtail/wagtail/issues/10982 + + Ensures Model Name or Verbose Name is stripped from Custom Permissions before being displayed + A Model "ModelWithVerboseName" is added to wagtail.test.testapp.models with verbose_name = "Custom Verbose Name" + + """ + response = self.get() + + self.assertContains(response, "Can view", msg_prefix="No Can view permission") + self.assertNotContains( + response, + "Can view model with verbose name", + msg_prefix=" Model Name not stripped from Can view permission", + ) + self.assertNotContains( + response, + "Can view custom verbose name", + msg_prefix="Verbose Name of ModelWithVerboseName not stripped from Can view permission", + ) + pattern = r'Can\sview\s\[.*?"' + self.assertNotRegex( + response.content.decode(), + pattern, + msg="Model Name not stripped from custom permissions", + ) + class TestGroupEditView(AdminTemplateTestUtils, WagtailTestUtils, TestCase): def setUp(self):