diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 8bc4fe0..2cb4507 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -9,15 +9,14 @@ jobs:
continue-on-error: ${{ matrix.continue-on-error }}
strategy:
matrix:
- python-version: ["3.11", "3.10", "3.9"]
- django: [42, 41, 32]
- cms: [311, 39]
+ python-version: ["3.8", "3.9", "3.10"]
+ django: [32, 42]
+ cms: [40]
+ requirements-file: [
+ dj32_cms40.txt,
+ dj42_cms40.txt,
+ ]
continue-on-error: [true]
- exclude:
- - django: 41
- cms: 39
- - django: 42
- cms: 39
steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
@@ -40,6 +39,8 @@ jobs:
${{ runner.os }}-tox-${{ format('{{py{0}-django{1}-cms{2}}}', matrix.python-version, matrix.django, matrix.cms) }}-
- name: Install dependencies
run: |
+ python setup.py install
+ pip install -r tests/requirements/dj${{matrix.django}}_cms${{matrix.cms}}.txt
sudo apt-get install gettext
python -m pip install --upgrade pip setuptools tox>4
- name: Test with tox
diff --git a/changes/82.feature b/changes/82.feature
new file mode 100644
index 0000000..7ae4c66
--- /dev/null
+++ b/changes/82.feature
@@ -0,0 +1 @@
+Add support for django CMS 4+
diff --git a/changes/910.feature b/changes/910.feature
new file mode 100644
index 0000000..9d140fd
--- /dev/null
+++ b/changes/910.feature
@@ -0,0 +1,3 @@
+* Update tooling and ci test suite to Github Actions
+* Add compatibility with Django 3.2
+* Drop compatibility with Django < 2.2
diff --git a/cms_helper.py b/cms_helper.py
index 4dae60a..a9fabc7 100755
--- a/cms_helper.py
+++ b/cms_helper.py
@@ -6,9 +6,6 @@ def gettext(s):
HELPER_SETTINGS = {
- "NOSE_ARGS": [
- "-s",
- ],
"CACHES": {
"default": {
"BACKEND": "django.core.cache.backends.locmem.LocMemCache",
@@ -19,6 +16,7 @@ def gettext(s):
"content": 10,
"permissions": 10,
},
+ "CMS_CONFIRM_VERSION4": True,
"ROOT_URLCONF": "tests.test_utils.urls",
"INSTALLED_APPS": [
"django.contrib.sitemaps",
@@ -53,6 +51,12 @@ def gettext(s):
},
},
}
+try:
+ import djangocms_versioning # noqa: F401
+
+ HELPER_SETTINGS["INSTALLED_APPS"].append("djangocms_versioning")
+except ImportError:
+ pass
def run():
diff --git a/djangocms_page_sitemap/cms_toolbars.py b/djangocms_page_sitemap/cms_toolbars.py
index 01c8a13..df7fa50 100644
--- a/djangocms_page_sitemap/cms_toolbars.py
+++ b/djangocms_page_sitemap/cms_toolbars.py
@@ -1,7 +1,3 @@
-from cms.api import get_page_draft
-from cms.cms_toolbars import PAGE_MENU_THIRD_BREAK
-from cms.toolbar.items import Break
-from cms.toolbar_base import CMSToolbar
from cms.toolbar_pool import toolbar_pool
from cms.utils.conf import get_cms_setting
from cms.utils.permissions import has_page_permission
@@ -10,14 +6,20 @@
from .models import PageSitemapProperties
+# Handle versioned toolbar if it exists, otherwise just use the normal CMS toolbar
+try:
+ from djangocms_versioning.cms_toolbars import VersioningPageToolbar as PageToolbar
+except ImportError:
+ from cms.cms_toolbars import PageToolbar
+
+
PAGE_SITEMAP_MENU_TITLE = _("Sitemap properties")
@toolbar_pool.register
-class PageSitemapPropertiesMeta(CMSToolbar):
+class PageSitemapPropertiesMeta(PageToolbar):
def populate(self):
- # always use draft if we have a page
- self.page = get_page_draft(self.request.current_page)
+ self.page = self.request.current_page
if not self.page:
return
if self.page.is_page_type:
@@ -36,7 +38,6 @@ def populate(self):
if has_global_current_page_change_permission or can_change:
not_edit_mode = not self.toolbar.edit_mode_active
current_page_menu = self.toolbar.get_or_create_menu("page")
- position = current_page_menu.find_first(Break, identifier=PAGE_MENU_THIRD_BREAK) - 1
# Page tags
try:
page_extension = PageSitemapProperties.objects.get(extended_object_id=self.page.pk)
@@ -45,21 +46,14 @@ def populate(self):
try:
if page_extension:
url = reverse(
- "admin:djangocms_page_sitemap_pagesitemapproperties_change",
- args=(page_extension.pk,),
+ "admin:djangocms_page_sitemap_pagesitemapproperties_change", args=(page_extension.pk,)
)
else:
url = "{}?extended_object={}".format(
- reverse("admin:djangocms_page_sitemap_pagesitemapproperties_add"),
- self.page.pk,
+ reverse("admin:djangocms_page_sitemap_pagesitemapproperties_add"), self.page.pk
)
except NoReverseMatch: # pragma: no cover
# not in urls
pass
else:
- current_page_menu.add_modal_item(
- PAGE_SITEMAP_MENU_TITLE,
- url=url,
- disabled=not_edit_mode,
- position=position,
- )
+ current_page_menu.add_modal_item(PAGE_SITEMAP_MENU_TITLE, url=url, disabled=not_edit_mode)
diff --git a/djangocms_page_sitemap/models.py b/djangocms_page_sitemap/models.py
index ea2fb99..15db55a 100644
--- a/djangocms_page_sitemap/models.py
+++ b/djangocms_page_sitemap/models.py
@@ -14,10 +14,7 @@
@extension_pool.register
class PageSitemapProperties(PageExtension):
changefreq = models.CharField(
- _("Change frequency"),
- max_length=20,
- default="monthly",
- choices=PAGE_SITEMAP_CHANGEFREQ_LIST.items(),
+ _("Change frequency"), max_length=20, default="monthly", choices=PAGE_SITEMAP_CHANGEFREQ_LIST.items()
)
priority = models.DecimalField(
_("Priority"),
@@ -28,14 +25,10 @@ class PageSitemapProperties(PageExtension):
)
include_in_sitemap = models.BooleanField(_("Include in sitemap"), default=True)
noindex = models.BooleanField(
- _("Mark as no index"),
- default=False,
- help_text=_("Add meta tag robots with value noindex"),
+ _("Mark as no index"), default=False, help_text=_("Add meta tag robots with value noindex")
)
noarchive = models.BooleanField(
- _("Mark as no archive"),
- default=False,
- help_text=_("Add meta tag robots with value noarchive"),
+ _("Mark as no archive"), default=False, help_text=_("Add meta tag robots with value noarchive")
)
robots_extra = models.CharField(
_("Extra robots value"),
diff --git a/djangocms_page_sitemap/sitemap.py b/djangocms_page_sitemap/sitemap.py
index eb9a47c..676459b 100644
--- a/djangocms_page_sitemap/sitemap.py
+++ b/djangocms_page_sitemap/sitemap.py
@@ -1,9 +1,12 @@
from cms.sitemaps import CMSSitemap
+from cms.utils import get_current_site
+from cms.utils.i18n import get_public_languages
from django.core.cache import cache
+from django.db.models import Prefetch
from .models import PageSitemapProperties
from .settings import PAGE_SITEMAP_CACHE_DURATION, PAGE_SITEMAP_DEFAULT_CHANGEFREQ
-from .utils import get_cache_key
+from .utils import get_cache_key, is_versioning_enabled
class ExtendedSitemap(CMSSitemap):
@@ -11,7 +14,41 @@ class ExtendedSitemap(CMSSitemap):
default_priority = CMSSitemap.priority
def items(self):
- return super().items().exclude(page__pagesitemapproperties__include_in_sitemap=False)
+ try:
+ from cms.models import PageContent, PageUrl
+
+ # FIXME:This method was created from this commit:
+ # https://github.com/divio/django-cms/blob/2894ae8bcf92092d947a097499c01ab2bbb0e6df/cms/sitemaps/cms_sitemap.py
+ site = get_current_site()
+ languages = get_public_languages(site_id=site.pk)
+ page_content_prefetch = Prefetch(
+ "page__pagecontent_set",
+ queryset=PageContent.objects.filter(
+ language__in=languages,
+ ),
+ )
+ all_urls = (
+ PageUrl.objects.get_for_site(site)
+ .prefetch_related(page_content_prefetch)
+ .filter(
+ language__in=languages,
+ path__isnull=False,
+ page__login_required=False,
+ page__node__site=site,
+ )
+ .exclude(page__pagesitemapproperties__include_in_sitemap=False)
+ .order_by("page__node__path")
+ )
+ valid_urls = []
+ for page_url in all_urls:
+ for page_content in page_url.page.pagecontent_set.all():
+ if page_url.language == page_content.language:
+ valid_urls.append(page_url)
+ break
+
+ return valid_urls
+ except ImportError:
+ return super().items().exclude(page__pagesitemapproperties__include_in_sitemap=False)
def priority(self, title):
ext_key = get_cache_key(title.page)
@@ -44,3 +81,22 @@ def changefreq(self, title):
return title.page.pagesitemapproperties.changefreq
except PageSitemapProperties.DoesNotExist:
return self.default_changefreq
+
+ def lastmod(self, page_url):
+ # if versioning is enabled we return the latest version modified using the versioning
+ # modified date. if versioning is disabled we return the page changed_date
+ if is_versioning_enabled():
+ from cms.models import PageContent
+
+ site = get_current_site()
+ page_contents = PageContent.objects.filter(
+ page=page_url.page,
+ language=page_url.language,
+ page__node__site=site,
+ ).first()
+
+ if page_contents:
+ published_version = page_contents.versions.first()
+ return published_version.modified
+
+ return page_url.page.changed_date
diff --git a/djangocms_page_sitemap/utils.py b/djangocms_page_sitemap/utils.py
index e7b4c9a..2428efb 100644
--- a/djangocms_page_sitemap/utils.py
+++ b/djangocms_page_sitemap/utils.py
@@ -1,4 +1,5 @@
from cms.cache import _get_cache_key
+from django.apps import apps
def get_cache_key(page):
@@ -7,3 +8,17 @@ def get_cache_key(page):
"""
site_id = page.node.site_id
return _get_cache_key("page_sitemap", page, "default", site_id)
+
+
+def is_versioning_enabled():
+ """Check if djangocms-versioning plugin is installed."""
+ try:
+ from cms.models import PageContent
+
+ try:
+ app_config = apps.get_app_config("djangocms_versioning")
+ return app_config.cms_extension.is_content_model_versioned(PageContent)
+ except LookupError: # pragma: no cover
+ return False
+ except ImportError:
+ return False
diff --git a/setup.cfg b/setup.cfg
index 2afe59b..4619a7b 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -23,11 +23,9 @@ classifiers =
Framework :: Django :: 4.1
Framework :: Django :: 4.2
Programming Language :: Python :: 3
- Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
- Programming Language :: Python :: 3.11
[options]
include_package_data = True
@@ -36,7 +34,7 @@ install_requires =
setup_requires =
setuptools
packages = djangocms_page_sitemap
-python_requires = >=3.7
+python_requires = >=3.8
zip_safe = False
test_suite = cms_helper.run
diff --git a/tests/base.py b/tests/base.py
index e2d8a04..4611dcf 100644
--- a/tests/base.py
+++ b/tests/base.py
@@ -1,10 +1,13 @@
from io import StringIO
+from cms.api import create_page, create_title
from cms.utils.i18n import get_language_list
from django.contrib.auth.models import User
from django.http import HttpResponse, SimpleCookie
from django.test import RequestFactory, TestCase
+from djangocms_page_sitemap.utils import is_versioning_enabled
+
class BaseTest(TestCase):
"""
@@ -27,8 +30,14 @@ def setUpClass(cls):
cls.user_normal = User.objects.create(username="normal")
def get_pages(self):
- from cms.api import create_page, create_title
+ try:
+ from cms.models import PageContent # noqa: F401
+
+ return self._cms_4_pages()
+ except ImportError:
+ return self._cms_3_pages()
+ def _cms_3_pages(self):
page_1 = create_page("page one", "page.html", language="en")
page_2 = create_page("page two", "page.html", language="en")
page_3 = create_page("page three", "page.html", language="en")
@@ -49,6 +58,29 @@ def get_pages(self):
page_3.get_draft_object(),
)
+ def _cms_4_pages(self):
+ from cms.models import PageContent # noqa: F401
+
+ page_1 = create_page("page one", "page.html", language="en", created_by=self.user)
+ page_2 = create_page("page two", "page.html", language="en", created_by=self.user)
+ page_3 = create_page("page three", "page.html", language="en", created_by=self.user)
+ page_content1 = PageContent._base_manager.get(page=page_1, language="en")
+ page_content2 = PageContent._base_manager.get(page=page_2, language="en")
+ page_content3 = PageContent._base_manager.get(page=page_3, language="en")
+ page_1_content_fr = create_title(language="fr", title="page un", page=page_1, created_by=self.user)
+ page_1_content_it = create_title(language="it", title="pagina uno", page=page_1, created_by=self.user)
+ page_3_content_fr = create_title(language="fr", title="page trois", page=page_3, created_by=self.user)
+ if is_versioning_enabled():
+ page_content1.versions.first().publish(self.user)
+ page_content2.versions.first().publish(self.user)
+ page_content3.versions.first().publish(self.user)
+ page_1_content_fr.versions.first().publish(self.user)
+ page_1_content_it.versions.first().publish(self.user)
+ page_3_content_fr.versions.first().publish(self.user)
+ if hasattr(page_1, "set_as_homepage"):
+ page_1.set_as_homepage()
+ return page_1, page_2, page_3
+
def get_request(self, page, lang):
request = self.request_factory.get(page.get_path(lang))
request.current_page = page
@@ -75,7 +107,7 @@ def get_page_request(self, page, user, path=None, edit=False, lang_code="en"):
request.GET = {"edit_off": None}
request.current_page = page
if hasattr(ToolbarMiddleware, "process_request"):
- mid = ToolbarMiddleware()
+ mid = ToolbarMiddleware(lambda req: HttpResponse())
mid.process_request(request)
else:
mid = ToolbarMiddleware(lambda req: HttpResponse())
diff --git a/tests/requirements/dj32_cms40.txt b/tests/requirements/dj32_cms40.txt
new file mode 100644
index 0000000..80e163e
--- /dev/null
+++ b/tests/requirements/dj32_cms40.txt
@@ -0,0 +1,4 @@
+-r requirements_base.txt
+
+Django>=3.2,<4
+
diff --git a/tests/requirements/dj42_cms40.txt b/tests/requirements/dj42_cms40.txt
new file mode 100644
index 0000000..9107cb2
--- /dev/null
+++ b/tests/requirements/dj42_cms40.txt
@@ -0,0 +1,4 @@
+-r requirements_base.txt
+
+Django>=4.2,<5
+
diff --git a/tests/requirements/requirements_base.txt b/tests/requirements/requirements_base.txt
new file mode 100644
index 0000000..4ad6077
--- /dev/null
+++ b/tests/requirements/requirements_base.txt
@@ -0,0 +1,7 @@
+-e .[docs]
+coverage>5
+coveralls>2
+mock>=1.0.1
+django-app-helper>=2.0.0
+
+https://github.com/django-cms/django-cms/tarball/release/4.0.1.x#egg=django-cms
\ No newline at end of file
diff --git a/tests/test_models.py b/tests/test_models.py
index 42f72b7..4aee45a 100644
--- a/tests/test_models.py
+++ b/tests/test_models.py
@@ -56,17 +56,19 @@ def test_robots_options(self):
def test_robots_page_parameter(self):
page1, page2, page3 = self.get_pages()
extension = PageSitemapProperties.objects.create(extended_object=page1, priority="0.2", changefreq="never")
- page1.publish("en")
+ if hasattr(page1, "publish"):
+ page1.publish("en")
extension.refresh_from_db()
template = "{% load robots_index %}{% page_robots %}"
expected = ""
- context = {"request": self.get_page_request(page2.get_public_object(), AnonymousUser())}
+ context = {"request": self.get_page_request(page2, AnonymousUser())}
self._test_robots_tag(template, context, expected)
extension.noindex = True
extension.save()
- page1.publish("en")
+ if hasattr(page1, "publish"):
+ page1.publish("en")
expected = ""
self._test_robots_tag(template, context, expected)
@@ -76,46 +78,51 @@ def test_robots_page_parameter(self):
extension.noarchive = True
extension.save()
- page1.publish("en")
+ if hasattr(page1, "publish"):
+ page1.publish("en")
expected = ''
self._test_robots_tag(template, context, expected)
extension.robots_extra = "nodmoz"
extension.save()
- page1.publish("en")
+ if hasattr(page1, "publish"):
+ page1.publish("en")
expected = ''
self._test_robots_tag(template, context, expected)
def test_robots_page_no_site(self):
page1, page2, page3 = self.get_pages()
extension = PageSitemapProperties.objects.create(extended_object=page1, priority="0.2", changefreq="never")
- page1.publish("en")
+ if hasattr(page1, "publish"):
+ page1.publish("en")
extension.refresh_from_db()
template = '{% load robots_index %}{% page_robots None "abc" %}'
expected = ""
- context = {"request": self.get_page_request(page2.get_public_object(), AnonymousUser())}
+ context = {"request": self.get_page_request(page2, AnonymousUser())}
self._test_robots_tag(template, context, expected)
def test_robots_page_no_page(self):
page1, page2, page3 = self.get_pages()
extension = PageSitemapProperties.objects.create(extended_object=page1, priority="0.2", changefreq="never")
- page1.publish("en")
+ if hasattr(page1, "publish"):
+ page1.publish("en")
extension.refresh_from_db()
template = '{% load robots_index %}{% page_robots "abc" %}'
expected = ""
- context = {"request": self.get_page_request(page2.get_public_object(), AnonymousUser())}
+ context = {"request": self.get_page_request(page2, AnonymousUser())}
self._test_robots_tag(template, context, expected)
def test_robots_page_other_site(self):
site_2 = Site.objects.create(domain="http://othersite.com")
page1, page2, page3 = self.get_pages()
extension = PageSitemapProperties.objects.create(extended_object=page1, priority="0.2", changefreq="never")
- page1.publish("en")
+ if hasattr(page1, "publish"):
+ page1.publish("en")
extension.refresh_from_db()
template = "{%% load robots_index %%}{%% page_robots None %s %%}" % site_2.pk
expected = ""
- context = {"request": self.get_page_request(page2.get_public_object(), AnonymousUser())}
+ context = {"request": self.get_page_request(page2, AnonymousUser())}
self._test_robots_tag(template, context, expected)
diff --git a/tests/test_sitemap.py b/tests/test_sitemap.py
index 23208e0..facd270 100644
--- a/tests/test_sitemap.py
+++ b/tests/test_sitemap.py
@@ -1,38 +1,55 @@
from decimal import Decimal
+from unittest import skipIf
+import cms
+from cms.api import create_page, create_title
+from cms.test_utils.util.fuzzy_int import FuzzyInt
from django.core.cache import cache
from django.utils.timezone import now
from djangocms_page_sitemap.models import PageSitemapProperties
from djangocms_page_sitemap.sitemap import ExtendedSitemap
-from djangocms_page_sitemap.utils import get_cache_key
+from djangocms_page_sitemap.utils import get_cache_key, is_versioning_enabled
from .base import BaseTest
class SitemapTest(BaseTest):
def test_sitemap_base(self):
+ page1, page2, page3 = self.get_pages()
+
+ try:
+ title_language = page1.get_title_obj().language
+ except AttributeError:
+ title_language = page1.get_page_content_obj_attribute("language")
+
+ sitemap = self.client.get("/sitemap.xml")
test_string = (
- "http://example.com/it/"
- "%smonthly0.5" % now().strftime("%Y-%m-%d")
+ "http://example.com/%s/%s"
+ "monthly0.5" % (title_language, now().strftime("%Y-%m-%d"))
)
- self.get_pages()
- sitemap = self.client.get("/sitemap.xml")
self.assertContains(sitemap, test_string)
def test_sitemap_extended(self):
- test_string = (
- "http://example.com/it/"
- "%snever0.2" % now().strftime("%Y-%m-%d")
- )
page1, page2, page3 = self.get_pages()
PageSitemapProperties.objects.create(extended_object=page1, priority="0.2", changefreq="never")
- page1.publish("it")
+ if hasattr(page1, "publish"):
+ page1.publish("it")
+
+ try:
+ title_language = page1.get_title_obj().language
+ except AttributeError:
+ title_language = page1.get_page_content_obj_attribute("language")
+ test_string = (
+ "http://example.com/%s/%s"
+ "never0.2" % (title_language, now().strftime("%Y-%m-%d"))
+ )
sitemap = self.client.get("/sitemap.xml")
self.assertContains(sitemap, test_string)
def test_sitemap_exclude(self):
page1, page2, page3 = self.get_pages()
+
PageSitemapProperties.objects.create(
extended_object=page3,
priority="0.2",
@@ -40,25 +57,30 @@ def test_sitemap_exclude(self):
include_in_sitemap=False,
)
sitemap = ExtendedSitemap()
- # unpublished since change, still in the sitemap
- self.assertEqual(len(sitemap.items()), 6)
-
- page3.publish("en")
- page3.publish("fr")
- sitemap = ExtendedSitemap()
- # published, then no longer in the sitemap
- self.assertEqual(len(sitemap.items()), 4)
+ # If publish is available, page must be published for property to be recognized
+ if hasattr(page1, "publish"):
+ # unpublished since change, still in the sitemap
+ self.assertEqual(len(sitemap.items()), 6)
+ page3.publish("en")
+ page3.publish("fr")
+ sitemap = ExtendedSitemap()
+ # published, then no longer in the sitemap
+ self.assertEqual(len(sitemap.items()), 4)
+ else:
+ self.assertEqual(len(sitemap.items()), 4)
def test_sitemap_cache(self):
page1, page2, page3 = self.get_pages()
PageSitemapProperties.objects.create(extended_object=page1, priority="0.2", changefreq="never")
PageSitemapProperties.objects.create(extended_object=page3, priority="0.8", changefreq="hourly")
- page1.publish("fr")
- page1 = page1.get_public_object()
- page3.publish("fr")
- page3 = page3.get_public_object()
+ if hasattr(page1, "publish"):
+ page1.publish("fr")
+ page1 = page1.get_public_object()
+ page3.publish("fr")
+ page3 = page3.get_public_object()
sitemap = ExtendedSitemap()
self.assertEqual(len(sitemap.items()), 6)
+
for item in sitemap.items():
if item.page.pk == page1.pk:
self.assertEqual(sitemap.changefreq(item), "never")
@@ -76,3 +98,36 @@ def test_sitemap_cache(self):
ext_key = get_cache_key(page3)
page3.delete()
self.assertEqual(cache.get(ext_key), None)
+
+ @skipIf(not is_versioning_enabled(), "This test can only run when versioning is installed")
+ def test_pageurl_lastmod_with_cms4_versioning(self):
+ # Check the latest version modified date for the page is checked for lastmod()
+ # if versioning is enabled, Currenly test is skipped , as this require changes in testsuite
+ page_1 = create_page("page-one", "page.html", language="en", created_by=self.user)
+ page_content = create_title(title="page un", language="en", page=page_1, created_by=self.user)
+ if is_versioning_enabled():
+ page_content.versions.first().publish(self.user)
+ last_modified_date = "%s" % (page_content.versions.first().modified.strftime("%Y-%m-%d"))
+ expected_string = (
+ "http://example.com%s%smonthly"
+ "0.5"
+ % (page_1.get_absolute_url(language="en"), last_modified_date)
+ )
+ sitemap = self.client.get("/sitemap.xml")
+
+ self.assertContains(sitemap, expected_string)
+
+ def test_sitemap_items_query_performance(self):
+ page1, page2, page3 = self.get_pages()
+
+ PageSitemapProperties.objects.create(extended_object=page1, priority="0.2", changefreq="never")
+ PageSitemapProperties.objects.create(extended_object=page3, priority="0.8", changefreq="hourly")
+ sitemap = ExtendedSitemap()
+
+ if cms.__version__ < "4.0":
+ with self.assertNumQueries(1):
+ self.assertEqual(len(sitemap.items()), 6)
+ else:
+ max_queries = 4
+ with self.assertNumQueries(FuzzyInt(3, max_queries)):
+ self.assertEqual(len(sitemap.items()), 6)
diff --git a/tests/test_toolbar.py b/tests/test_toolbar.py
index 1270511..1ec9857 100644
--- a/tests/test_toolbar.py
+++ b/tests/test_toolbar.py
@@ -1,3 +1,8 @@
+from unittest import skipIf
+
+import cms
+from cms.api import create_page
+from cms.test_utils.testcases import CMSTestCase
from cms.toolbar.items import Menu, ModalItem
from django.contrib.auth.models import Permission, User
from django.test.utils import override_settings
@@ -7,10 +12,24 @@
from djangocms_page_sitemap.cms_toolbars import PAGE_SITEMAP_MENU_TITLE
from djangocms_page_sitemap.models import PageSitemapProperties
+from djangocms_page_sitemap.utils import is_versioning_enabled
from .base import BaseTest
+def find_toolbar_buttons(button_name, toolbar):
+ """
+ Taken from: from djangocms_versioning.test_utils.test_helpers import find_toolbar_buttons
+
+ CAVEAT: This test helper is not currently accesible due to the fact that it would then enforce
+ versioning test packages and factory boy on this test suite.
+ """
+ found = []
+ for button_list in toolbar.get_right_items():
+ found = found + [button for button in button_list.buttons if button.name == button_name]
+ return found
+
+
class ToolbarTest(BaseTest):
def test_no_page(self):
"""
@@ -144,10 +163,40 @@ def test_toolbar_with_items(self):
meta_menu = page_menu.find_items(ModalItem, name="%s ..." % force_str(PAGE_SITEMAP_MENU_TITLE))[0].item
self.assertTrue(
meta_menu.url.startswith(
- reverse(
- "admin:djangocms_page_sitemap_pagesitemapproperties_change",
- args=(page_ext.pk,),
- )
+ reverse("admin:djangocms_page_sitemap_pagesitemapproperties_change", args=(page_ext.pk,))
)
)
self.assertEqual(force_str(page_ext), force_str(_("Sitemap values for Page %s") % page1.pk))
+
+
+class VersioningToolbarTest(CMSTestCase):
+ @skipIf(cms.__version__ < "4.0", "Versioning not available if django CMS < 4")
+ def test_toolbar_buttons_are_not_duplicated(self):
+ """
+ The toolbar for djangocms-page-sitemap doesn't affect the toolbar buttons.
+
+ This test Can be ran with or without versioning and should return the same result!
+ """
+ from cms.models import PageContent
+ from cms.toolbar.utils import get_object_preview_url
+
+ user = self.get_superuser()
+ page_1 = create_page("page-one", "page.html", language="en", created_by=user)
+ page_content = PageContent._base_manager.get(page=page_1, language="en")
+
+ if is_versioning_enabled():
+ page_content.versions.first().publish(user)
+ preview_endpoint = get_object_preview_url(page_content, language="en")
+
+ with self.login_user_context(self.get_superuser()):
+ response = self.client.post(preview_endpoint)
+
+ edit_button_list = find_toolbar_buttons("Edit", response.wsgi_request.toolbar)
+ new_draft_button_list = find_toolbar_buttons("New Draft", response.wsgi_request.toolbar)
+ create_button_list = find_toolbar_buttons("Create", response.wsgi_request.toolbar)
+
+ self.assertEqual(len(create_button_list), 1)
+ if is_versioning_enabled():
+ self.assertEqual(len(new_draft_button_list), 1)
+ else:
+ self.assertEqual(len(edit_button_list), 1)
diff --git a/tests/test_utils/urls.py b/tests/test_utils/urls.py
index 01e4af4..401c1da 100644
--- a/tests/test_utils/urls.py
+++ b/tests/test_utils/urls.py
@@ -11,6 +11,11 @@
admin.autodiscover()
urlpatterns = [
+ re_path(r"^media/(?P.*)$", serve, {"document_root": settings.MEDIA_ROOT, "show_indexes": True}),
+ re_path(
+ r"^media/cms/(?P.*)$", serve, {"document_root": get_cms_setting("MEDIA_ROOT"), "show_indexes": True}
+ ),
+ path("", include(sitemap_urls)),
re_path(
r"^media/(?P.*)$",
serve,
diff --git a/tox.ini b/tox.ini
index 97ce37b..9d7592a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -8,18 +8,18 @@ envlist =
ruff
pypi-description
towncrier
- py{311,310,39}-django{42,41}-cms{311}
- py{311,310,39}-django{32}-cms{311,39}
+ py{39, 310, 311}-django{32,42}-cms{40}
[testenv]
commands = {env:COMMAND:python} cms_helper.py djangocms_page_sitemap test {posargs}
deps =
- django32: Django~=3.2.0
- django41: Django~=4.1.0
- django42: Django~=4.2.0
- cms39: https://github.com/django-cms/django-cms/archive/release/3.9.x.zip
- cms311: https://github.com/yakky/django-cms/archive/release/3.11.x.zip
- -r{toxinidir}/requirements-test.txt
+ -r{toxinidir}/tests/requirements/requirements_base.txt
+ django32: -r{toxinidir}/tests/requirements/dj32_cms40.txt
+ django42: -r{toxinidir}/tests/requirements/dj42_cms40.txt
+basepython=
+ py38: python3.8
+ py39: python3.9
+ py310: python3.10
passenv =
COMMAND
PYTEST_*