From 037c480253bcc9d177226e30246c934a51ac888c Mon Sep 17 00:00:00 2001 From: Halit Date: Sat, 2 Nov 2024 14:38:19 +0100 Subject: [PATCH 1/2] Fall back to class name when app name is None --- cms/apphook_pool.py | 3 +-- cms/tests/test_apphooks.py | 27 ++++++++++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/cms/apphook_pool.py b/cms/apphook_pool.py index 68574990051..fc732f74e34 100644 --- a/cms/apphook_pool.py +++ b/cms/apphook_pool.py @@ -73,9 +73,8 @@ def get_apphooks(self): for app_name in self.apps: app = self.apps[app_name] - if app.get_urls(): - hooks.append((app_name, app.name)) + hooks.append((app_name, app.name or app_name)) # Unfortunately, we lose the ordering since we now have a list of # tuples. Let's reorder by app_name: diff --git a/cms/tests/test_apphooks.py b/cms/tests/test_apphooks.py index f08a316208f..de06525e96e 100644 --- a/cms/tests/test_apphooks.py +++ b/cms/tests/test_apphooks.py @@ -15,11 +15,7 @@ from cms.api import create_page, create_page_content from cms.app_base import CMSApp from cms.apphook_pool import apphook_pool -from cms.appresolver import ( - applications_page_check, - clear_app_resolvers, - get_app_patterns, -) +from cms.appresolver import applications_page_check, clear_app_resolvers, get_app_patterns from cms.middleware.page import get_page from cms.models import PageContent from cms.test_utils.project.placeholderapp.models import Example1 @@ -332,6 +328,27 @@ def test_apphooks_with_excluded_permissions(self): self.assertEqual(not_excluded_response.status_code, 302) self.apphook_clear() + @override_settings(CMS_APPHOOKS=[f'{APP_MODULE}.{APP_NAME}']) + def test_apphook_without_name_defaults_to_class_name(self): + """ + Test that an apphook without a name defaults to the class name. + """ + @apphook_pool.register + class AppWithoutName(CMSApp): + def get_urls(self, page=None, language=None, **kwargs): + return ["sampleapp.urls"] + + @apphook_pool.register + class AppWithName(CMSApp): + name = "Custom name" + def get_urls(self, page=None, language=None, **kwargs): + return ["sampleapp.urls"] + + hooks = apphook_pool.get_apphooks() + hook_names = dict(hooks) + self.assertEqual(hook_names.get('AppWithoutName'), 'AppWithoutName') + self.assertEqual(hook_names.get('AppWithName'), 'Custom name') + @override_settings(ROOT_URLCONF='cms.test_utils.project.urls_3') def test_get_page_for_apphook_on_preview_or_edit(self): if get_user_model().USERNAME_FIELD == 'email': From 0b838ac5de257aa7715237f4e604435e284aad91 Mon Sep 17 00:00:00 2001 From: Halit Celik Date: Mon, 4 Nov 2024 10:24:26 +0100 Subject: [PATCH 2/2] Adds a check for CMSApps without name and test --- cms/tests/test_check.py | 11 +++++++++++ cms/utils/check.py | 12 ++++++++++++ 2 files changed, 23 insertions(+) diff --git a/cms/tests/test_check.py b/cms/tests/test_check.py index cd906819bb5..543b6626ef2 100644 --- a/cms/tests/test_check.py +++ b/cms/tests/test_check.py @@ -135,6 +135,17 @@ def test_non_numeric_site_id(self): with self.settings(SITE_ID='broken'): self.assertCheck(False, warnings=0, errors=1) + def test_cmsapps_check(self): + from cms.app_base import CMSApp + from cms.apphook_pool import apphook_pool + class AppWithoutName(CMSApp): + def get_urls(self, page=None, language=None, **kwargs): + return ["sampleapp.urls"] + + app = apphook_pool.register(AppWithoutName) + + self.assertCheck(True, warnings=1, errors=0) + apphook_pool.apps.pop(app.__name__) class CheckWithDatabaseTests(CheckAssertMixin, TestCase): diff --git a/cms/utils/check.py b/cms/utils/check.py index e46557f84c3..9de52e417e3 100644 --- a/cms/utils/check.py +++ b/cms/utils/check.py @@ -371,6 +371,18 @@ def check_template_conf(output): "Will run in headless mode with one placeholder called \"content\"") +@define_check +def check_cmsapps_names(output): + from cms.apphook_pool import apphook_pool + with output.section("Apphooks") as section: + for hook, name in apphook_pool.get_apphooks(): + if apphook_pool.get_apphook(hook).name is None: + section.warn("CMSApps should define a name. %s doesn't have a name" % name) + if section.successful: + section.finish_success("CMSApps configuration is okay") + + + def check(output): """ Checks the configuration/environment of this django CMS installation.