dynamicweb/cms/tests/test_rendering.py

982 lines
41 KiB
Python

from django.core.cache import cache
from django.http.response import Http404
from django.test.utils import override_settings
from django.urls import reverse
from sekizai.context import SekizaiContext
from cms import plugin_rendering
from cms.api import add_plugin, create_page
from cms.cache.placeholder import get_placeholder_cache
from cms.models import EmptyPageContent, Page, Placeholder
from cms.plugin_rendering import PluginContext
from cms.test_utils.project.placeholderapp.models import Example1
from cms.test_utils.testcases import CMSTestCase
from cms.test_utils.util.context_managers import override_placeholder_conf
from cms.test_utils.util.fuzzy_int import FuzzyInt
from cms.toolbar.toolbar import CMSToolbar
from cms.toolbar.utils import get_object_edit_url
from cms.views import details
TEMPLATE_NAME = 'tests/rendering/base.html'
INHERIT_TEMPLATE_NAME = 'tests/rendering/inherit.html'
INHERIT_WITH_OR_TEMPLATE_NAME = 'tests/rendering/inherit_with_or.html'
def sample_plugin_processor(instance, placeholder, rendered_content, original_context):
original_context_var = original_context['original_context_var']
return f'{rendered_content}|test_plugin_processor_ok|{instance.body}|{placeholder.slot}|{original_context_var}'
def sample_plugin_context_processor(instance, placeholder, original_context):
content = 'test_plugin_context_processor_ok|' + instance.body + '|' + \
placeholder.slot + '|' + original_context['original_context_var']
return {
'test_plugin_context_processor': content,
}
@override_settings(
CMS_TEMPLATES=[
(TEMPLATE_NAME, TEMPLATE_NAME),
('extra_context.html', 'extra_context.html')
],
)
class RenderingEmptyTestCase(CMSTestCase):
def setUp(self):
super().setUp()
self.test_data = {
'title': 'RenderingTestCase-title',
'slug': 'renderingtestcase-slug',
'reverse_id': 'renderingtestcase-reverse-id',
}
self.user = self.get_superuser()
self.client.force_login(self.user)
self.page = create_page(
self.test_data['title'], TEMPLATE_NAME, 'en',
slug=self.test_data['slug'], created_by=self.user,
reverse_id=self.test_data['reverse_id']
)
# we need an empty pagecontent for this.
self.page.pagecontent_set.all().delete()
def test_page_with_empty_pagecontent(self):
"""
A page with EmptyPageContent except root returns 404 when you try to view it.
"""
page_content = self.page.get_content_obj('en', force_reload=True)
self.assertEqual(isinstance(page_content, EmptyPageContent), True)
with self.assertRaises(Http404):
path = self.page.get_path('en')
request = self.get_request(path=path, page=self.page)
details(request, slug=path)
def test_page_with_empty_pagecontent_for_root_url(self):
"""
The root page with EmptyPageContent redirects to PageContent's changelist
"""
page_content = self.page.get_content_obj('en', force_reload=True)
self.assertEqual(isinstance(page_content, EmptyPageContent), True)
request = self.get_request(path='/en/', page=self.page)
response = details(request, slug=self.page.get_path('en'))
self.assertEqual(response.status_code, 302)
self.assertEqual(response.url, reverse('admin:cms_pagecontent_changelist'))
@override_settings(
CMS_TEMPLATES=[
(TEMPLATE_NAME, TEMPLATE_NAME),
(INHERIT_TEMPLATE_NAME, INHERIT_TEMPLATE_NAME),
(INHERIT_WITH_OR_TEMPLATE_NAME, INHERIT_WITH_OR_TEMPLATE_NAME),
('extra_context.html', 'extra_context.html')
],
)
class RenderingTestCase(CMSTestCase):
def setUp(self):
super().setUp()
self.test_user = self.get_superuser()
with self.login_user_context(self.test_user):
self.test_data = {
'title': 'RenderingTestCase-title',
'slug': 'renderingtestcase-slug',
'reverse_id': 'renderingtestcase-reverse-id',
'text_main': 'RenderingTestCase-main',
'text_sub': 'RenderingTestCase-sub',
}
self.test_data2 = {
'title': 'RenderingTestCase-title2',
'slug': 'RenderingTestCase-slug2',
'reverse_id': 'renderingtestcase-reverse-id2',
}
self.test_data3 = {
'title': 'RenderingTestCase-title3',
'slug': 'RenderingTestCase-slug3',
'reverse_id': 'renderingtestcase-reverse-id3',
'text_sub': 'RenderingTestCase-sub3',
}
self.test_data4 = {
'title': 'RenderingTestCase-title3',
'no_extra': 'no extra var!',
'placeholderconf': {'extra_context': {'extra_context': {'extra_var': 'found extra var'}}},
'extra': 'found extra var',
}
self.test_data5 = {
'title': 'RenderingTestCase-title5',
'slug': 'RenderingTestCase-slug5',
'reverse_id': 'renderingtestcase-reverse-id5',
'text_main': 'RenderingTestCase-main-page5',
'text_sub': 'RenderingTestCase-sub5',
}
self.test_data6 = {
'title': 'RenderingTestCase-title6',
'slug': 'RenderingTestCase-slug6',
'reverse_id': 'renderingtestcase-reverse-id6',
'text_sub': 'RenderingTestCase-sub6',
}
self.test_data7 = {
'title': 'RenderingTestCase-title7',
'slug': 'RenderingTestCase-slug7',
'reverse_id': 'renderingtestcase-reverse-id7',
'text_sub': 'RenderingTestCase-sub7',
}
self.test_data8 = {
'title': 'RenderingTestCase-title8',
'slug': 'RenderingTestCase-slug8',
'reverse_id': 'renderingtestcase-reverse-id8',
'text_sub': 'RenderingTestCase-sub8',
}
self.test_data9 = {
'title': 'RenderingTestCase-title9',
'slug': 'RenderingTestCase-slug9',
'reverse_id': 'renderingtestcase-reverse-id9',
'text_sub': 'RenderingTestCase-sub9',
}
self.test_data10 = {
'title': 'RenderingTestCase-title10',
'slug': 'RenderingTestCase-slug10',
'reverse_id': 'renderingtestcase-reverse-id10',
'text_sub': 'RenderingTestCase-sub10',
}
self.insert_test_content()
def insert_test_content(self):
# Insert a page
p = create_page(self.test_data['title'], TEMPLATE_NAME, 'en',
slug=self.test_data['slug'], created_by=self.test_user,
reverse_id=self.test_data['reverse_id'])
# Placeholders have been inserted on post_save signal:
self.test_placeholders = {}
for placeholder in p.get_placeholders('en'):
self.test_placeholders[placeholder.slot] = placeholder
# Insert some test Text plugins
add_plugin(self.test_placeholders['main'], 'TextPlugin', 'en',
body=self.test_data['text_main'])
add_plugin(self.test_placeholders['sub'], 'TextPlugin', 'en',
body=self.test_data['text_sub'])
# Insert another page that is not the home page
p2 = create_page(self.test_data2['title'], INHERIT_TEMPLATE_NAME, 'en',
parent=p, slug=self.test_data2['slug'],
reverse_id=self.test_data2['reverse_id'])
# Insert another page that is not the home page
p3 = create_page(self.test_data3['title'], INHERIT_TEMPLATE_NAME, 'en',
slug=self.test_data3['slug'], parent=p2,
reverse_id=self.test_data3['reverse_id'])
# Placeholders have been inserted on post_save signal:
self.test_placeholders3 = {}
for placeholder in p3.get_placeholders('en'):
self.test_placeholders3[placeholder.slot] = placeholder
# # Insert some test Text plugins
add_plugin(self.test_placeholders3['sub'], 'TextPlugin', 'en', body=self.test_data3['text_sub'])
# Insert another page that is not the home
p4 = create_page(self.test_data4['title'], 'extra_context.html', 'en', parent=p)
# Placeholders have been inserted on post_save signal:
self.test_placeholders4 = {}
for placeholder in p4.get_placeholders('en'):
self.test_placeholders4[placeholder.slot] = placeholder
# Insert some test plugins
add_plugin(self.test_placeholders4['extra_context'], 'ExtraContextPlugin', 'en')
# Insert another page that is not the home page
p5 = create_page(
self.test_data5['title'], INHERIT_TEMPLATE_NAME, 'en',
parent=p, slug=self.test_data5['slug'],
reverse_id=self.test_data5['reverse_id']
)
# Placeholders have been inserted on post_save signal:
self.test_placeholders5 = {}
for placeholder in p5.get_placeholders('en'):
self.test_placeholders5[placeholder.slot] = placeholder
# # Insert some test Text plugins
add_plugin(self.test_placeholders5['sub'], 'TextPlugin', 'en', body=self.test_data5['text_sub'])
add_plugin(self.test_placeholders5['main'], 'TextPlugin', 'en', body=self.test_data5['text_main'])
# Insert another page that is not the home page
p6 = create_page(
self.test_data6['title'], INHERIT_TEMPLATE_NAME, 'en',
slug=self.test_data6['slug'], parent=p5,
reverse_id=self.test_data6['reverse_id']
)
# Placeholders have been inserted on post_save signal:
self.test_placeholders6 = {}
for placeholder in p6.get_placeholders('en'):
self.test_placeholders6[placeholder.slot] = placeholder
# # Insert some test Text plugins
add_plugin(self.test_placeholders6['sub'], 'TextPlugin', 'en', body=self.test_data6['text_sub'])
p7 = create_page(
self.test_data7['title'], INHERIT_TEMPLATE_NAME, 'en',
slug=self.test_data7['slug'], parent=p6,
reverse_id=self.test_data7['reverse_id']
)
p8 = create_page(
self.test_data8['title'], INHERIT_WITH_OR_TEMPLATE_NAME, 'en',
slug=self.test_data8['slug'], parent=p7,
reverse_id=self.test_data8['reverse_id']
)
p9 = create_page(
self.test_data9['title'], INHERIT_WITH_OR_TEMPLATE_NAME, 'en',
slug=self.test_data9['slug'],
reverse_id=self.test_data9['reverse_id']
)
p10 = create_page(
self.test_data10['title'], INHERIT_WITH_OR_TEMPLATE_NAME, 'en',
slug=self.test_data10['slug'], parent=p9,
reverse_id=self.test_data10['reverse_id'])
# Reload test pages
self.test_page = self.reload(p)
self.test_page2 = self.reload(p2)
self.test_page3 = self.reload(p3)
self.test_page4 = self.reload(p4)
self.test_page5 = self.reload(p5)
self.test_page6 = self.reload(p6)
self.test_page7 = self.reload(p7)
self.test_page8 = self.reload(p8)
self.test_page9 = self.reload(p9)
self.test_page10 = self.reload(p10)
def strip_rendered(self, content):
return content.strip().replace("\n", "")
@override_settings(CMS_TEMPLATES=[(TEMPLATE_NAME, '')])
def render(self, page, template=None, context_vars=None, request=None):
if request is None:
request = self.get_request(page=page)
request.toolbar = CMSToolbar(request)
if context_vars is None:
context_vars = {}
if template is None:
template = page.get_template()
template_obj = self.get_template(template)
output = template_obj.render(context_vars, request)
else:
output = self.render_template_obj(template, context_vars, request)
return self.strip_rendered(output)
@override_settings(CMS_TEMPLATES=[(TEMPLATE_NAME, '')])
def test_details_view(self):
"""
Tests that the `detail` view is working.
"""
response = details(self.get_request(page=self.test_page), self.test_page.get_path('en'))
response.render()
r = self.strip_rendered(response.content.decode('utf8'))
self.assertEqual(r, '|' + self.test_data['text_main'] + '|' + self.test_data['text_sub'] + '|')
def test_getting_placeholders(self):
"""ContentRenderer._get_content_object uses toolbar to return placeholders of a page"""
request = self.get_request(page=self.test_page)
request.toolbar = CMSToolbar(request)
wrong_content_obj = self.test_page2.get_content_obj("en")
wrong_content_obj.page = self.test_page
request.toolbar.set_object(wrong_content_obj)
content_renderer = self.get_content_renderer(request)
placeholders = content_renderer._get_content_object(self.test_page)
wrong_content_obj.page = self.test_page2
self.assertEqual(len(placeholders), 2)
@override_settings(
CMS_PLUGIN_PROCESSORS=('cms.tests.test_rendering.sample_plugin_processor',),
CMS_PLUGIN_CONTEXT_PROCESSORS=('cms.tests.test_rendering.sample_plugin_context_processor',),
)
def test_processors(self):
"""
Tests that plugin processors and plugin context processors can be defined
in settings and are working and that extra plugin context processors can be
passed to PluginContext.
"""
from djangocms_text.cms_plugins import TextPlugin
from cms.plugin_pool import plugin_pool
instance = self.test_placeholders['main'].get_plugins('en').first().get_bound_plugin()
load_from_string = self.load_template_from_string
@plugin_pool.register_plugin
class ProcessorTestPlugin(TextPlugin):
name = "Test Plugin"
def get_render_template(self, context, instance, placeholder):
t = '{% load cms_tags %}' + \
'{{ body }}|test_passed_plugin_context_processor_ok|' \
'{{ test_plugin_context_processor }}'
return load_from_string(t)
def test_passed_plugin_context_processor(instance, placeholder, context):
return {'test_passed_plugin_context_processor': 'test_passed_plugin_context_processor_ok'}
instance.plugin_type = 'ProcessorTestPlugin'
instance._inst = instance
context = PluginContext(
{'original_context_var': 'original_context_var_ok', "request": None},
instance,
self.test_placeholders['main'], processors=(test_passed_plugin_context_processor,)
)
plugin_rendering._standard_processors = {}
content_renderer = self.get_content_renderer()
r = content_renderer.render_plugin(instance, context, self.test_placeholders['main'])
expected = (
f"{self.test_data['text_main']}|test_passed_plugin_context_processor_ok|test_plugin_context_processor_ok|"
f"{self.test_data['text_main']}|main|original_context_var_ok|test_plugin_processor_ok|"
f"{self.test_data['text_main']}|main|original_context_var_ok"
)
self.assertEqual(r, expected)
plugin_rendering._standard_processors = {}
def test_placeholder(self):
"""
Tests the {% placeholder %} templatetag.
"""
r = self.render(self.test_page)
self.assertEqual(r, '|' + self.test_data['text_main'] + '|' + self.test_data['text_sub'] + '|')
def test_placeholder_extra_context(self):
t = '{% load cms_tags %}{% placeholder "extra_context" %}'
r = self.render(self.test_page4, template=t)
self.assertEqual(r, self.test_data4['no_extra'])
cache.clear()
with override_placeholder_conf(CMS_PLACEHOLDER_CONF=self.test_data4['placeholderconf']):
r = self.render(self.test_page4, template=t)
self.assertEqual(r, self.test_data4['extra'])
def test_placeholder_extra_context_template_specific(self):
"""Template-specific CMS_PLACEHOLDER_CONF keys must be respected (regression #8649)."""
t = '{% load cms_tags %}{% placeholder "extra_context" %}'
template_specific_conf = {
'extra_context.html extra_context': self.test_data4['placeholderconf']['extra_context'],
}
r = self.render(self.test_page4, template=t)
self.assertEqual(r, self.test_data4['no_extra'])
cache.clear()
with override_placeholder_conf(CMS_PLACEHOLDER_CONF=template_specific_conf):
r = self.render(self.test_page4, template=t)
self.assertEqual(r, self.test_data4['extra'])
def test_placeholder_extra_context_template_specific_takes_precedence(self):
"""Template-specific CMS_PLACEHOLDER_CONF key takes precedence over generic slot key."""
t = '{% load cms_tags %}{% placeholder "extra_context" %}'
combined_conf = {
'extra_context': {'extra_context': {'extra_var': 'generic var'}},
'extra_context.html extra_context': self.test_data4['placeholderconf']['extra_context'],
}
cache.clear()
with override_placeholder_conf(CMS_PLACEHOLDER_CONF=combined_conf):
r = self.render(self.test_page4, template=t)
self.assertEqual(r, self.test_data4['extra']) # template-specific wins, not 'generic var'
def test_placeholder_or(self):
"""
Tests the {% placeholder %} templatetag.
"""
t = '{% load cms_tags %}' + \
'|{% placeholder "empty" or %}No content{% endplaceholder %}'
r = self.render(self.test_page, template=t)
self.assertEqual(r, '|No content')
def test_placeholder_or_in_edit_mode(self):
"""
Tests the {% placeholder or %} templatetag in edit mode.
"""
t = '{% load cms_tags %}' + \
'|{% placeholder "empty" or %}No content{% endplaceholder %}'
superuser = self.get_superuser()
with self.login_user_context(superuser):
endpoint = self.test_page.get_absolute_url() + '?edit'
request = self.get_request(endpoint, page=self.test_page)
request.session['cms_edit'] = True
request.toolbar = CMSToolbar(request)
renderer = self.get_content_renderer(request)
context = SekizaiContext()
context['cms_content_renderer'] = renderer
placeholder = self.test_page.get_placeholders('en').get(slot='empty')
expected = renderer.render_placeholder(
placeholder,
context=context,
language='en',
page=self.test_page,
editable=True,
)
expected = f'|{expected}No content'
rendered = self.render(self.test_page, template=t, request=request)
self.assertEqual(rendered, self.strip_rendered(expected))
def test_render_placeholder_tag(self):
"""
Tests the {% render_placeholder %} templatetag.
"""
render_placeholder_body = "I'm the render placeholder body"
ex1 = Example1(char_1="char_1", char_2="char_2", char_3="char_3",
char_4="char_4")
ex1.save()
add_plugin(ex1.placeholder, "TextPlugin", "en", body=render_placeholder_body)
t = '''{% extends "base.html" %}
{% load cms_tags %}
{% block content %}
<h1>{% render_placeholder ex1.placeholder %}</h1>
<h2>{% render_placeholder ex1.placeholder as tempvar %}</h2>
<h3>{{ tempvar }}</h3>
{% endblock content %}
'''
r = self.render(self.test_page, template=t, context_vars={'ex1': ex1})
self.assertIn(
'<h1>%s</h1>' % render_placeholder_body,
r
)
self.assertIn(
'<h2></h2>',
r
)
self.assertIn(
'<h3>%s</h3>' % render_placeholder_body,
r
)
def test_render_uncached_placeholder_tag(self):
"""
Tests the {% render_uncached_placeholder %} templatetag.
"""
render_uncached_placeholder_body = "I'm the render uncached placeholder body"
ex1 = Example1(char_1="char_1", char_2="char_2", char_3="char_3",
char_4="char_4")
ex1.save()
add_plugin(ex1.placeholder, "TextPlugin", "en", body=render_uncached_placeholder_body)
t = '''{% extends "base.html" %}
{% load cms_tags %}
{% block content %}
<h1>{% render_uncached_placeholder ex1.placeholder %}</h1>
<h2>{% render_uncached_placeholder ex1.placeholder as tempvar %}</h2>
<h3>{{ tempvar }}</h3>
{% endblock content %}
'''
r = self.render(self.test_page, template=t, context_vars={'ex1': ex1})
self.assertIn(
'<h1>%s</h1>' % render_uncached_placeholder_body,
r
)
self.assertIn(
'<h2></h2>',
r
)
self.assertIn(
'<h3>%s</h3>' % render_uncached_placeholder_body,
r
)
def test_render_uncached_placeholder_tag_no_use_cache(self):
"""
Tests that {% render_uncached_placeholder %} does not populate cache.
"""
render_uncached_placeholder_body = "I'm the render uncached placeholder body"
ex1 = Example1(char_1="char_1", char_2="char_2", char_3="char_3",
char_4="char_4")
ex1.save()
request = self.get_request('/')
add_plugin(ex1.placeholder, "TextPlugin", "en", body=render_uncached_placeholder_body)
template = '{% load cms_tags %}<h1>{% render_uncached_placeholder ex1.placeholder %}</h1>'
cache_value_before = get_placeholder_cache(ex1.placeholder, 'en', 1, request)
self.render(self.test_page, template, {'ex1': ex1})
cache_value_after = get_placeholder_cache(ex1.placeholder, 'en', 1, request)
self.assertEqual(cache_value_before, cache_value_after)
self.assertIsNone(cache_value_after)
def test_render_placeholder_tag_use_cache(self):
"""
Tests that {% render_placeholder %} populates cache.
"""
render_placeholder_body = "I'm the render placeholder body"
ex1 = Example1(char_1="char_1", char_2="char_2", char_3="char_3",
char_4="char_4")
ex1.save()
request = self.get_request('/')
add_plugin(ex1.placeholder, "TextPlugin", "en", body=render_placeholder_body)
template = '{% load cms_tags %}<h1>{% render_placeholder ex1.placeholder %}</h1>'
cache_value_before = get_placeholder_cache(ex1.placeholder, 'en', 1, request)
self.render(self.test_page, template, {'ex1': ex1})
cache_value_after = get_placeholder_cache(ex1.placeholder, 'en', 1, request)
self.assertNotEqual(cache_value_before, cache_value_after)
self.assertIsNone(cache_value_before)
self.assertIsNotNone(cache_value_after)
def test_show_placeholder(self):
"""
Tests the {% show_placeholder %} templatetag, using lookup by pk/dict/reverse_id and passing a Page object.
"""
t = '{% load cms_tags %}' + \
'|{% show_placeholder "main" ' + str(self.test_page.pk) + ' %}' + \
'|{% show_placeholder "main" test_dict %}' + \
'|{% show_placeholder "sub" "' + str(self.test_page.reverse_id) + '" %}' + \
'|{% show_placeholder "sub" test_page %}'
r = self.render(
self.test_page,
template=t,
context_vars={'test_page': self.test_page, 'test_dict': {'pk': self.test_page.pk}}
)
self.assertEqual(r, ('|' + self.test_data['text_main']) * 2 + ('|' + self.test_data['text_sub']) * 2)
def test_show_placeholder_extra_context(self):
t = '{% load cms_tags %}{% show_uncached_placeholder "extra_context" ' + str(self.test_page4.pk) + ' %}'
r = self.render(self.test_page4, template=t)
self.assertEqual(r, self.test_data4['no_extra'])
cache.clear()
with override_placeholder_conf(CMS_PLACEHOLDER_CONF=self.test_data4['placeholderconf']):
r = self.render(self.test_page4, template=t)
self.assertEqual(r, self.test_data4['extra'])
def test_show_uncached_placeholder_by_pk(self):
"""
Tests the {% show_uncached_placeholder %} templatetag, using lookup by pk.
"""
template = '{%% load cms_tags %%}{%% show_uncached_placeholder "main" %s %%}' % self.test_page.pk
output = self.render(self.test_page, template)
self.assertEqual(output, self.test_data['text_main'])
def test_show_uncached_placeholder_by_lookup_dict(self):
template = '{% load cms_tags %}{% show_uncached_placeholder "main" test_dict %}'
output = self.render(self.test_page, template, {'test_dict': {'pk': self.test_page.pk}})
self.assertEqual(output, self.test_data['text_main'])
def test_show_uncached_placeholder_by_reverse_id(self):
template = '{%% load cms_tags %%}{%% show_uncached_placeholder "sub" "%s" %%}' % self.test_page.reverse_id
output = self.render(self.test_page, template)
self.assertEqual(output, self.test_data['text_sub'])
def test_show_uncached_placeholder_by_page(self):
template = '{% load cms_tags %}{% show_uncached_placeholder "sub" test_page %}'
output = self.render(self.test_page, template, {'test_page': self.test_page})
self.assertEqual(output, self.test_data['text_sub'])
def test_show_uncached_placeholder_tag_no_use_cache(self):
"""
Tests that {% show_uncached_placeholder %} does not populate cache.
"""
template = '{% load cms_tags %}<h1>{% show_uncached_placeholder "sub" test_page %}</h1>'
placeholder = self.test_page.get_placeholders('en').get(slot='sub')
request = self.get_request(page=self.test_page)
cache_value_before = get_placeholder_cache(placeholder, 'en', 1, request)
output = self.render(self.test_page, template, {'test_page': self.test_page})
cache_value_after = get_placeholder_cache(placeholder, 'en', 1, request)
self.assertEqual(output, '<h1>%s</h1>' % self.test_data['text_sub'])
self.assertEqual(cache_value_before, cache_value_after)
self.assertIsNone(cache_value_after)
def test_page_url_by_pk(self):
template = '{%% load cms_tags %%}{%% page_url %s %%}' % self.test_page2.pk
output = self.render(self.test_page, template)
self.assertEqual(output, self.test_page2.get_absolute_url())
def test_page_url_by_dictionary(self):
template = '{% load cms_tags %}{% page_url test_dict %}'
output = self.render(self.test_page, template, {'test_dict': {'pk': self.test_page2.pk}})
self.assertEqual(output, self.test_page2.get_absolute_url())
def test_page_url_by_reverse_id(self):
template = '{%% load cms_tags %%}{%% page_url "%s" %%}' % self.test_page2.reverse_id
output = self.render(self.test_page, template)
self.assertEqual(output, self.test_page2.get_absolute_url())
def test_page_url_by_reverse_id_not_on_a_page(self):
template = '{%% load cms_tags %%}{%% page_url "%s" %%}' % self.test_page2.reverse_id
output = self.render(None, template)
self.assertEqual(output, self.test_page2.get_absolute_url())
def test_page_url_by_page(self):
template = '{% load cms_tags %}{% page_url test_page %}'
output = self.render(self.test_page, template, {'test_page': self.test_page2})
self.assertEqual(output, self.test_page2.get_absolute_url())
def test_page_url_by_page_as(self):
template = '{% load cms_tags %}{% page_url test_page as test_url %}{{ test_url }}'
output = self.render(self.test_page, template, {'test_page': self.test_page2})
self.assertEqual(output, self.test_page2.get_absolute_url())
#
# To ensure compatible behaviour, test that page_url swallows any
# Page.DoesNotExist exceptions when NOT in DEBUG mode.
#
@override_settings(DEBUG=False)
def test_page_url_on_bogus_page(self):
template = '{% load cms_tags %}{% page_url "bogus_page" %}'
output = self.render(self.test_page, template, {'test_page': self.test_page2})
self.assertEqual(output, '')
#
# To ensure compatible behaviour, test that page_url will raise a
# Page.DoesNotExist exception when the page argument does not eval to a
# valid page
#
@override_settings(DEBUG=True)
def test_page_url_on_bogus_page_in_debug(self):
template = '{% load cms_tags %}{% page_url "bogus_page" %}'
self.assertRaises(
Page.DoesNotExist,
self.render,
self.test_page,
template,
{'test_page': self.test_page2}
)
#
# In the 'as varname' form, ensure that the tag will always swallow
# Page.DoesNotExist exceptions both when DEBUG is False and...
#
@override_settings(DEBUG=False)
def test_page_url_as_on_bogus_page(self):
template = '{% load cms_tags %}{% page_url "bogus_page" as test_url %}{{ test_url }}'
output = self.render(self.test_page, template, {'test_page': self.test_page2})
self.assertEqual(output, '')
#
# ...when it is True.
#
@override_settings(DEBUG=True)
def test_page_url_as_on_bogus_page_in_debug(self):
template = '{% load cms_tags %}{% page_url "bogus_page" as test_url %}{{ test_url }}'
output = self.render(self.test_page, template, {'test_page': self.test_page2})
self.assertEqual(output, '')
def test_page_attribute(self):
"""
Tests the {% page_attribute %} templatetag, using current page, lookup by pk/dict/reverse_id and passing a
Page object.
"""
t = '{% load cms_tags %}' + \
'|{% page_attribute title %}' + \
'{% page_attribute title as title %}' + \
'|{{ title }}' + \
'|{% page_attribute title ' + str(self.test_page2.pk) + ' %}' + \
'{% page_attribute title ' + str(self.test_page2.pk) + ' as title %}' + \
'|{{ title }}' + \
'|{% page_attribute title test_dict %}' + \
'{% page_attribute title test_dict as title %}' + \
'|{{ title }}' + \
'|{% page_attribute slug "' + str(self.test_page2.reverse_id) + '" %}' + \
'{% page_attribute slug "' + str(self.test_page2.reverse_id) + '" as slug %}' + \
'|{{ slug }}' + \
'|{% page_attribute slug test_page %}' + \
'{% page_attribute slug test_page as slug %}' + \
'|{{ slug }}'
r = self.render(
self.test_page,
template=t,
context_vars={'test_page': self.test_page2, 'test_dict': {'pk': self.test_page2.pk}}
)
self.assertEqual(r, ('|' + self.test_data['title']) * 2 + ('|' + self.test_data2['title']) * 4 + (
'|' + self.test_data2['slug']) * 4)
def test_inherit_placeholder(self):
# a page whose parent has no 'main' placeholder inherits from ancestors
r = self.render(self.test_page3)
self.assertEqual(r, '|' + self.test_data['text_main'] + '|' + self.test_data3['text_sub'])
# a page whose parent has 'main' placeholder inherits from the parent, not ancestors
r = self.render(self.test_page6)
self.assertEqual(r, '|' + self.test_data5['text_main'] + '|' + self.test_data6['text_sub'])
def test_inherit_placeholder_with_cache(self):
expected_6 = '|' + self.test_data5['text_main'] + '|' + self.test_data6['text_sub']
expected_7 = '|' + self.test_data5['text_main'] + '|'
# Render the top-most page
# This will cache its contents
self.render(self.test_page)
# Render the parent page
# This will cache its contents
self.render(self.test_page5)
# Render the target page
# This should use the cached parent page content
self.assertEqual(self.render(self.test_page6), expected_6)
self.assertEqual(self.render(self.test_page7), expected_7)
self.render(self.test_page9)
# This should use the cached parent page content
self.assertEqual(self.render(self.test_page10), '|<p>Ultimate fallback</p>|')
def test_inherit_placeholder_with_or(self):
# Tests that the "or" statement used in a {% placeholder %}
# declaration is used as the last fallback when inheritance
# fails to find content.
expected_8 = '|' + self.test_data5['text_main'] + '|'
self.assertEqual(self.render(self.test_page8), expected_8)
expected_10 = '|<p>Ultimate fallback</p>|'
self.assertEqual(self.render(self.test_page10), expected_10)
def test_inherit_placeholder_override(self):
# Tests that the user can override the inherited content
# in a placeholder by adding plugins to the inherited placeholder.
# a page whose parent has 'main' placeholder inherits from the parent, not ancestors
r = self.render(self.test_page5)
self.assertEqual(r, '|' + self.test_data5['text_main'] + '|' + self.test_data5['text_sub'])
@override_settings(CMS_PLACEHOLDER_CONF={None: {'language_fallback': False}})
def test_inherit_placeholder_queries(self):
with self.assertNumQueries(FuzzyInt(6, 10)):
r = self.render(self.test_page2)
self.assertEqual(r, '|' + self.test_data['text_main'] + '|')
def test_render_placeholder_toolbar(self):
placeholder = Placeholder()
placeholder.slot = 'test'
placeholder.pk = placeholder.id = 99
with self.login_user_context(self.get_superuser()):
page_content = self.get_pagecontent_obj(self.test_page)
request = self.get_request(get_object_edit_url(page_content))
request.session = {}
request.toolbar = CMSToolbar(request)
renderer = self.get_content_renderer(request)
context = SekizaiContext()
context['request'] = request
classes = [
"cms-placeholder-%s" % placeholder.pk,
'cms-placeholder',
]
output = renderer.render_placeholder(placeholder, context, 'en', editable=True)
for cls in classes:
self.assertTrue(cls in output, f'{cls!r} is not in {output!r}')
def test_render_plugin_toolbar_markup(self):
"""
Ensures that the edit-mode markup is correct
"""
page = self.test_page
placeholder = page.get_placeholders('en').get(slot='main')
parent_plugin = add_plugin(placeholder, 'SolarSystemPlugin', 'en')
child_plugin_1 = add_plugin(placeholder, 'PlanetPlugin', 'en', target=parent_plugin)
child_plugin_2 = add_plugin(placeholder, 'PlanetPlugin', 'en', target=parent_plugin)
parent_plugin.child_plugin_instances = [
child_plugin_1,
child_plugin_2,
]
plugins = [
parent_plugin,
child_plugin_1,
child_plugin_2,
]
with self.login_user_context(self.get_superuser()):
page_content = self.get_pagecontent_obj(page)
request = self.get_request(get_object_edit_url(page_content))
request.session = {}
request.toolbar = CMSToolbar(request)
context = SekizaiContext()
context['request'] = request
content_renderer = request.toolbar.get_content_renderer()
output = content_renderer.render_plugin(
instance=parent_plugin,
context=context,
placeholder=placeholder,
editable=True,
)
tag_format = ('<template class="cms-plugin cms-plugin-start cms-plugin-{}" data-cms-placeholder="{}">')
for plugin in plugins:
start_tag = tag_format.format(plugin.pk, plugin.placeholder_id, plugin.position)
self.assertIn(start_tag, output)
@override_settings(
CMS_TEMPLATES=[
(TEMPLATE_NAME, TEMPLATE_NAME),
],
)
class RenderedPlaceholderTestCase(CMSTestCase):
"""Test cases for the RenderedPlaceholder class"""
def test_rendered_placeholder_init(self):
"""Test RenderedPlaceholder initialization"""
from cms.plugin_rendering import RenderedPlaceholder
page = create_page("Test", TEMPLATE_NAME, "en")
placeholder = page.get_placeholders("en").first()
rendered_placeholder = RenderedPlaceholder(
placeholder=placeholder,
language="en",
site_id=1,
cached=True,
editable=False,
has_content=True,
)
self.assertEqual(rendered_placeholder.placeholder, placeholder)
self.assertEqual(rendered_placeholder.language, "en")
self.assertEqual(rendered_placeholder.site_id, 1)
self.assertTrue(rendered_placeholder.cached)
self.assertFalse(rendered_placeholder.editable)
self.assertTrue(rendered_placeholder.has_content)
def test_rendered_placeholder_equality(self):
"""Test RenderedPlaceholder equality comparison"""
from cms.plugin_rendering import RenderedPlaceholder
page = create_page("Test", TEMPLATE_NAME, "en")
placeholders = page.get_placeholders("en")
placeholder1 = placeholders[0]
# Create two RenderedPlaceholder instances with same placeholder
# but different parameters
rendered1 = RenderedPlaceholder(
placeholder=placeholder1,
language="en",
site_id=1,
cached=True,
editable=True,
)
rendered2 = RenderedPlaceholder(
placeholder=placeholder1,
language="de",
site_id=2,
cached=False,
editable=False,
)
# They should be equal because they represent the same placeholder
self.assertEqual(rendered1, rendered2)
def test_rendered_placeholder_inequality(self):
"""Test RenderedPlaceholder inequality comparison"""
from cms.plugin_rendering import RenderedPlaceholder
page = create_page("Test", TEMPLATE_NAME, "en")
placeholders = list(page.get_placeholders("en"))
# Need at least 2 placeholders
if len(placeholders) < 2:
self.skipTest("Template needs at least 2 placeholders")
placeholder1 = placeholders[0]
placeholder2 = placeholders[1]
rendered1 = RenderedPlaceholder(
placeholder=placeholder1,
language="en",
site_id=1,
)
rendered2 = RenderedPlaceholder(
placeholder=placeholder2,
language="en",
site_id=1,
)
# They should not be equal because they represent different placeholders
self.assertNotEqual(rendered1, rendered2)
def test_rendered_placeholder_hash(self):
"""Test RenderedPlaceholder hash functionality"""
from cms.plugin_rendering import RenderedPlaceholder
page = create_page("Test", TEMPLATE_NAME, "en")
placeholder = page.get_placeholders("en").first()
rendered1 = RenderedPlaceholder(
placeholder=placeholder,
language="en",
site_id=1,
)
rendered2 = RenderedPlaceholder(
placeholder=placeholder,
language="de",
site_id=2,
)
# Hash should be the same because it's based on the placeholder
self.assertEqual(hash(rendered1), hash(rendered2))
self.assertEqual(hash(rendered1), hash(placeholder))
def test_rendered_placeholder_in_set(self):
"""Test RenderedPlaceholder can be used in a set"""
from cms.plugin_rendering import RenderedPlaceholder
page = create_page("Test", TEMPLATE_NAME, "en")
placeholder = page.get_placeholders("en").first()
rendered1 = RenderedPlaceholder(
placeholder=placeholder,
language="en",
site_id=1,
)
rendered2 = RenderedPlaceholder(
placeholder=placeholder,
language="de",
site_id=2,
)
# Adding both to a set should result in only one item
# because they represent the same placeholder
placeholder_set = {rendered1, rendered2}
self.assertEqual(len(placeholder_set), 1)
def test_rendered_placeholder_default_values(self):
"""Test RenderedPlaceholder default parameter values"""
from cms.plugin_rendering import RenderedPlaceholder
page = create_page("Test", TEMPLATE_NAME, "en")
placeholder = page.get_placeholders("en").first()
# Create with minimal required parameters
rendered = RenderedPlaceholder(
placeholder=placeholder,
language="en",
site_id=1,
)
# Check default values
self.assertFalse(rendered.cached)
self.assertFalse(rendered.editable)
self.assertFalse(rendered.has_content)