forked from ungleich-public/dynamicweb
1126 lines
48 KiB
Python
1126 lines
48 KiB
Python
import datetime
|
|
import functools
|
|
import os.path
|
|
from unittest import skipIf
|
|
|
|
from django.conf import settings
|
|
from django.contrib.auth import get_user_model
|
|
from django.contrib.sites.models import Site
|
|
from django.core.cache import cache
|
|
from django.core.exceptions import ValidationError
|
|
from django.db import models
|
|
from django.db.utils import IntegrityError
|
|
from django.http import HttpResponse, HttpResponseNotFound
|
|
from django.urls import reverse
|
|
from django.utils.timezone import now as tz_now
|
|
from django.utils.translation import override as force_language
|
|
|
|
from cms import constants
|
|
from cms.api import add_plugin, create_page, create_page_content
|
|
from cms.cache.page import get_page_cache
|
|
from cms.forms.validators import validate_url_uniqueness
|
|
from cms.models import Page, PageContent
|
|
from cms.models.placeholdermodel import Placeholder
|
|
from cms.models.pluginmodel import CMSPlugin
|
|
from cms.sitemaps import CMSSitemap
|
|
from cms.test_utils.testcases import CMSTestCase, TransactionCMSTestCase
|
|
from cms.utils.conf import get_cms_setting
|
|
from cms.utils.page import (
|
|
get_available_slug,
|
|
get_page_from_request,
|
|
)
|
|
|
|
|
|
def _get_current_site():
|
|
return Site.objects.get_current()
|
|
|
|
|
|
class PageMigrationTestCase(CMSTestCase):
|
|
def test_content_type(self):
|
|
"""
|
|
Test correct content type is set for Page object
|
|
"""
|
|
from django.contrib.contenttypes.models import ContentType
|
|
|
|
self.assertEqual(ContentType.objects.filter(model="page", app_label="cms").count(), 1)
|
|
|
|
|
|
def has_no_custom_user():
|
|
return get_user_model().USERNAME_FIELD != "email"
|
|
|
|
|
|
class PagesTestCase(TransactionCMSTestCase):
|
|
def tearDown(self):
|
|
cache.clear()
|
|
|
|
def test_absolute_url(self):
|
|
"""
|
|
Test correct content type is set for Page object
|
|
"""
|
|
page = self.create_homepage("page", "nav_playground.html", "en")
|
|
create_page_content("fr", "french home", page)
|
|
page_2 = create_page("inner", "nav_playground.html", "en", parent=page)
|
|
create_page_content("fr", "french inner", page_2)
|
|
|
|
self.assertEqual(page_2.get_absolute_url(), "/en/inner/")
|
|
self.assertEqual(page_2.get_absolute_url(language="en"), "/en/inner/")
|
|
self.assertEqual(page_2.get_absolute_url(language="fr"), "/fr/french-inner/")
|
|
|
|
with force_language("fr"):
|
|
self.assertEqual(page_2.get_absolute_url(), "/fr/french-inner/")
|
|
self.assertEqual(page_2.get_absolute_url(language="en"), "/en/inner/")
|
|
self.assertEqual(page_2.get_absolute_url(language="fr"), "/fr/french-inner/")
|
|
|
|
def test_absolute_url_page_content(self):
|
|
page = self.create_homepage("page", "nav_playground.html", "en")
|
|
create_page_content("fr", "french home", page)
|
|
page_2 = create_page("inner", "nav_playground.html", "en", parent=page)
|
|
content_2 = create_page_content("fr", "french inner", page_2)
|
|
|
|
# content_2 is French
|
|
self.assertEqual(content_2.get_absolute_url(), "/fr/french-inner/")
|
|
# if language specified, get the language version's url
|
|
self.assertEqual(content_2.get_absolute_url(language="en"), "/en/inner/")
|
|
# for completeness: specify own language
|
|
self.assertEqual(content_2.get_absolute_url(language="fr"), "/fr/french-inner/")
|
|
|
|
# The above result does not change if language is changed
|
|
with force_language("en"):
|
|
self.assertEqual(content_2.get_absolute_url(), "/fr/french-inner/")
|
|
self.assertEqual(content_2.get_absolute_url(language="en"), "/en/inner/")
|
|
self.assertEqual(content_2.get_absolute_url(language="fr"), "/fr/french-inner/")
|
|
|
|
def test_get_root_page(self):
|
|
_create = functools.partial(
|
|
create_page,
|
|
template="nav_playground.html",
|
|
language="en",
|
|
)
|
|
page_a = _create("page_a")
|
|
page_a_a = _create("page_a_a_a", parent=page_a)
|
|
page_a_a_a = _create("page_a_a_a", parent=page_a_a)
|
|
page_tree_with_root = [
|
|
(page_a, page_a),
|
|
(page_a_a, page_a),
|
|
(page_a_a_a, page_a),
|
|
]
|
|
|
|
for page, root in page_tree_with_root:
|
|
self.assertEqual(page.get_root(), root)
|
|
|
|
def test_treebeard_delete(self):
|
|
"""
|
|
This is a test for #4102
|
|
|
|
When deleting a page, parent must be updated too, to reflect the new tree status.
|
|
This is handled by MP_NodeQuerySet (which was not used before the fix)
|
|
|
|
"""
|
|
page1 = create_page("home", "nav_playground.html", "en")
|
|
page2 = create_page("page2", "nav_playground.html", "en", parent=page1)
|
|
page3 = create_page("page3", "nav_playground.html", "en", parent=page2)
|
|
|
|
self.assertEqual(page1.depth, 1)
|
|
self.assertEqual(page1.numchild, 1)
|
|
self.assertFalse(page1.is_leaf())
|
|
|
|
self.assertEqual(page2.depth, 2)
|
|
self.assertEqual(page2.numchild, 1)
|
|
self.assertFalse(page2.is_leaf())
|
|
|
|
self.assertEqual(page3.depth, 3)
|
|
self.assertEqual(page3.numchild, 0)
|
|
self.assertTrue(page3.is_leaf())
|
|
|
|
page3.delete()
|
|
page1.refresh_from_db()
|
|
page2.refresh_from_db()
|
|
|
|
self.assertEqual(page2.depth, 2)
|
|
self.assertEqual(page2.numchild, 0)
|
|
self.assertTrue(page2.is_leaf())
|
|
|
|
page3 = create_page("page3", "nav_playground.html", "en", parent=page2, reverse_id="page3")
|
|
|
|
self.assertEqual(page2.depth, 2)
|
|
self.assertEqual(page2.numchild, 1)
|
|
self.assertFalse(page2.is_leaf())
|
|
|
|
self.assertEqual(page3.depth, 3)
|
|
self.assertEqual(page3.numchild, 0)
|
|
self.assertTrue(page3.is_leaf())
|
|
|
|
self.assertEqual(page1.depth, 1)
|
|
self.assertEqual(page1.numchild, 1)
|
|
self.assertFalse(page1.is_leaf())
|
|
|
|
self.assertEqual(page2.depth, 2)
|
|
self.assertEqual(page2.numchild, 1)
|
|
self.assertFalse(page2.is_leaf())
|
|
|
|
self.assertEqual(page3.depth, 3)
|
|
self.assertEqual(page3.numchild, 0)
|
|
self.assertTrue(page3.is_leaf())
|
|
|
|
def test_create_page_api(self):
|
|
page_data = {
|
|
"title": "root",
|
|
"slug": "root",
|
|
"language": settings.LANGUAGES[0][0],
|
|
"template": "nav_playground.html",
|
|
}
|
|
page = self.create_homepage(**page_data)
|
|
self.assertEqual(Page.objects.count(), 1)
|
|
self.assertTrue(page.is_home)
|
|
self.assertEqual(list(page.get_urls().values_list("path", flat=True)), [""])
|
|
|
|
@skipIf(has_no_custom_user(), "No custom user")
|
|
def test_create_page_api_with_long_username(self):
|
|
page_data = {
|
|
"title": "root",
|
|
"slug": "root",
|
|
"language": settings.LANGUAGES[0][0],
|
|
"template": "nav_playground.html",
|
|
"created_by": self._create_user(
|
|
"V" * constants.PAGE_USERNAME_MAX_LENGTH + "ERY-LONG-USERNAME",
|
|
is_staff=True,
|
|
is_superuser=True,
|
|
),
|
|
}
|
|
page = create_page(**page_data)
|
|
self.assertEqual(Page.objects.count(), 1)
|
|
|
|
self.assertLessEqual(len(page.created_by), constants.PAGE_USERNAME_MAX_LENGTH)
|
|
self.assertRegex(page.created_by, r"V+\.{3} \(id=\d+\)")
|
|
|
|
self.assertLessEqual(len(page.changed_by), constants.PAGE_USERNAME_MAX_LENGTH)
|
|
self.assertRegex(page.changed_by, r"V+\.{3} \(id=\d+\)")
|
|
|
|
self.assertEqual(list(page.get_urls().values_list("path", flat=True)), ["root"])
|
|
|
|
def test_get_available_slug_recursion(self):
|
|
"""Checks cms.utils.page.get_available_slug for infinite recursion"""
|
|
site = _get_current_site()
|
|
for x in range(0, 12):
|
|
create_page("test-page", "nav_playground.html", "en")
|
|
new_slug = get_available_slug(site, "test-page", "en")
|
|
self.assertEqual(new_slug, "test-page-copy-13") # get_available_slug's suffix default is 'copy'
|
|
|
|
def test_path_collisions_api_1(self):
|
|
"""Checks for slug collisions on sibling pages - uses API to create pages"""
|
|
page1 = create_page("test page 1", "nav_playground.html", "en")
|
|
create_page("test page 1_1", "nav_playground.html", "en", parent=page1, slug="foo")
|
|
|
|
# Try to create a sibling page with the same slug - should fail with IntegrityError
|
|
with self.assertRaises(IntegrityError):
|
|
create_page("test page 1_1", "nav_playground.html", "en", parent=page1, slug="foo")
|
|
|
|
def test_path_collisions_api_2(self):
|
|
"""Checks for slug collisions on root (not home) page and a home page child - uses API to create pages"""
|
|
page1 = self.create_homepage("test page 1", "nav_playground.html", "en")
|
|
create_page("test page 1_1", "nav_playground.html", "en", parent=page1, slug="foo")
|
|
|
|
# Try to create a root page with the same slug - should fail with IntegrityError
|
|
with self.assertRaises(IntegrityError):
|
|
create_page("test page 1_1", "nav_playground.html", "en", slug="foo")
|
|
|
|
def test_path_collisions_api_3(self):
|
|
"""Checks for slug collisions on children of a non root page - uses API to create pages"""
|
|
site = _get_current_site()
|
|
page1 = create_page("test page 1", "nav_playground.html", "en")
|
|
page1_1 = create_page("test page 1_1", "nav_playground.html", "en", parent=page1, slug="foo")
|
|
create_page("test page 1_1_1", "nav_playground.html", "en", parent=page1_1, slug="bar")
|
|
page1_2 = create_page("test page 1_2", "nav_playground.html", "en", parent=page1, slug="bar")
|
|
# Direct children of home has different slug so it's ok.
|
|
self.assertTrue(
|
|
validate_url_uniqueness(
|
|
site,
|
|
path=page1_1.get_path("en"),
|
|
language="en",
|
|
exclude_page=page1_1,
|
|
)
|
|
)
|
|
self.assertTrue(
|
|
validate_url_uniqueness(
|
|
site,
|
|
path=page1_2.get_path("en"),
|
|
language="en",
|
|
exclude_page=page1_2,
|
|
)
|
|
)
|
|
with self.assertRaises(IntegrityError):
|
|
create_page("test page 1_1_1", "nav_playground.html", "en", parent=page1_1, slug="bar")
|
|
|
|
def test_parent_child_same_slug(self):
|
|
"""Test that a parent page and its child can have the same slug."""
|
|
parent = create_page("parent", "nav_playground.html", "en", slug="foo")
|
|
child = create_page("child", "nav_playground.html", "en", parent=parent, slug="foo")
|
|
|
|
# Verify the paths are correctly formed and different
|
|
self.assertEqual(parent.get_path("en"), "foo")
|
|
self.assertEqual(child.get_path("en"), "foo/foo")
|
|
self.assertEqual(parent.get_absolute_url("en"), "/en/foo/")
|
|
self.assertEqual(child.get_absolute_url("en"), "/en/foo/foo/")
|
|
|
|
# Verify we can access both pages
|
|
response = self.client.get(parent.get_absolute_url("en"))
|
|
self.assertEqual(response.status_code, 200)
|
|
response = self.client.get(child.get_absolute_url("en"))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def test_validate_url_uniqueness_child_page_sibling_conflict(self):
|
|
"""A child page's natural path is checked for conflicts with its siblings (#8902)"""
|
|
site = _get_current_site()
|
|
parent = create_page("Parent", "nav_playground.html", "en", slug="parent")
|
|
create_page("A", "nav_playground.html", "en", parent=parent, slug="a")
|
|
page_b = create_page("B", "nav_playground.html", "en", parent=parent, slug="b")
|
|
|
|
# B may keep its own path
|
|
self.assertTrue(validate_url_uniqueness(site, path="parent/b", language="en", exclude_page=page_b))
|
|
# but not take A's path
|
|
with self.assertRaises(ValidationError):
|
|
validate_url_uniqueness(site, path="parent/a", language="en", exclude_page=page_b)
|
|
|
|
def test_validate_url_uniqueness_parent_child_same_slug(self):
|
|
"""A child with the same slug as its parent has a different path and is valid"""
|
|
site = _get_current_site()
|
|
parent = create_page("parent", "nav_playground.html", "en", slug="foo")
|
|
child = create_page("child", "nav_playground.html", "en", parent=parent, slug="foo")
|
|
|
|
self.assertTrue(validate_url_uniqueness(site, path="foo/foo", language="en", exclude_page=child))
|
|
self.assertTrue(validate_url_uniqueness(site, path="foo", language="en", exclude_page=parent))
|
|
|
|
def test_validate_url_uniqueness_escapes_html_in_error_message(self):
|
|
"""
|
|
validate_url_uniqueness raises a ValidationError whose message is
|
|
wrapped in mark_safe so it can render an <a> link to the conflicting
|
|
page in the admin. Any user-controlled fragments interpolated into
|
|
that message MUST be HTML-escaped, otherwise a page title containing
|
|
markup like ``<script>...</script>`` would render unescaped wherever
|
|
Django renders the validation error (admin form errors, toolbar
|
|
notifications, ...).
|
|
"""
|
|
from django.utils.safestring import SafeString
|
|
|
|
site = _get_current_site()
|
|
evil = "<script>alert('xss')</script>"
|
|
|
|
# Page A: the existing page that owns the conflicting slug. Its title
|
|
# ends up inside the <a>...</a> link in the rendered error message.
|
|
conflict_page = create_page(f"conflict {evil}", "nav_playground.html", "en", slug="foo")
|
|
# Page B: the page being validated. Its title is interpolated into
|
|
# the "current page" portion of the message via the `instance` kwarg.
|
|
current_page = create_page(f"current {evil}", "nav_playground.html", "en", slug="bar")
|
|
|
|
with self.assertRaises(ValidationError) as ctx:
|
|
validate_url_uniqueness(
|
|
site,
|
|
path=conflict_page.get_path("en"),
|
|
language="en",
|
|
exclude_page=current_page,
|
|
)
|
|
|
|
# ValidationError messages are a list; the validator only raises one.
|
|
rendered = ctx.exception.messages[0]
|
|
self.assertIsInstance(rendered, SafeString)
|
|
|
|
# The raw <script> tag must NOT survive into the safe message — neither
|
|
# from the conflict page's title (escaped explicitly via django.utils.html.escape)
|
|
# nor from the current page's title (interpolated via `instance`).
|
|
self.assertNotIn("<script>", rendered)
|
|
self.assertNotIn("</script>", rendered)
|
|
# Both titles should appear in their HTML-escaped form.
|
|
self.assertIn("<script>", rendered)
|
|
self.assertIn("</script>", rendered)
|
|
# The legitimate <a> tag the validator builds for the admin link is
|
|
# still preserved (it's the only HTML the message is allowed to emit).
|
|
self.assertIn('<a href="', rendered)
|
|
|
|
def test_details_view(self):
|
|
"""
|
|
Test the details view
|
|
"""
|
|
superuser = self.get_superuser()
|
|
self.assertEqual(Page.objects.all().count(), 0)
|
|
with self.login_user_context(superuser):
|
|
page = self.create_homepage("test page 1", "nav_playground.html", "en")
|
|
response = self.client.get(self.get_pages_root())
|
|
self.assertEqual(response.status_code, 200)
|
|
page2 = create_page("test page 2", "nav_playground.html", "en", parent=page)
|
|
homepage = Page.objects.get_home()
|
|
self.assertEqual(homepage.get_slug("en"), "test-page-1")
|
|
|
|
self.assertEqual(page2.get_absolute_url(), "/en/test-page-2/")
|
|
response = self.client.get(page2.get_absolute_url())
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
def test_move_page_regression_left_to_right_5752(self):
|
|
# ref: https://github.com/divio/django-cms/issues/5752
|
|
# Tests tree integrity when moving sibling pages from left
|
|
# to right under the same parent.
|
|
home = create_page("Home", "nav_playground.html", "en")
|
|
alpha = create_page(
|
|
"Alpha",
|
|
"nav_playground.html",
|
|
"en",
|
|
parent=home,
|
|
)
|
|
beta = create_page(
|
|
"Beta",
|
|
"nav_playground.html",
|
|
"en",
|
|
parent=home,
|
|
)
|
|
beta.move_page(alpha, position="left")
|
|
|
|
# Draft
|
|
self.assertEqual(home.path, "0001")
|
|
self.assertEqual(beta.path, "00010001")
|
|
self.assertEqual(alpha.path, "00010002")
|
|
|
|
def test_move_page_regression_right_to_left_5752(self):
|
|
# ref: https://github.com/divio/django-cms/issues/5752
|
|
# Tests tree integrity when moving sibling pages from right
|
|
# to left under the same parent.
|
|
home = create_page("Home", "nav_playground.html", "en")
|
|
alpha = create_page(
|
|
"Alpha",
|
|
"nav_playground.html",
|
|
"en",
|
|
parent=home,
|
|
)
|
|
beta = create_page(
|
|
"Beta",
|
|
"nav_playground.html",
|
|
"en",
|
|
parent=home,
|
|
)
|
|
beta.move_page(alpha, position="left")
|
|
|
|
alpha.refresh_from_db()
|
|
beta.refresh_from_db()
|
|
|
|
# Draft
|
|
self.assertEqual(home.path, "0001")
|
|
self.assertEqual(beta.path, "00010001")
|
|
self.assertEqual(alpha.path, "00010002")
|
|
|
|
def test_move_page_regression_5640(self):
|
|
# ref: https://github.com/divio/django-cms/issues/5640
|
|
alpha = create_page("Alpha", "nav_playground.html", "en")
|
|
beta = create_page("Beta", "nav_playground.html", "en")
|
|
alpha.move_page(beta, position="right")
|
|
self.assertEqual(beta.path, "0002")
|
|
self.assertEqual(alpha.path, "0003")
|
|
|
|
def test_move_page_regression_nested_5640(self):
|
|
# ref: https://github.com/divio/django-cms/issues/5640
|
|
alpha = create_page("Alpha", "nav_playground.html", "en")
|
|
beta = create_page("Beta", "nav_playground.html", "en")
|
|
gamma = create_page("Gamma", "nav_playground.html", "en")
|
|
delta = create_page("Delta", "nav_playground.html", "en")
|
|
theta = create_page("Theta", "nav_playground.html", "en")
|
|
|
|
beta.move_page(alpha, position="last-child")
|
|
gamma.move_page(beta, position="last-child")
|
|
delta.move_page(gamma, position="last-child")
|
|
theta.move_page(delta, position="last-child")
|
|
|
|
tree = [
|
|
(alpha, "0001"),
|
|
(beta, "00010001"),
|
|
(gamma, "000100010001"),
|
|
(delta, "0001000100010001"),
|
|
(theta, "00010001000100010001"),
|
|
]
|
|
|
|
for page, path in tree:
|
|
self.assertEqual(page.path, path)
|
|
|
|
def test_move_page_inherit(self):
|
|
parent = create_page("Parent", "col_three.html", "en")
|
|
child = create_page("Child", constants.TEMPLATE_INHERITANCE_MAGIC, "en", parent=parent)
|
|
self.assertEqual(child.get_template(), parent.get_template())
|
|
child.move_page(parent, "left")
|
|
child = Page.objects.get(pk=child.pk)
|
|
self.assertEqual(child.get_template(), parent.get_template())
|
|
|
|
def test_add_placeholder(self):
|
|
# create page
|
|
page = create_page("Add Placeholder", "nav_playground.html", "en", position="last-child", in_navigation=True)
|
|
page.update_translations(template="add_placeholder.html")
|
|
url = page.get_absolute_url()
|
|
response = self.client.get(url)
|
|
self.assertEqual(200, response.status_code)
|
|
path = os.path.join(settings.TEMPLATES[0]["DIRS"][0], "add_placeholder.html")
|
|
with open(path) as fobj:
|
|
old = fobj.read()
|
|
try:
|
|
new = old.replace("<!-- SECOND_PLACEHOLDER -->", "{% placeholder second_placeholder %}")
|
|
with open(path, "w") as fobj:
|
|
fobj.write(new)
|
|
response = self.client.get(url)
|
|
self.assertEqual(200, response.status_code)
|
|
finally:
|
|
with open(path, "w") as fobj:
|
|
fobj.write(old)
|
|
|
|
def test_sitemap_login_required_pages(self):
|
|
"""
|
|
Test that CMSSitemap object contains only published,public (login_required=False) pages
|
|
"""
|
|
create_page("page", "nav_playground.html", "en", login_required=True, in_navigation=True)
|
|
self.assertEqual(len(CMSSitemap().items()), 0)
|
|
|
|
def test_sitemap_includes_last_modification_date(self):
|
|
one_day_ago = tz_now() - datetime.timedelta(days=1)
|
|
page = create_page("page", "nav_playground.html", "en")
|
|
page.creation_date = one_day_ago
|
|
page.save()
|
|
sitemap = CMSSitemap()
|
|
self.assertEqual(len(sitemap.items()), 1)
|
|
actual_last_modification_time = sitemap.lastmod(sitemap.items()[0])
|
|
self.assertTrue(actual_last_modification_time > one_day_ago)
|
|
|
|
def test_sitemap_uses_publication_date_when_later_than_modification(self):
|
|
now = tz_now()
|
|
now -= datetime.timedelta(microseconds=now.microsecond)
|
|
one_day_ago = now - datetime.timedelta(days=1)
|
|
page = create_page("page", "nav_playground.html", "en")
|
|
page.get_content_obj("en")
|
|
page.creation_date = one_day_ago
|
|
page.changed_date = one_day_ago
|
|
page.save()
|
|
sitemap = CMSSitemap()
|
|
actual_last_modification_time = sitemap.lastmod(sitemap.items().first())
|
|
self.assertEqual(actual_last_modification_time.date(), now.date())
|
|
|
|
def test_templates(self):
|
|
"""
|
|
Test the inheritance magic for templates
|
|
"""
|
|
parent = create_page("parent", "nav_playground.html", "en")
|
|
child = create_page("child", "nav_playground.html", "en", parent=parent)
|
|
grand_child = create_page("grand child", "nav_playground.html", "en", parent=child)
|
|
child2 = create_page("child2", "col_two.html", "en", parent=parent)
|
|
grand_child2 = create_page("grand child2", "nav_playground.html", "en", parent=child2)
|
|
child_content = child.get_content_obj("en")
|
|
child2_content = child2.get_content_obj("en")
|
|
child_content.template = constants.TEMPLATE_INHERITANCE_MAGIC
|
|
grand_child_content = grand_child.get_content_obj("en")
|
|
grand_child_content.template = constants.TEMPLATE_INHERITANCE_MAGIC
|
|
child_content.save()
|
|
grand_child_content.save()
|
|
grand_child2_content = grand_child2.get_content_obj("en")
|
|
grand_child2_content.template = constants.TEMPLATE_INHERITANCE_MAGIC
|
|
grand_child2_content.save()
|
|
|
|
self.assertFalse(hasattr(grand_child_content, "_template_cache"))
|
|
with self.assertNumQueries(0):
|
|
self.assertEqual(child_content.template, constants.TEMPLATE_INHERITANCE_MAGIC)
|
|
with self.assertNumQueries(2):
|
|
self.assertEqual(parent.get_template_name(), grand_child.get_template_name())
|
|
|
|
# test template cache
|
|
with self.assertNumQueries(0):
|
|
grand_child.get_template()
|
|
|
|
self.assertFalse(hasattr(grand_child2_content, "_template_cache"))
|
|
with self.assertNumQueries(1):
|
|
self.assertEqual(child2_content.template, "col_two.html")
|
|
self.assertEqual(child2.get_template_name(), grand_child2.get_template_name())
|
|
|
|
# test template cache
|
|
with self.assertNumQueries(0):
|
|
grand_child2.get_template()
|
|
|
|
parent_content = parent.get_content_obj("en")
|
|
parent_content.template = constants.TEMPLATE_INHERITANCE_MAGIC
|
|
parent_content.save()
|
|
self.assertEqual(parent_content.template, constants.TEMPLATE_INHERITANCE_MAGIC)
|
|
self.assertEqual(parent.get_template(), get_cms_setting("TEMPLATES")[0][0])
|
|
self.assertEqual(parent.get_template_name(), get_cms_setting("TEMPLATES")[0][1])
|
|
|
|
def test_delete_with_plugins(self):
|
|
"""
|
|
Check that plugins and placeholders get correctly deleted when we delete
|
|
a page!
|
|
"""
|
|
Text = self.get_plugin_model("TextPlugin")
|
|
home = create_page("home", "nav_playground.html", "en")
|
|
page = create_page("page", "nav_playground.html", "en")
|
|
placeholder = page.get_placeholders("en")[0]
|
|
plugin_base = CMSPlugin.objects.create(
|
|
plugin_type="TextPlugin", placeholder=placeholder, position=1, language=settings.LANGUAGES[0][0]
|
|
)
|
|
|
|
plugin = Text(body="")
|
|
plugin_base.set_base_attr(plugin)
|
|
plugin.save()
|
|
self.assertEqual(CMSPlugin.objects.count(), 1)
|
|
self.assertEqual(Text.objects.count(), 1)
|
|
self.assertTrue(Placeholder.objects.count() > 2)
|
|
|
|
superuser = self.get_superuser()
|
|
home_pl_count = home.get_placeholders("en").count()
|
|
page_pl_count = page.get_placeholders("en").count()
|
|
expected_pl_count = Placeholder.objects.count() - (home_pl_count + page_pl_count)
|
|
|
|
with self.login_user_context(superuser):
|
|
# Delete page
|
|
self.client.post(self.get_admin_url(Page, "delete", page.pk), {"post": "yes"})
|
|
|
|
with self.login_user_context(superuser):
|
|
# Delete home page
|
|
self.client.post(self.get_admin_url(Page, "delete", home.pk), {"post": "yes"})
|
|
self.assertEqual(CMSPlugin.objects.count(), 0)
|
|
self.assertEqual(Text.objects.count(), 0)
|
|
self.assertEqual(Placeholder.objects.exclude(slot="clipboard").count(), expected_pl_count)
|
|
self.assertEqual(Page.objects.count(), 0)
|
|
|
|
def test_get_page_from_request_nopage(self):
|
|
request = self.get_request("/")
|
|
page = get_page_from_request(request)
|
|
self.assertEqual(page, None)
|
|
|
|
def test_get_page_from_request_with_page_404(self):
|
|
create_page("page", "nav_playground.html", "en")
|
|
request = self.get_request("/does-not-exist/")
|
|
found_page = get_page_from_request(request)
|
|
self.assertEqual(found_page, None)
|
|
|
|
def test_get_page_without_final_slash(self):
|
|
root = create_page("root", "nav_playground.html", "en", slug="root")
|
|
create_page("page", "nav_playground.html", "en", slug="page", parent=root)
|
|
request = self.get_request("/en/root/page")
|
|
found_page = get_page_from_request(request)
|
|
self.assertIsNotNone(found_page)
|
|
|
|
def test_page_urls(self):
|
|
page1 = self.create_homepage("test page 1", "nav_playground.html", "en")
|
|
page2 = create_page("test page 2", "nav_playground.html", "en", parent=page1)
|
|
page3 = create_page("test page 3", "nav_playground.html", "en", parent=page2)
|
|
page4 = create_page("test page 4", "nav_playground.html", "en")
|
|
page5 = create_page("test page 5", "nav_playground.html", "en", parent=page4)
|
|
|
|
page1.refresh_from_db()
|
|
page2.refresh_from_db()
|
|
page3.refresh_from_db()
|
|
page4.refresh_from_db()
|
|
page5.refresh_from_db()
|
|
self.assertEqual(page3.parent_id, page2.pk)
|
|
self.assertEqual(page2.parent_id, page1.pk)
|
|
self.assertEqual(page5.parent_id, page4.pk)
|
|
|
|
self.assertEqual(page1.get_absolute_url(), self.get_pages_root() + "")
|
|
self.assertEqual(page2.get_absolute_url(), self.get_pages_root() + "test-page-2/")
|
|
self.assertEqual(page3.get_absolute_url(), self.get_pages_root() + "test-page-2/test-page-3/")
|
|
self.assertEqual(page4.get_absolute_url(), self.get_pages_root() + "test-page-4/")
|
|
self.assertEqual(page5.get_absolute_url(), self.get_pages_root() + "test-page-4/test-page-5/")
|
|
page3 = self.move_page(page3, page1)
|
|
self.assertEqual(page3.get_absolute_url(), self.get_pages_root() + "test-page-3/")
|
|
page3.refresh_from_db()
|
|
page2.refresh_from_db()
|
|
page5.refresh_from_db()
|
|
page5 = self.move_page(page5, page2)
|
|
self.assertEqual(page5.get_absolute_url(), self.get_pages_root() + "test-page-2/test-page-5/")
|
|
page3.refresh_from_db()
|
|
page4.refresh_from_db()
|
|
page3 = self.move_page(page3, page4)
|
|
self.assertEqual(page3.get_absolute_url(), self.get_pages_root() + "test-page-4/test-page-3/")
|
|
|
|
def test_page_and_title_repr(self):
|
|
non_saved_page = Page()
|
|
self.assertIsNone(non_saved_page.pk)
|
|
self.assertIn("id=None", repr(non_saved_page))
|
|
|
|
saved_page = create_page("test saved page", "nav_playground.html", "en")
|
|
self.assertIsNotNone(saved_page.pk)
|
|
self.assertIn(f"id={saved_page.pk}", repr(saved_page))
|
|
|
|
non_saved_title = PageContent()
|
|
self.assertIsNone(non_saved_title.pk)
|
|
self.assertIn("id=None", repr(non_saved_title))
|
|
|
|
saved_content = saved_page.get_content_obj()
|
|
self.assertIsNotNone(saved_content.pk)
|
|
self.assertIn(f"id={saved_content.pk}", repr(saved_content))
|
|
|
|
def test_page_overwrite_urls(self):
|
|
page1 = self.create_homepage("test page 1", "nav_playground.html", "en")
|
|
|
|
page2 = create_page("test page 2", "nav_playground.html", "en", parent=page1)
|
|
|
|
page3 = create_page(
|
|
"test page 3", "nav_playground.html", "en", parent=page2, overwrite_url="i-want-another-url"
|
|
)
|
|
superuser = self.get_superuser()
|
|
|
|
self.assertEqual(page2.get_absolute_url(), self.get_pages_root() + "test-page-2/")
|
|
self.assertEqual(page3.get_absolute_url(), self.get_pages_root() + "i-want-another-url/")
|
|
|
|
endpoint = self.get_page_change_uri("en", page2)
|
|
|
|
with self.login_user_context(superuser):
|
|
data = {"title": "test page 2", "slug": "page-test-2", "template": "nav_playground.html"}
|
|
response = self.client.post(endpoint, data)
|
|
self.assertRedirects(response, self.get_pages_admin_list_uri("en"))
|
|
|
|
page2 = Page.objects.get(pk=page2.pk)
|
|
page3 = Page.objects.get(pk=page3.pk)
|
|
|
|
self.assertEqual(page2.get_absolute_url(), self.get_pages_root() + "page-test-2/")
|
|
self.assertEqual(page3.get_absolute_url(), self.get_pages_root() + "i-want-another-url/")
|
|
|
|
# tests a bug found in 2.2 where saving an ancestor page
|
|
# wiped out the overwrite_url for child pages
|
|
page2.save()
|
|
self.assertEqual(page3.get_absolute_url(), self.get_pages_root() + "i-want-another-url/")
|
|
|
|
def test_slug_url_overwrite_clash(self):
|
|
"""Tests if a URL-Override clashes with a normal page url"""
|
|
site = _get_current_site()
|
|
with self.settings(CMS_PERMISSION=False):
|
|
create_page("home", "nav_playground.html", "en")
|
|
bar = create_page("bar", "nav_playground.html", "en")
|
|
foo = create_page("foo", "nav_playground.html", "en")
|
|
# Tests to assure is_valid_url is ok on plain pages
|
|
self.assertTrue(
|
|
validate_url_uniqueness(
|
|
site,
|
|
path=bar.get_path("en"),
|
|
language="en",
|
|
exclude_page=bar,
|
|
)
|
|
)
|
|
self.assertTrue(
|
|
validate_url_uniqueness(
|
|
site,
|
|
path=foo.get_path("en"),
|
|
language="en",
|
|
exclude_page=foo,
|
|
)
|
|
)
|
|
|
|
with self.assertRaises(IntegrityError):
|
|
foo.update_urls("en", managed=False, path="bar")
|
|
|
|
def test_valid_url_multisite(self):
|
|
site1 = Site.objects.get_current()
|
|
site3 = Site.objects.create(domain="sample3.com", name="sample3.com")
|
|
home = create_page("home", "nav_playground.html", "de", site=site1)
|
|
bar = create_page("bar", "nav_playground.html", "de", slug="bar", parent=home, site=site1)
|
|
home_s3 = create_page("home", "nav_playground.html", "de", site=site3)
|
|
bar_s3 = create_page("bar", "nav_playground.html", "de", slug="bar", parent=home_s3, site=site3)
|
|
|
|
self.assertTrue(
|
|
validate_url_uniqueness(
|
|
site1,
|
|
path=bar.get_path("de"),
|
|
language="de",
|
|
exclude_page=bar,
|
|
)
|
|
)
|
|
|
|
self.assertTrue(
|
|
validate_url_uniqueness(
|
|
site3,
|
|
path=bar_s3.get_path("de"),
|
|
language="de",
|
|
exclude_page=bar_s3,
|
|
)
|
|
)
|
|
|
|
def test_home_slug_not_accessible(self):
|
|
with self.settings(CMS_PERMISSION=False):
|
|
page = self.create_homepage("page", "nav_playground.html", "en")
|
|
self.assertEqual(page.get_absolute_url("en"), "/en/")
|
|
resp = self.client.get("/en/")
|
|
self.assertEqual(resp.status_code, HttpResponse.status_code)
|
|
resp = self.client.get("/en/page/")
|
|
self.assertEqual(resp.status_code, HttpResponseNotFound.status_code)
|
|
|
|
def test_plugin_loading_queries(self):
|
|
with self.settings(
|
|
CMS_TEMPLATES=(("placeholder_tests/base.html", "tpl"),),
|
|
):
|
|
page = create_page("home", "placeholder_tests/base.html", "en", slug="home")
|
|
page.page_content_cache["en"] = page.pagecontent_set.get(language="en")
|
|
placeholders = list(page.get_placeholders("en"))
|
|
for i, placeholder in enumerate(placeholders):
|
|
for j in range(5):
|
|
add_plugin(placeholder, "TextPlugin", "en", body="text-%d-%d" % (i, j))
|
|
add_plugin(placeholder, "LinkPlugin", "en", name="link-%d-%d" % (i, j))
|
|
|
|
# trigger the apphook query so that it doesn't get in our way
|
|
reverse("pages-root")
|
|
# trigger the get_languages query so it doesn't get in our way
|
|
context = self.get_context(page=page)
|
|
context["request"].current_page.get_languages()
|
|
|
|
renderer = self.get_content_renderer(context["request"])
|
|
|
|
with self.assertNumQueries(4):
|
|
for i, placeholder in enumerate(placeholders):
|
|
content = renderer.render_page_placeholder(
|
|
placeholder.slot,
|
|
context,
|
|
inherit=False,
|
|
)
|
|
for j in range(5):
|
|
self.assertIn("text-%d-%d" % (i, j), content)
|
|
self.assertIn("link-%d-%d" % (i, j), content)
|
|
|
|
def test_xframe_options_allow(self):
|
|
"""Test that no X-Frame-Options is set when page's xframe_options is set to allow"""
|
|
page = create_page(
|
|
title="home",
|
|
template="nav_playground.html",
|
|
language="en",
|
|
slug="home",
|
|
xframe_options=constants.X_FRAME_OPTIONS_ALLOW,
|
|
)
|
|
|
|
resp = self.client.get(page.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), None)
|
|
|
|
def test_xframe_options_sameorigin(self):
|
|
"""Test that X-Frame-Options is 'SAMEORIGIN' when xframe_options is set to origin"""
|
|
page = create_page(
|
|
title="home",
|
|
template="nav_playground.html",
|
|
language="en",
|
|
slug="home",
|
|
xframe_options=constants.X_FRAME_OPTIONS_SAMEORIGIN,
|
|
)
|
|
|
|
resp = self.client.get(page.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), "SAMEORIGIN")
|
|
|
|
def test_xframe_options_deny(self):
|
|
"""Test that X-Frame-Options is 'DENY' when xframe_options is set to deny"""
|
|
page = create_page(
|
|
title="home",
|
|
template="nav_playground.html",
|
|
language="en",
|
|
slug="home",
|
|
xframe_options=constants.X_FRAME_OPTIONS_DENY,
|
|
)
|
|
|
|
resp = self.client.get(page.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), "DENY")
|
|
|
|
def test_xframe_options_inherit_with_parent(self):
|
|
"""Test that X-Frame-Options is set to parent page's setting when inherit is set"""
|
|
parent = create_page(
|
|
title="home",
|
|
template="nav_playground.html",
|
|
language="en",
|
|
slug="home",
|
|
xframe_options=constants.X_FRAME_OPTIONS_DENY,
|
|
)
|
|
|
|
child1 = create_page(
|
|
title="subpage",
|
|
template="nav_playground.html",
|
|
language="en",
|
|
slug="subpage",
|
|
parent=parent,
|
|
xframe_options=constants.X_FRAME_OPTIONS_INHERIT,
|
|
)
|
|
|
|
child2 = create_page(
|
|
title="subpage",
|
|
template="nav_playground.html",
|
|
language="en",
|
|
slug="subpage",
|
|
parent=child1,
|
|
xframe_options=constants.X_FRAME_OPTIONS_ALLOW,
|
|
)
|
|
child3 = create_page(
|
|
title="subpage",
|
|
template="nav_playground.html",
|
|
language="en",
|
|
slug="subpage",
|
|
parent=child2,
|
|
xframe_options=constants.X_FRAME_OPTIONS_INHERIT,
|
|
)
|
|
|
|
resp = self.client.get(parent.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), "DENY")
|
|
|
|
resp = self.client.get(child1.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), "DENY")
|
|
|
|
resp = self.client.get(child2.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), None)
|
|
|
|
resp = self.client.get(child3.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), None)
|
|
|
|
def test_top_level_page_inherited_xframe_options_are_applied(self):
|
|
MIDDLEWARE = settings.MIDDLEWARE + ["django.middleware.clickjacking.XFrameOptionsMiddleware"]
|
|
with self.settings(MIDDLEWARE=MIDDLEWARE):
|
|
page = create_page("test page 1", "nav_playground.html", "en")
|
|
resp = self.client.get(page.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), "SAMEORIGIN")
|
|
|
|
def test_xframe_options_with_cms_page_cache_and_clickjacking_middleware(self):
|
|
# Refs: 6346
|
|
if getattr(settings, "MIDDLEWARE", None):
|
|
override = {
|
|
"MIDDLEWARE": settings.MIDDLEWARE
|
|
+ [
|
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
]
|
|
}
|
|
else:
|
|
override = {
|
|
"MIDDLEWARE_CLASSES": settings.MIDDLEWARE_CLASSES
|
|
+ [
|
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
]
|
|
}
|
|
|
|
override["CMS_PAGE_CACHE"] = True
|
|
|
|
with self.settings(**override):
|
|
page = create_page(
|
|
"test page 1",
|
|
"nav_playground.html",
|
|
"en",
|
|
xframe_options=constants.X_FRAME_OPTIONS_ALLOW,
|
|
)
|
|
|
|
# Normal response from render_page
|
|
resp = self.client.get(page.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), None)
|
|
|
|
# Response from page cache
|
|
resp = self.client.get(page.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), None)
|
|
|
|
def test_xframe_options_inherit_with_cms_page_cache_and_clickjacking_middleware(self):
|
|
# A cached "Inherit" page must still receive the clickjacking
|
|
# middleware's X-Frame-Options header. Regression: the cached copy used
|
|
# to be served with xframe_options_exempt=True, which suppressed the
|
|
# middleware and dropped the header, leaving cached inherit pages
|
|
# framable while the uncached copy was protected.
|
|
if getattr(settings, "MIDDLEWARE", None):
|
|
override = {
|
|
"MIDDLEWARE": settings.MIDDLEWARE
|
|
+ [
|
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
]
|
|
}
|
|
else:
|
|
override = {
|
|
"MIDDLEWARE_CLASSES": settings.MIDDLEWARE_CLASSES
|
|
+ [
|
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
|
]
|
|
}
|
|
|
|
override["CMS_PAGE_CACHE"] = True
|
|
override["X_FRAME_OPTIONS"] = "SAMEORIGIN"
|
|
|
|
with self.settings(**override):
|
|
page = create_page(
|
|
"inherit page",
|
|
"nav_playground.html",
|
|
"en",
|
|
xframe_options=constants.X_FRAME_OPTIONS_INHERIT,
|
|
)
|
|
|
|
# Fresh response from render_page: the middleware adds the site
|
|
# default because the page defers to it (inherit).
|
|
resp = self.client.get(page.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), "SAMEORIGIN")
|
|
|
|
# Response from page cache must carry the same protection.
|
|
resp = self.client.get(page.get_absolute_url("en"))
|
|
self.assertEqual(resp.get("X-Frame-Options"), "SAMEORIGIN")
|
|
|
|
def test_page_cache_basic(self):
|
|
"""
|
|
Test that the page cache works in its basic form
|
|
"""
|
|
page = self.create_homepage("page", "nav_playground.html", "en")
|
|
page_url = page.get_absolute_url()
|
|
request = self.get_request(page_url)
|
|
|
|
# First request - should set cache
|
|
response = self.client.get(page_url)
|
|
self.assertEqual(response.status_code, 200)
|
|
cached_data = get_page_cache(request)
|
|
self.assertIsNotNone(cached_data)
|
|
|
|
# Verify cache contents
|
|
cached_content, cached_headers, expires, xframe_options_exempt = cached_data
|
|
self.assertEqual(cached_content, response.content)
|
|
|
|
def test_page_cache_language_handling(self):
|
|
"""
|
|
Test that the page cache properly handles different languages
|
|
"""
|
|
page = self.create_homepage("page", "nav_playground.html", "en")
|
|
create_page_content("fr", "french home", page)
|
|
|
|
# Get the page in English
|
|
en_url = page.get_absolute_url(language="en")
|
|
en_request = self.get_request(en_url)
|
|
en_request.LANGUAGE_CODE = "en"
|
|
en_response = self.client.get(en_url)
|
|
self.assertEqual(en_response.status_code, 200)
|
|
|
|
# Get the page in French
|
|
fr_url = page.get_absolute_url(language="fr")
|
|
fr_request = self.get_request(fr_url)
|
|
fr_request.LANGUAGE_CODE = "fr"
|
|
fr_response = self.client.get(fr_url)
|
|
self.assertEqual(fr_response.status_code, 200)
|
|
|
|
# Verify we have different cache entries for each language
|
|
en_cached = get_page_cache(en_request)
|
|
fr_cached = get_page_cache(fr_request)
|
|
|
|
self.assertIsNotNone(en_cached)
|
|
self.assertIsNotNone(fr_cached)
|
|
self.assertNotEqual(en_cached[0], fr_cached[0]) # Different content for different languages
|
|
|
|
def test_page_cache_language_fallback(self):
|
|
"""
|
|
Test that the page cache works correctly with language fallbacks:
|
|
- No cache entry should exist for non-existent language versions
|
|
- The fallback language version should be cached
|
|
"""
|
|
page = self.create_homepage("page", "nav_playground.html", "en")
|
|
|
|
# Request in German (which doesn't exist)
|
|
de_url = page.get_absolute_url(language="de")
|
|
de_request = self.get_request(de_url)
|
|
de_request.LANGUAGE_CODE = "de"
|
|
|
|
response = self.client.get(de_url)
|
|
self.assertEqual(response.status_code, 302) # Should redirect to English
|
|
self.assertTrue(response["Location"].startswith("/en/")) # Redirects to English version
|
|
|
|
# German version should NOT be cached since it doesn't exist
|
|
cached_data = get_page_cache(de_request)
|
|
self.assertIsNone(cached_data, "Non-existent German version should not be cached")
|
|
|
|
# English version should be cached after we follow the redirect
|
|
en_request = self.get_request(response["Location"])
|
|
en_request.LANGUAGE_CODE = "en"
|
|
en_response = self.client.get(response["Location"])
|
|
self.assertEqual(en_response.status_code, 200)
|
|
|
|
en_cached = get_page_cache(en_request)
|
|
self.assertIsNotNone(en_cached, "Fallback English version should be cached")
|
|
|
|
def test_page_objects_search(self):
|
|
"""
|
|
Test the search method of Page.objects
|
|
"""
|
|
page1 = create_page("test page 1", "nav_playground.html", "en", slug="test-page-1")
|
|
create_page_content("de", "some random content", page1)
|
|
create_page("another page", "nav_playground.html", "en", slug="another-page")
|
|
create_page_content("fr", "some more random content", page1)
|
|
|
|
# Search by title
|
|
results = Page.objects.search("test")
|
|
self.assertEqual(len(results), 1)
|
|
self.assertEqual(results[0].pk, page1.pk)
|
|
|
|
# Search by content
|
|
results = Page.objects.search("more random")
|
|
self.assertEqual(len(results), 1)
|
|
self.assertEqual(results[0].pk, page1.pk)
|
|
|
|
# Search by content and language
|
|
results = Page.objects.search("more random", language="fr")
|
|
self.assertEqual(len(results), 1)
|
|
self.assertEqual(results[0].pk, page1.pk)
|
|
|
|
# Search with no results
|
|
results = Page.objects.search("nonexistent")
|
|
self.assertEqual(len(results), 0)
|
|
|
|
# Search with language that has no content
|
|
results = Page.objects.search("more random", language="en")
|
|
self.assertEqual(len(results), 0)
|
|
|
|
|
|
class PageTreeTests(CMSTestCase):
|
|
def test_rename_node(self):
|
|
superuser = self.get_superuser()
|
|
create_page("grandpa", "nav_playground.html", "en", slug="home")
|
|
parent = create_page("parent", "nav_playground.html", "en", slug="parent")
|
|
child = create_page("child", "nav_playground.html", "en", slug="child", parent=parent)
|
|
endpoint = self.get_page_change_uri("en", parent)
|
|
|
|
with self.login_user_context(superuser):
|
|
data = {"title": "parent", "slug": "father", "template": "nav_playground.html"}
|
|
response = self.client.post(endpoint, data)
|
|
self.assertRedirects(response, self.get_pages_admin_list_uri("en"))
|
|
|
|
child = Page.objects.get(pk=child.pk)
|
|
|
|
self.assertEqual(child.get_absolute_url(language="en"), "/en/father/child/")
|
|
|
|
def test_rename_node_alters_descendants(self):
|
|
superuser = self.get_superuser()
|
|
create_page("grandpa", "nav_playground.html", "en", slug="home")
|
|
parent = create_page("parent", "nav_playground.html", "en", slug="parent")
|
|
child = create_page("child", "nav_playground.html", "en", slug="child", parent=parent)
|
|
grandchild_1 = create_page("grandchild-1", "nav_playground.html", "en", slug="grandchild-1", parent=child)
|
|
child.refresh_from_db()
|
|
grandchild_2 = create_page("grandchild-2", "nav_playground.html", "en", slug="grandchild-2", parent=child)
|
|
child.refresh_from_db()
|
|
grandchild_3 = create_page("grandchild-3", "nav_playground.html", "en", slug="grandchild-3", parent=child)
|
|
endpoint = self.get_page_change_uri("en", parent)
|
|
|
|
with self.login_user_context(superuser):
|
|
data = {"title": "parent", "slug": "father", "template": "nav_playground.html"}
|
|
response = self.client.post(endpoint, data)
|
|
self.assertRedirects(response, self.get_pages_admin_list_uri("en"))
|
|
|
|
self.assertEqual(grandchild_1.get_absolute_url(language="en"), "/en/father/child/grandchild-1/")
|
|
self.assertEqual(grandchild_2.get_absolute_url(language="en"), "/en/father/child/grandchild-2/")
|
|
self.assertEqual(grandchild_3.get_absolute_url(language="en"), "/en/father/child/grandchild-3/")
|
|
|
|
def test_move_node(self):
|
|
home = create_page("grandpa", "nav_playground.html", "en", slug="home")
|
|
parent = create_page("parent", "nav_playground.html", "en", slug="parent")
|
|
child = create_page("child", "nav_playground.html", "en", slug="child", parent=home)
|
|
child.move_page(parent)
|
|
child.refresh_from_db()
|
|
self.assertEqual(child.get_absolute_url(language="en"), "/en/parent/child/")
|
|
|
|
|
|
class PageContentTests(CMSTestCase):
|
|
def setUp(self):
|
|
self.page = create_page("english-page", "nav_playground.html", "en")
|
|
self.german_content = create_page_content("de", "german content", self.page)
|
|
self.english_content = self.page.get_content_obj("en")
|
|
|
|
def test_get_content_obj(self):
|
|
"""
|
|
Cache partially populated, if no hit it should try to populate it
|
|
"""
|
|
del self.page.page_content_cache["de"]
|
|
german_content = self.page.get_content_obj("de")
|
|
self.assertEqual(german_content.pk, self.german_content.pk)
|
|
|
|
def test_page_content_manager(self):
|
|
from cms.models.managers import ContentAdminQuerySet
|
|
|
|
# check if admin_manager exists
|
|
self.assertTrue(isinstance(PageContent.admin_manager, models.Manager))
|
|
self.assertTrue(isinstance(PageContent.admin_manager.none(), ContentAdminQuerySet))
|
|
|
|
# setup created to page contents for self.page. Test if admin_manager sees them
|
|
self.assertEqual(PageContent.admin_manager.filter(page=self.page).count(), 2)
|
|
|
|
# test if the current_content_iterator sees both page contents
|
|
self.assertEqual(len(list(PageContent.admin_manager.filter(page=self.page).current_content())), 2)
|