forked from ungleich-public/dynamicweb
982 lines
41 KiB
Python
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)
|