diff --git a/CHANGELOG.rst b/CHANGELOG.rst index fcc33d3..a80261a 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,7 @@ Changelog ========= +* Fix: Enable Aldryn queryset in admin (draft) mode. 0.7.0 (2023-05-07) ================== diff --git a/aldryn_apphooks_config/tests/test_config.py b/aldryn_apphooks_config/tests/test_config.py index 045671b..ad5561f 100644 --- a/aldryn_apphooks_config/tests/test_config.py +++ b/aldryn_apphooks_config/tests/test_config.py @@ -1,16 +1,23 @@ import os.path +import sys +import unittest from copy import deepcopy from io import StringIO +import six from app_helper.base_test import BaseTestCase -from cms import api +from cms import __version__ as cms_version, api from cms.apphook_pool import apphook_pool +from cms.test_utils.testcases import CMSTestCase from cms.utils.conf import get_cms_setting from django.conf import settings +from django.contrib.auth import get_user_model from django.http import SimpleCookie from django.template import RequestContext, Template -from django.urls import reverse +from django.test.client import RequestFactory +from django.urls import clear_url_caches, reverse from django.utils.encoding import force_str +from packaging import version from ..utils import get_app_instance, get_apphook_configs, get_apphook_field_names from .utils.example.models import ( @@ -22,11 +29,59 @@ TranslatableArticle, ) +current_cms_version, cms_version_40 = version.parse(cms_version), version.parse("4.0") -class AppHookConfigTestCase(BaseTestCase): +if current_cms_version >= cms_version_40: + + # Django App Helper is not compatible with CMS > 3.x. Therefore, CMSTestCase is used, + class VersionTestCase(CMSTestCase): + def page_get_slug(self, page): + return page.get_slug(self.language) + + def page_publish(self, page, language): + pass + + def run_reload_urlconf(self): + from cms.appresolver import clear_app_resolvers, get_app_patterns + from django.conf import settings + + six.moves.reload_module(sys.modules["cms.urls"]) + six.moves.reload_module(sys.modules[settings.ROOT_URLCONF]) + clear_url_caches() + clear_app_resolvers() + get_app_patterns() + + def create_user_for_testcase(self): + self.user = get_user_model().objects.create(username="admin", is_superuser=True, is_staff=True) + + def version_request(self, path): + return RequestFactory().get(path) + +else: + + # BaseTestCase from Django App Helper is used to maintain tests for older CMS versions. + class VersionTestCase(BaseTestCase): + def page_get_slug(self, page): + return page.get_slug() + + def page_publish(self, page, language): + page.publish(language) + + def run_reload_urlconf(self): + self.reload_urlconf() + + def create_user_for_testcase(self): + pass + + def version_request(self, path): + return self.request(path) + + +class AppHookConfigTestCase(VersionTestCase): def setUp(self): self.template = get_cms_setting("TEMPLATES")[0][0] self.language = settings.LANGUAGES[0][0] + self.create_user_for_testcase() self.root_page = api.create_page("root page", self.template, self.language, published=True) # This is needed in django CMS 3.5+ to keep the same tree across # all django CMS versions @@ -75,9 +130,9 @@ def setUp(self): for page in self.root_page, self.page_1, self.page_2: for language, _ in settings.LANGUAGES[1:]: - api.create_title(language, page.get_slug(), page) - page.publish(language) - self.reload_urlconf() + api.create_title(language, self.page_get_slug(page), page) + self.page_publish(page, language) + self.run_reload_urlconf() def test_configs(self): app = apphook_pool.get_apphook(self.page_1.application_urls) @@ -98,7 +153,7 @@ def test_app_no_ns(self): self.assertEqual(("", None), config) def test_no_page(self): - request = self.request("/en/sample/login/") + request = self.version_request("/en/sample/login/") request.user = self.user request.session = {} request.cookies = SimpleCookie() @@ -354,6 +409,7 @@ def test_apphook_admin(self): self.assertContains(response, "

app1

") self.assertContains(response, 'name="config-property" type="text" value="app1_property"') + @unittest.skipIf(current_cms_version >= cms_version_40, "CMS version is higher than 3.x.") def test_admin(self): from django.contrib import admin @@ -463,3 +519,41 @@ def test_apphook_config_objects_discovery(self): obj = NotApphookedModel() configs = get_apphook_configs(obj) self.assertEqual(configs, []) + + def test_page(self): + article = Article.objects.create(title="article_app_1", slug="article_app_1", section=self.ns_app_1) + response = self.client.get("/en/page_1/") + self.assertContains(response, "namespace:app1") + self.assertContains(response, "property:app1_property") + self.assertContains(response, "objects:1") + self.assertContains( + response, + """ +
+
article_app_1
+
""".format(article.pk), + html=True, + ) + + @unittest.skipUnless(current_cms_version >= cms_version_40, "CMS version is higher than 3.x.") + def test_preview_page(self): + from cms.models.contentmodels import PageContent + from django.contrib.contenttypes.models import ContentType + + article = Article.objects.create(title="article_app_1", slug="article_app_1", section=self.ns_app_1) + content = self.page_1.get_content_obj(self.language) + page_content_type = ContentType.objects.get_for_model(PageContent) + url = reverse("admin:cms_placeholder_render_object_preview", args=(page_content_type.pk, content.pk)) + self.client.force_login(self.user) + response = self.client.get(url) + self.assertContains(response, "namespace:app1") + self.assertContains(response, "property:app1_property") + self.assertContains(response, "objects:1") + self.assertContains( + response, + """ +
+
article_app_1
+
""".format(article.pk), + html=True, + ) diff --git a/aldryn_apphooks_config/tests/utils/example/templates/app1/article_list.html b/aldryn_apphooks_config/tests/utils/example/templates/app1/article_list.html index cbb91fe..9c9a2bb 100644 --- a/aldryn_apphooks_config/tests/utils/example/templates/app1/article_list.html +++ b/aldryn_apphooks_config/tests/utils/example/templates/app1/article_list.html @@ -1,7 +1,14 @@ {% extends CMS_TEMPLATE %} {% block content %} +
 namespace:{{view.namespace}}
 property:{{view.config.property}}
 objects:{{object_list.count}}
+
+
+ {% for item in object_list %} +
{{ item.title }}
+ {% endfor %} +
{% endblock content %} diff --git a/aldryn_apphooks_config/tests/utils/example/views.py b/aldryn_apphooks_config/tests/utils/example/views.py index 316da33..b5e880c 100644 --- a/aldryn_apphooks_config/tests/utils/example/views.py +++ b/aldryn_apphooks_config/tests/utils/example/views.py @@ -19,7 +19,8 @@ class ArticleList(AppConfigMixin, ListView): model = Article def get_template_names(self): - return "%s/article_list.html" % self.config.namespace + namespace = "app1" if self.config is None else self.config.namespace + return "%s/article_list.html" % namespace def get_queryset(self): return Article.objects.all().filter(section__namespace=self.namespace) diff --git a/aldryn_apphooks_config/utils.py b/aldryn_apphooks_config/utils.py index eb43c28..b2a704f 100644 --- a/aldryn_apphooks_config/utils.py +++ b/aldryn_apphooks_config/utils.py @@ -23,6 +23,9 @@ def get_app_instance(request): config = None with override(get_language_from_request(request, check_path=True)): namespace = resolve(request.path_info).namespace + if namespace == "admin" and request.current_page.application_namespace: + # Enable Aldryn queryset in admin (draft) mode. + namespace = request.current_page.application_namespace config = app.get_config(namespace) return namespace, config except Resolver404: diff --git a/requirements-test.txt b/requirements-test.txt index 4e2461f..ace3af8 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -7,3 +7,4 @@ django-parler>=1.4 https://github.com/ella/django-appdata/archive/refs/heads/master.zip coverage coveralls>=2.0 +packaging diff --git a/test_settings.py b/test_settings.py index 0b4ed6a..383ca1a 100644 --- a/test_settings.py +++ b/test_settings.py @@ -25,6 +25,7 @@ "aldryn_apphooks_config.tests.utils.example", "parler", ], + CMS_CONFIRM_VERSION4=True, ) diff --git a/tox.ini b/tox.ini index 6017bb4..c4e7747 100644 --- a/tox.ini +++ b/tox.ini @@ -8,12 +8,14 @@ envlist = pypi-description towncrier py{311,310,39}-django{42}-cms{311} - py{311,310,39}-django{41,40,32}-cms{311,310} + py{311,310,39}-django{41,40,32}-cms{311} py{311,310,39}-django{32}-cms{39} + py{312}-cms{50} minversion = 3.23 [testenv] -commands = {env:COMMAND:python} test_settings.py +; tox -e py312-cms50 -- test aldryn_apphooks_config.tests.test_config.AppHookConfigTestCase.test_preview_page +commands = {env:COMMAND:python} test_settings.py {posargs} deps= -r{toxinidir}/requirements-test.txt django32: django~=3.2.0 @@ -21,8 +23,8 @@ deps= django41: django~=4.1.0 django42: django~=4.2.0 cms39: https://github.com/django-cms/django-cms/archive/release/3.9.x.zip - cms310: https://github.com/django-cms/django-cms/archive/release/3.10.x.zip cms311: https://github.com/yakky/django-cms/archive/release/3.11.x.zip + cms50: django-cms~=5.0 passenv = COMMAND PYTEST_*