def create_page_grid(self, page): """ With Cascade, create a Bootstrap Container, with a Row and a Column to be used as placeholder for all kinds of elements. """ # locate placeholder placeholder = page.placeholders.get(slot='Main Content') # create container BS3_BREAKPOINT_KEYS = list( tp[0] for tp in bs3_settings.CMSPLUGIN_CASCADE['bootstrap3']['breakpoints']) container_element = add_plugin(placeholder, BootstrapContainerPlugin, 'en', glossary={'breakpoints': BS3_BREAKPOINT_KEYS}) container_plugin = container_element.get_plugin_class_instance(self.admin_site) self.assertIsInstance(container_plugin, BootstrapContainerPlugin) # add one row row_element = add_plugin(placeholder, BootstrapRowPlugin, 'en', target=container_element, glossary={}) row_plugin = row_element.get_plugin_class_instance() self.assertIsInstance(row_plugin, BootstrapRowPlugin) # add one column column_element = add_plugin(placeholder, BootstrapColumnPlugin, 'en', target=row_element, glossary={'xs-column-width': 'col-xs-12', 'sm-column-width': 'col-sm-6', 'md-column-width': 'col-md-4', 'lg-column-width': 'col-lg-3'}) column_plugin = column_element.get_plugin_class_instance() self.assertIsInstance(column_plugin, BootstrapColumnPlugin) return column_element
def test_placeholder_pk_thousands_format(self): page = create_page("page", "nav_playground.html", "en", published=True) for placeholder in page.placeholders.all(): page.placeholders.remove(placeholder) placeholder.pk += 1000 placeholder.save() page.placeholders.add(placeholder) page.reload() for placeholder in page.placeholders.all(): add_plugin(placeholder, "TextPlugin", "en", body="body", id=placeholder.pk) with SettingsOverride(USE_THOUSAND_SEPARATOR=True, USE_L10N=True): # Superuser user = self.get_superuser() self.client.login(username=getattr(user, get_user_model().USERNAME_FIELD), password=getattr(user, get_user_model().USERNAME_FIELD)) response = self.client.get("/en/?%s" % get_cms_setting('CMS_TOOLBAR_URL__EDIT_ON')) for placeholder in page.placeholders.all(): self.assertContains( response, "'placeholder_id': '%s'" % placeholder.pk) self.assertNotContains( response, "'placeholder_id': '%s'" % format( placeholder.pk, ".", grouping=3, thousand_sep=",")) self.assertNotContains( response, "'plugin_id': '%s'" % format( placeholder.pk, ".", grouping=3, thousand_sep=",")) self.assertNotContains( response, "'clipboard': '%s'" % format( response.context['request'].toolbar.clipboard.pk, ".", grouping=3, thousand_sep=","))
def test_section(self): heading_model = add_plugin(self.placeholder, HeadingPlugin, 'en', target=self.column_model) self.assertIsInstance(heading_model, CascadeElement) heading_plugin = heading_model.get_plugin_class_instance(self.admin_site) self.assertIsInstance(heading_plugin, HeadingPlugin) ModelForm = heading_plugin.get_form(self.request, heading_model) post_data = QueryDict('', mutable=True) post_data.update(tag_type='h2', content="Hello", element_id='foo') form = ModelForm(post_data, None, instance=heading_model) html = form.as_p() needle = '<input id="id_glossary_element_id" name="element_id" type="text" value="foo" />' self.assertInHTML(needle, html) self.assertTrue(form.is_valid()) heading_plugin.save_model(self.request, heading_model, form, False) # check identifier html = heading_plugin.get_identifier(heading_model) expected = '<code>h2</code>: Hello <code>id="foo"</code>' self.assertHTMLEqual(html, expected) # render the Container Plugin with the Heading Plgin as a child self.plugin_list.append(heading_model) build_plugin_tree(self.plugin_list) # context = get_request_context(self.request) # html = heading_model.render_plugin(context) html = self.get_html(heading_model, self.get_request_context()) expected = '<h2 id="foo">Hello</h2>' self.assertHTMLEqual(html, expected) # add another heading model with the same id heading_model = add_plugin(self.placeholder, HeadingPlugin, 'en', target=self.column_model) form = ModelForm(post_data, None, instance=heading_model) self.assertFalse(form.is_valid()) expected = '<ul class="errorlist"><li>glossary<ul class="errorlist"><li>The element ID 'foo' is not unique for this page.</li></ul></li></ul>' self.assertHTMLEqual(str(form.errors), expected)
def test_revert_contents(self): user = self.get_superuser() page = create_page("Page", "nav_playground.html", "en", published=True, created_by=user) placeholder = page.placeholders.get(slot=u"body") deleted_plugin = add_plugin(placeholder, u"TextPlugin", u"en", body="Deleted content") text_plugin = add_plugin(placeholder, u"TextPlugin", u"en", body="Public content") page.publish() # Modify and delete plugins text_plugin.body = "<p>Draft content</p>" text_plugin.save() deleted_plugin.delete() self.assertEquals(CMSPlugin.objects.count(), 3) # Now let's revert and restore page.revert() self.assertEquals(page.publisher_state, Page.PUBLISHER_STATE_DEFAULT) self.assertEquals(page.pagemoderatorstate_set.count(), 0) self.assertEquals(CMSPlugin.objects.count(), 4) plugins = CMSPlugin.objects.filter(placeholder__page=page) self.assertEquals(plugins.count(), 2) plugins = [plugin.get_plugin_instance()[0] for plugin in plugins] self.assertEquals(plugins[0].body, "Deleted content") self.assertEquals(plugins[1].body, "Public content")
def test_show_placeholder_lang_parameter(self): from django.core.cache import cache cache.clear() page = create_page('Test', 'col_two.html', 'en') create_title('fr', 'Fr Test', page) placeholder = page.placeholders.all()[0] add_plugin(placeholder, TextPlugin, 'en', body='<b>En Test</b>') add_plugin(placeholder, TextPlugin, 'fr', body='<b>Fr Test</b>') request = RequestFactory().get('/') request.user = AnonymousUser() request.current_page = page template = "{% load cms_tags sekizai_tags %}{% show_placeholder slot page 'en' 1 %}{% render_block 'js' %}" output = self.render_template_obj(template, {'page': page, 'slot': placeholder.slot}, request) self.assertIn('<b>En Test</b>', output) template = "{% load cms_tags sekizai_tags %}{% show_placeholder slot page 'fr' 1 %}{% render_block 'js' %}" output = self.render_template_obj(template, {'page': page, 'slot': placeholder.slot}, request) self.assertIn('<b>Fr Test</b>', output) # Cache is now primed for both languages template = "{% load cms_tags sekizai_tags %}{% show_placeholder slot page 'en' 1 %}{% render_block 'js' %}" output = self.render_template_obj(template, {'page': page, 'slot': placeholder.slot}, request) self.assertIn('<b>En Test</b>', output) template = "{% load cms_tags sekizai_tags %}{% show_placeholder slot page 'fr' 1 %}{% render_block 'js' %}" output = self.render_template_obj(template, {'page': page, 'slot': placeholder.slot}, request) self.assertIn('<b>Fr Test</b>', output)
def test_placeholder_render_ghost_plugin(self): """ Tests a placeholder won't render a ghost plugin. """ page_en = create_page('page_en', 'col_two.html', 'en') placeholder_en = page_en.placeholders.get(slot='col_left') CMSPlugin.objects.create( language='en', plugin_type='LinkPlugin', position=1, placeholder=placeholder_en, parent=None, ) add_plugin( placeholder_en, "LinkPlugin", "en", name='name', url='http://example.com/', ) context_en = SekizaiContext() context_en['request'] = self.get_request(language="en", page=page_en) content_en = _render_placeholder(placeholder_en, context_en) self.assertEqual(content_en.strip(), '<a href="http://example.com/" >name</a>')
def test_cache_invalidation(self): # Ensure that we're testing in an environment WITHOUT the MW cache... exclude = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware' ] overrides = dict() if getattr(settings, 'MIDDLEWARE', None): overrides['MIDDLEWARE'] = [mw for mw in settings.MIDDLEWARE if mw not in exclude] else: overrides['MIDDLEWARE_CLASSES'] = [mw for mw in settings.MIDDLEWARE_CLASSES if mw not in exclude] with self.settings(**overrides): # Silly to do these tests if this setting isn't True page_cache_setting = get_cms_setting('PAGE_CACHE') self.assertTrue(page_cache_setting) page1 = create_page('test page 1', 'nav_playground.html', 'en', published=True) placeholder = page1.placeholders.get(slot="body") add_plugin(placeholder, "TextPlugin", 'en', body="First content") page1.publish('en') response = self.client.get('/en/') self.assertContains(response, 'First content') response = self.client.get('/en/') self.assertContains(response, 'First content') add_plugin(placeholder, "TextPlugin", 'en', body="Second content") page1.publish('en') response = self.client.get('/en/') self.assertContains(response, 'Second content')
def test_table_name_patching(self): """ This tests the plugin models patching when publishing from the command line """ User = get_user_model() User.objects.create_superuser('djangocms', '*****@*****.**', '123456') create_page("The page!", "nav_playground.html", "en", published=True) draft = Page.objects.drafts()[0] draft.reverse_id = 'a_test' # we have to change *something* draft.save() add_plugin(draft.placeholders.get(slot=u"body"), u"TextPlugin", u"en", body="Test content") draft.publish('en') add_plugin(draft.placeholders.get(slot=u"body"), u"TextPlugin", u"en", body="Test content") # Manually undoing table name patching Text._meta.db_table = 'djangocms_text_ckeditor_text' plugin_pool.patched = False with disable_logger(log): call_command('cms', 'moderator', 'on') # Sanity check the database (we should have one draft and one public) not_drafts = len(Page.objects.filter(publisher_is_draft=False)) drafts = len(Page.objects.filter(publisher_is_draft=True)) self.assertEqual(not_drafts, 1) self.assertEqual(drafts, 1)
def test_cached_show_placeholder_sekizai(self): from django.core.cache import cache cache.clear() from cms.test_utils import project template_dir = os.path.join(os.path.dirname(project.__file__), 'templates', 'alt_plugin_templates', 'show_placeholder') page = create_page('Test', 'col_two.html', 'en') placeholder = page.placeholders.all()[0] add_plugin(placeholder, TextPlugin, 'en', body='HIDDEN') request = RequestFactory().get('/') request.user = self.get_staff_user_with_no_permissions() request.current_page = page if DJANGO_1_7: override = {'TEMPLATE_DIRS': [template_dir], 'CMS_TEMPLATES': []} else: override = {'TEMPLATES': deepcopy(settings.TEMPLATES)} override['TEMPLATES'][0]['DIRS'] = [template_dir] with self.settings(**override): template = Template( "{% load cms_tags sekizai_tags %}{% show_placeholder slot page 'en' 1 %}{% render_block 'js' %}") context = RequestContext(request, {'page': page, 'slot': placeholder.slot}) output = template.render(context) self.assertIn('JAVASCRIPT', output) context = RequestContext(request, {'page': page, 'slot': placeholder.slot}) output = template.render(context) self.assertIn('JAVASCRIPT', output)
def test_render_textplugin(self): # Setup page = create_page("render test", "nav_playground.html", "en") ph = page.placeholders.get(slot="body") text_plugin = add_plugin(ph, "TextPlugin", "en", body="Hello World") link_plugins = [] for i in range(0, 10): link_plugins.append(add_plugin(ph, "LinkPlugin", "en", target=text_plugin, name="A Link %d" % i, url="http://django-cms.org")) text_plugin.text.body += '<img src="/static/cms/images/plugins/link.png" alt="Link - %s" id="plugin_obj_%d" title="Link - %s" />' % ( link_plugins[-1].name, link_plugins[-1].pk, link_plugins[-1].name, ) text_plugin.save() txt = text_plugin.text ph = Placeholder.objects.get(pk=ph.pk) with self.assertNumQueries(2): # 1 query for the CMSPlugin objects, # 1 query for each type of child object (1 in this case, all are Link plugins) txt.body = plugin_tags_to_admin_html( '\n'.join(["{{ plugin_object %d }}" % l.cmsplugin_ptr_id for l in link_plugins])) txt.save() text_plugin = self.reload(text_plugin) with self.assertNumQueries(2): rendered = text_plugin.render_plugin(placeholder=ph) for i in range(0, 10): self.assertTrue('A Link %d' % i in rendered)
def save(self, commit=True): article = super(CreateNewsBlogArticleForm, self).save(commit=False) # Set owner to current user article.owner = self.user # If 'content' field has value, create a TextPlugin with same and add # it to the PlaceholderField content = clean_html(self.cleaned_data.get('content', ''), False) if content and permissions.has_plugin_permission( self.user, 'TextPlugin', 'add'): # If the article has not been saved, then there will be no # Placeholder set-up for this article yet, so, ensure we have saved # first. if not article.pk: article.save() if article and article.content: add_plugin( placeholder=article.content, plugin_type='TextPlugin', language=self.language_code, body=content, ) with transaction.atomic(): with create_revision(): article.save() if self.user: set_user(self.user) set_comment(ugettext("Initial version.")) return article
def test_plugins_discarded_with_language_fallback(self): """ Tests side effect of language fallback: if fallback enabled placeholder existed, it discards all other existing plugins """ page_en = create_page('page_en', 'col_two.html', 'en') create_title("de", "page_de", page_en) placeholder_sidebar_en = page_en.placeholders.get(slot='col_sidebar') placeholder_en = page_en.placeholders.get(slot='col_left') add_plugin(placeholder_sidebar_en, TextPlugin, 'en', body='en body') context_en = SekizaiContext() context_en['request'] = self.get_request(language="en", page=page_en) conf = { 'col_left': { 'language_fallback': True, }, } with self.settings(CMS_PLACEHOLDER_CONF=conf): # call assign plugins first, as this is what is done in real cms life # for all placeholders in a page at once assign_plugins(context_en['request'], [placeholder_sidebar_en, placeholder_en], 'col_two.html') # if the normal, non fallback enabled placeholder still has content content_en = _render_placeholder(placeholder_sidebar_en, context_en) self.assertRegexpMatches(content_en, "^en body$") # remove the cached plugins instances del(placeholder_sidebar_en._plugins_cache) cache.clear()
def test_plugin_latest(self): pages = self.get_pages() posts = self.get_posts() posts[0].tags.add('tag 1') posts[0].publish = True posts[0].save() ph = pages[0].placeholders.get(slot='content') plugin = add_plugin(ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) tag = Tag.objects.get(slug='tag-1') plugin.tags.add(tag) context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) rendered = plugin.render_plugin(context, ph) try: self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-1') > -1) except AssertionError: self.assertTrue(rendered.find('cms-plugin-djangocms_blog-post-abstract-1') > -1) self.assertTrue(rendered.find(reverse('djangocms_blog:posts-tagged', kwargs={'tag': tag.slug})) > -1) self.assertTrue(rendered.find('<p>first line</p>') > -1) self.assertTrue(rendered.find('<article id="post-first-post"') > -1) self.assertTrue(rendered.find(posts[0].get_absolute_url()) > -1) category_2 = BlogCategory.objects.create(name='category 2', app_config=self.app_config_1) category_2.set_current_language('it', initialize=True) category_2.name = 'categoria 2' category_2.save() category_2.set_current_language('en') posts[1].categories.add(category_2) plugin = add_plugin(ph, 'BlogLatestEntriesPlugin', language='en', app_config=self.app_config_1) plugin.categories.add(category_2) context = self.get_plugin_context(pages[0], 'en', plugin, edit=True) rendered = plugin.render_plugin(context, ph) try: self.assertTrue(rendered.find('cms_plugin-djangocms_blog-post-abstract-2') > -1) except AssertionError: self.assertTrue(rendered.find('cms-plugin-djangocms_blog-post-abstract-2') > -1) self.assertTrue(rendered.find(reverse('djangocms_blog:posts-category', kwargs={'category': category_2.slug})) > -1) self.assertTrue(rendered.find('<p>second post first line</p>') > -1) self.assertTrue(rendered.find('<article id="post-second-post"') > -1) self.assertTrue(rendered.find(posts[1].get_absolute_url()) > -1) # Checking copy relations ph = pages[0].placeholders.get(slot='content') original = ph.get_plugins('en') pages[0].publish('en') published = pages[0].get_public_object() ph = published.placeholders.get(slot='content') new = ph.get_plugins('en') self.assertNotEqual(original, new) casted_tags, __ = new[0].get_plugin_instance() casted_categories, __ = new[1].get_plugin_instance() self.assertEqual(casted_tags.tags.count(), 1) self.assertEqual(casted_tags.categories.count(), 0) self.assertEqual(casted_categories.tags.count(), 0) self.assertEqual(casted_categories.categories.count(), 1)
def test_placeholder_content_ignores_plugins_without_bodies(self): page = create_page('Test Page', 'cms_default.html', 'en') blurb = page.placeholders.get(slot='blurb') add_plugin(blurb, PicturePlugin, 'en') self.assertEqual(placeholder_content(page), '')
def dispatch(self, request, *args, **kwargs): # check if logged in user has already created a page try: self.page = Page.objects.get(created_by=request.user, in_navigation=True, publisher_is_draft=True, is_home = False, template=settings.PROJECT_PAGE_TEMPLATE) except: # else, create page and hook plugins to placeholders : page_name = 'home-%s' % (request.user) self.page = create_page(page_name, settings.PROJECT_PAGE_TEMPLATE, 'fr', created_by=request.user, published=True, in_navigation=True) # assign user to created page assign_user_to_page(self.page, request.user, can_add=True, can_change=True, can_change_advanced_settings=True, can_publish=True) # logo logo_ph = self.page.placeholders.get(slot='logo') add_plugin(logo_ph, 'PicturePlugin', 'fr') # project_description descr_ph = self.page.placeholders.get(slot='project_description') add_plugin(descr_ph, 'TextPlugin', 'fr', body='Cliquez pour ajouter la description du projet') # project_pictures pic_ph = self.page.placeholders.get(slot='project_pictures') add_plugin(pic_ph, 'BackgroundImagesPlugin', 'fr') # news_block news_ph = self.page.placeholders.get(slot='news_block') add_plugin(news_ph, 'CMSNewsPlugin', 'fr') # carto carto_ph = self.page.placeholders.get(slot='carto') add_plugin(carto_ph, 'CartoPlugin', 'fr') return super(CMSRedirectView, self).dispatch(request, *args, **kwargs)
def test_plugin(self): page1 = self.get_or_create_page("Page One") ph = page1.placeholders.get(slot='content') plugin = add_plugin(ph, 'QuestionListPlugin', language='en') # First test that it is initially empty request = self.get_page_request( page1, self.user, None, lang_code='en', edit=False) context = RequestContext(request, {}) rendered = plugin.render_plugin(context, ph) self.assertTrue(rendered.find(">No entry found.</p>") > -1) # Now, add a question, and test that it renders. question1 = self.reload(self.question1, "en") plugin.questions.add(question1) plugin.save() request = self.get_page_request( page1, self.user, None, lang_code='en', edit=False) context = RequestContext(request, {}) rendered = plugin.render_plugin(context, ph) self.assertTrue(rendered.find(question1.title) > -1) # Test its unicode method self.assertEqual(str(plugin), '1 question selected') # Test its copy_relations. To do this, we'll create another instance # that is empty, then copy_relations to it, and prove that it contains # questions. plugin2 = add_plugin(ph, 'QuestionListPlugin', language='en') plugin2.copy_relations(plugin) self.assertTrue(plugin.get_questions(), plugin2.get_questions())
def test_cached_show_placeholder_sekizai(self): from django.core.cache import cache cache.clear() from cms.test_utils import project User = get_user_model() template_dir = os.path.join(os.path.dirname(project.__file__), 'templates', 'alt_plugin_templates', 'show_placeholder') page = create_page('Test', 'col_two.html', 'en') placeholder = page.placeholders.all()[0] add_plugin(placeholder, TextPlugin, 'en', body='HIDDEN') request = RequestFactory().get('/') request.user = User() request.current_page = page with SettingsOverride(TEMPLATE_DIRS=[template_dir]): template = Template( "{% load cms_tags sekizai_tags %}{% show_placeholder slot page 'en' 1 %}{% render_block 'js' %}") context = RequestContext(request, {'page': page, 'slot': placeholder.slot}) output = template.render(context) self.assertIn('JAVASCRIPT', output) context = RequestContext(request, {'page': page, 'slot': placeholder.slot}) output = template.render(context) self.assertIn('JAVASCRIPT', output)
def test_global_limit_on_plugin_move(self): admin = self.get_admin() superuser = self.get_superuser() source_placeholder = Placeholder.objects.create(slot='source') target_placeholder = self.get_placeholder() data = { 'placeholder': source_placeholder, 'plugin_type': 'LinkPlugin', 'language': 'en', } plugin_1 = add_plugin(**data) plugin_2 = add_plugin(**data) plugin_3 = add_plugin(**data) with UserLoginContext(self, superuser): with SettingsOverride(CMS_PLACEHOLDER_CONF=self.placeholderconf): request = self.get_post_request({'placeholder_id': target_placeholder.pk, 'plugin_id': plugin_1.pk}) response = admin.move_plugin(request) # first self.assertEqual(response.status_code, 200) request = self.get_post_request({'placeholder_id': target_placeholder.pk, 'plugin_id': plugin_2.pk}) response = admin.move_plugin(request) # second self.assertEqual(response.status_code, 200) request = self.get_post_request({'placeholder_id': target_placeholder.pk, 'plugin_id': plugin_3.pk}) response = admin.move_plugin(request) # third self.assertEqual(response.status_code, 400) self.assertEqual(response.content, "This placeholder already has the maximum number of plugins (2).")
def save(self, commit=True): post = super(PostCreationForm, self).save(commit=False) # Set owner to current user post.author = self.user # If 'content' field has value, create a TextPlugin with same and add # it to the PlaceholderField content = self.cleaned_data.get('content', '') if content and permissions.has_plugin_permission( self.user, 'TextPlugin', 'add'): # If the post has not been saved, then there will be no # Placeholder set-up for this article yet, so, ensure we have saved # first. if not post.pk: post.save() if post and post.content: add_plugin( placeholder=post.content, plugin_type='TextPlugin', language=self.language_code, body=content, ) if commit: post.save() return post
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, u"TextPlugin", u"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(t, self.test_page, {'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 djangocms_migration(self, keep=False): # Add and old SnippetPlugin and publish it content = self.random.get() old_snippet = OldSnippet( html=content, ) old_snippet.save() api.add_plugin(self.placeholder, OldSnippetPlugin, self.language, snippet=old_snippet) self.page.publish(self.language) response = self.client.get(self.page.get_absolute_url()) self.assertContains(response, content) self.assertTrue(OldSnippet.objects.exists()) self.assertTrue(CMSPlugin.objects.filter(plugin_type='SnippetPlugin').exists()) # old plugin self.assertFalse(CMSPlugin.objects.filter(plugin_type='Snippet').exists()) # new plugin # Migrate to new snippet plugin call_command('migrate_from_djangocms_snippet', keep=keep) if keep: self.assertTrue(OldSnippet.objects.exists()) else: self.assertFalse(OldSnippet.objects.exists()) self.assertFalse(CMSPlugin.objects.filter(plugin_type='SnippetPlugin').exists()) # old plugin self.assertTrue(CMSPlugin.objects.filter(plugin_type='Snippet').exists()) # new plugin new_snippet = CMSPlugin.objects.filter(plugin_type='Snippet')[0].get_plugin_instance()[0] content = self.random.get() new_snippet.content = content new_snippet.save() self.page.publish(self.language) response = self.client.get(self.page.get_absolute_url()) self.assertContains(response, content)
def create_default_job_opening(self, translated=False, category=None): # ensure that we always start with english, since it looks # like there is some issues with handling active language # between tests cases run if category is None: category = self.default_category with override('en'): job_opening = JobOpening.objects.create( category=category, **self.default_job_values['en']) api.add_plugin( job_opening.content, 'TextPlugin', 'en', body=self.default_plugin_content['en']) # check if we need a translated job opening if translated: job_opening.create_translation( 'de', **self.default_job_values['de']) with override('de'): api.add_plugin(job_opening.content, 'TextPlugin', 'de', body=self.default_plugin_content['de']) return JobOpening.objects.language('en').get(pk=job_opening.pk)
def test_type_limit_on_plugin_move(self): admin = self.get_admin() superuser = self.get_superuser() cms_page = self.get_page() source_placeholder = cms_page.placeholders.get(slot='right-column') target_placeholder = cms_page.placeholders.get(slot='body') data = { 'placeholder': source_placeholder, 'plugin_type': 'TextPlugin', 'language': 'en', } plugin_1 = add_plugin(**data) plugin_2 = add_plugin(**data) with UserLoginContext(self, superuser): with SettingsOverride(CMS_PLACEHOLDER_CONF=self.placeholderconf): request = self.get_post_request( {'placeholder_id': target_placeholder.pk, 'plugin_id': plugin_1.pk, 'plugin_parent': ''}) response = admin.move_plugin(request) # first self.assertEqual(response.status_code, 200) request = self.get_post_request( {'placeholder_id': target_placeholder.pk, 'plugin_id': plugin_2.pk, 'plugin_parent': ''}) response = admin.move_plugin(request) # second self.assertEqual(response.status_code, 400) self.assertEqual(response.content, b"This placeholder already has the maximum number (1) of allowed Text plugins.")
def test_instant_articles(self): self.user.first_name = 'Admin' self.user.last_name = 'User' self.user.save() posts = self.get_posts() pages = self.get_pages() posts[0].tags.add('tag 1', 'tag 2', 'tag 3', 'tag 4') posts[0].categories.add(self.category_1) posts[0].author = self.user posts[0].save() add_plugin( posts[0].content, 'TextPlugin', language='en', body='<h3>Ciao</h3><p></p><p>Ciao</p>' ) with smart_override('en'): with switch_language(posts[0], 'en'): request = self.get_page_request( pages[1], self.user, path=posts[0].get_absolute_url() ) feed = FBInstantArticles() feed.namespace, feed.config = get_app_instance(request) self.assertEqual(list(feed.items()), [posts[0]]) xml = feed(request) self.assertContains(xml, '<guid>{0}</guid>'.format(posts[0].guid)) self.assertContains(xml, 'content:encoded') self.assertContains(xml, 'class="op-modified" datetime="{0}"'.format( posts[0].date_modified.strftime(FBInstantFeed.date_format) )) self.assertContains(xml, '<link rel="canonical" href="{0}"/>'.format( posts[0].get_full_url() )) # Assert text transformation self.assertContains(xml, '<h2>Ciao</h2><p>Ciao</p>') self.assertContains(xml, '<a>Admin User</a>')
def test_plugin_edit(self): page = create_page(title='pagina', template='page.html', language='en') placeholder = get_page_placeholders(page, 'en').get(slot='content') add_plugin(placeholder, 'TextPlugin', 'en', body='Lorem ipsum') page.publish('en') response = self.client.get(page.get_absolute_url('en')) self.assertContains(response, 'Lorem ipsum')
def test_copy_filled_placeholder_force_copy(self): """ If an existing title in the target language has plugins in a placeholder and the command is called with *force-copy*, the plugins are copied on top of the existing one """ site = 1 number_start_plugins = CMSPlugin.objects.all().count() # create an empty title language root_page = Page.objects.on_site(site).get_home() create_title("de", "root page de", root_page) ph = root_page.placeholders.get(slot="body") add_plugin(ph, "TextPlugin", "de", body="Hello World") root_plugins = CMSPlugin.objects.filter(placeholder=ph) text_de_orig, _ = root_plugins.get(language='de', plugin_type='TextPlugin').get_plugin_instance() out = StringIO() management.call_command( 'cms', 'copy', 'lang', '--from-lang=en', '--to-lang=de', '--force', interactive=False, stdout=out ) CMSPlugin.objects.filter(placeholder=root_page.placeholders.get(slot="body")) self.assertEqual(CMSPlugin.objects.filter(language='en').count(), number_start_plugins) # we have an existing plugin in one placeholder, so we have one more self.assertEqual(CMSPlugin.objects.filter(language='de').count(), number_start_plugins+1)
def test_table_name_patching(self): """ This tests the plugin models patching when publishing from the command line """ User = get_user_model() User.objects.create_superuser('djangocms', '*****@*****.**', '123456') create_page("The page!", "nav_playground.html", "en", published=True) draft = Page.objects.drafts()[0] draft.reverse_id = 'a_test' # we have to change *something* draft.save() add_plugin(draft.placeholders.get(slot=u"body"), u"TextPlugin", u"en", body="Test content") draft.publish('en') add_plugin(draft.placeholders.get(slot=u"body"), u"TextPlugin", u"en", body="Test content") # Manually undoing table name patching Text._meta.db_table = 'djangocms_text_ckeditor_text' plugin_pool.patched = False with StdoutOverride(): # Now we don't expect it to raise, but we need to redirect IO call_command('cms', 'publisher_publish') not_drafts = len(Page.objects.filter(publisher_is_draft=False)) drafts = len(Page.objects.filter(publisher_is_draft=True)) self.assertEqual(not_drafts, 1) self.assertEqual(drafts, 1)
def test_calendar_plugin_with_not_existing_ns(self, timezone_mock): timezone_mock.now.return_value = tz_datetime(2014, 1, 2) self.create_base_pages() new_config = EventsConfig.objects.create(namespace='new_namespace') page = api.create_page('Plugin test en', self.template, 'en', published=True, slug='plugin-test-en') api.create_title('de', 'Plugin test de', page) ph = page.placeholders.get(slot='content') api.add_plugin(ph, 'CalendarPlugin', 'en', app_config=new_config) api.add_plugin(ph, 'CalendarPlugin', 'de', app_config=new_config) page.publish('en') page.publish('de') with force_language('en'): event = Event.objects.create( title='Test event namespace', slug='test-event-namespace', start_date=tz_datetime(2014, 1, 10), publish_at=tz_datetime(2014, 1, 1), app_config=new_config ) event.create_translation( 'de', title='Test event namespace de', slug='test-event-namespace-de') for language in ('en', 'de'): page_url = page.get_absolute_url(language) response = self.client.get(page_url) self.assertEqual(response.status_code, 200)
def test_cached_show_placeholder_preview(self): from django.core.cache import cache cache.clear() page = create_page('Test', 'col_two.html', 'en', published=True) placeholder = page.placeholders.all()[0] add_plugin(placeholder, TextPlugin, 'en', body='<b>Test</b>') request = RequestFactory().get('/') user = User(username="******", password="******", is_superuser=True, is_staff=True, is_active=True) user.save() request.current_page = page.publisher_public request.user = user template = Template( "{% load cms_tags %}{% show_placeholder slot page 'en' 1 %}") context = RequestContext(request, {'page': page, 'slot': placeholder.slot}) with self.assertNumQueries(5): output = template.render(context) self.assertIn('<b>Test</b>', output) add_plugin(placeholder, TextPlugin, 'en', body='<b>Test2</b>') request = RequestFactory().get('/?preview') request.current_page = page request.user = user context = RequestContext(request, {'page': page, 'slot': placeholder.slot}) with self.assertNumQueries(5): output = template.render(context) self.assertIn('<b>Test2</b>', output)
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', published=True, slug='home') placeholders = list(page.placeholders.all()) 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() content_renderer = context['cms_content_renderer'] with self.assertNumQueries(4): for i, placeholder in enumerate(placeholders): content = 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_plugin_show_links_are_shown_if_enabled_and_apphook_page(self): with force_language('en'): app_page = self.create_apphook_page() list_plugin = api.add_plugin( placeholder=self.placeholder, plugin_type=PeoplePlugin, language='en', ) list_plugin.show_links = True list_plugin.save() self.page.publish('en') url = self.page.get_absolute_url() person_url = self.person1.get_absolute_url() # ensure that url is not the link to the home page and not app page app_page_len = len(app_page.get_absolute_url()) self.assertGreater(len(person_url), app_page_len) response = self.client.get(url, follow=True) self.assertContains(response, person_url) # ensure that url is not shown if not enabled for plugin. list_plugin.show_links = False list_plugin.save() self.page.publish('en') response = self.client.get(url, follow=True) self.assertNotContains(response, person_url)
def _create_default_plugins(placeholder, confs, parent=None): """ Auxillary function that builds all of a placeholder's default plugins at the current level and drives the recursion down the tree. Returns the plugins at the current level along with all descendants. """ plugins, descendants = [], [] addable_confs = ( conf for conf in confs if has_plugin_permission(request.user, conf['plugin_type'], 'add')) for conf in addable_confs: plugin = add_plugin(placeholder, conf['plugin_type'], lang, target=parent, **conf['values']) if 'children' in conf: args = placeholder, conf['children'], plugin descendants += _create_default_plugins(*args) plugin.notify_on_autoadd(request, conf) plugins.append(plugin) if parent: parent.notify_on_autoadd_children(request, conf, plugins) return plugins + descendants
def test_cms_plugins_large_banner_no_background_image(self): """ Instanciating this plugin with an instance but no background image should render a default image in the html. The default image is defined as background image in the CSS. """ placeholder = Placeholder.objects.create(slot="test") # Create random values for parameters with a factory large_banner = LargeBannerFactory(background_image=None) fields_list = ["title", "background_image", "logo", "logo_alt_text"] model_instance = add_plugin( placeholder, LargeBannerPlugin, "en", **{field: getattr(large_banner, field) for field in fields_list}) # Get the generated html renderer = ContentRenderer(request=RequestFactory()) html = renderer.render_plugin(model_instance, {}) # Check that all expected elements are in the html self.assertIn('class="large-banner"', html) self.assertFalse('class="large-banner__background"' in html)
def test_show_ungrouped(self): """ """ the_bradys = Group.objects.create(name="The Bradys") alice = Person.objects.create(name="Alice") bobby = Person.objects.create(name="Bobby") cindy = Person.objects.create(name="Cindy") # Alice is the housekeeper, not a real Brady. bobby.groups.add(the_bradys) cindy.groups.add(the_bradys) # Now, add a new plugin where ungrouped people are shown plugin = api.add_plugin(self.placeholder, PeoplePlugin, self.language) plugin.people = Person.objects.all() plugin.group_by_group = True plugin.show_ungrouped = True plugin.save() self.page.publish(self.language) url = self.page.get_absolute_url() response = self.client.get(url, follow=True) self.assertContains(response, bobby.name) self.assertContains(response, cindy.name) self.assertContains(response, alice.name)
def forwards(apps, schema_editor): html_parser = HTMLParser() for cascade_element in CascadeElement.objects.all(): if cascade_element.plugin_type != 'CarouselSlidePlugin': continue caption = cascade_element.glossary.get('caption') if not caption: continue text_element = add_plugin(cascade_element.placeholder, TextPlugin, cascade_element.language, target=cascade_element) old_body = html_parser.unescape(caption) new_body, count = _replace_text_body( old_body, input_pattern= r'<img ([^>]*)\bid="plugin_obj_(?P<pk>\d+)"([^>]*)/?>', output_tag='<cms-plugin {}></cms-plugin>', id_format='id="{}"', ) text_element.body = new_body text_element.save() # TODO: need to be re-tested if False and count > 0: for link_element in CMSPlugin.objects.filter( parent_id__in=(cascade_element.id, cascade_element.parent_id), plugin_type='TextLinkPlugin'): # print("Move Link {} from {} -> {}".format(link_element.id, link_element.parent_id, text_element.id)) link_element.move(text_element, pos='last-child') link_element.save()
def test_render_plugin_no_context(self): placeholder = Placeholder.objects.create(slot='test') plugin = add_plugin(placeholder, TextPlugin, 'en', body='Test') parser = DummyParser() tokens = DummyTokens(plugin) tag = RenderPlugin(parser, tokens) superuser = self.get_superuser() request = RequestFactory().get('/') request.current_page = None request.user = superuser request.session = {} request.toolbar = CMSToolbar(request) request.toolbar.edit_mode = True context = SekizaiContext({ 'request': request, 'cms_content_renderer': request.toolbar.content_renderer, }) output = tag.render(context) self.assertEqual( output, '<template class="cms-plugin cms-plugin-start cms-plugin-{0}"></template>Test<template class="cms-plugin cms-plugin-end cms-plugin-{0}"></template>'.format( plugin.pk ) )
def test_cms_plugins_blogpost_default_variant(self): """ If the variant is specified on the blogpost plugin and also as variant variable in the context of its container, the instance variable should be used. """ # Create an blogpost blogpost = BlogPostFactory(page_title="public title", should_publish=True) blogpost_page = blogpost.extended_object # Create a page to add the plugin to page = create_i18n_page("A page") placeholder = page.placeholders.get(slot="maincontent") # Add blogpost plugin with default template model_instance = add_plugin(placeholder, BlogPostPlugin, "en", page=blogpost_page, variant="small") # Get generated html request = RequestFactory() request.current_page = page request.path_info = "/en/my-path/" request.user = AnonymousUser() context = { "current_page": page, "blogpost_variant": "xxl", "request": request } renderer = ContentRenderer(request=request) html = renderer.render_plugin(model_instance, context) self.assertIn("blogpost-small", html)
def test_add_plugin_alias(self): page_en = api.create_page("PluginOrderPage", "col_two.html", "en", slug="page1", published=True, in_navigation=True) ph_en = page_en.placeholders.get(slot="col_left") text_plugin_1 = api.add_plugin(ph_en, "TextPlugin", "en", body="I'm the first") with self.login_user_context(self.get_superuser()): response = self.client.post(admin_reverse('cms_create_alias'), data={'plugin_id': text_plugin_1.pk}) self.assertEqual(response.status_code, 200) response = self.client.post(admin_reverse('cms_create_alias'), data={'placeholder_id': ph_en.pk}) self.assertEqual(response.status_code, 200) response = self.client.post(admin_reverse('cms_create_alias')) self.assertEqual(response.status_code, 400) response = self.client.post(admin_reverse('cms_create_alias'), data={'plugin_id': 20000}) self.assertEqual(response.status_code, 400) response = self.client.post(admin_reverse('cms_create_alias'), data={'placeholder_id': 20000}) self.assertEqual(response.status_code, 400) response = self.client.post(admin_reverse('cms_create_alias'), data={'plugin_id': text_plugin_1.pk}) self.assertEqual(response.status_code, 403) instance = AliasPluginModel.objects.all()[0] admin = AliasPlugin() request = self.get_request("/") context = Context({'request': request}) admin.render(context, instance, ph_en) self.assertEqual(context['content'], "I'm the first")
def test_edit(self): """ Test editing a *PAGE* plugin """ page, placeholder, superuser, staff = self.get_data() # create the plugin using a superuser plugin = add_plugin(placeholder, 'TextPlugin', 'en', body='body') plugin_data = { 'plugin_id': plugin.pk, 'body': 'newbody', } self.assertEqual(plugin.body, 'body') # check the body is as expected. # log the user out, try to edit the plugin self.client.logout() endpoint = self.get_change_plugin_uri(plugin) response = self.client.post(endpoint, plugin_data) # since the user is not logged in, they should be prompted to log in. self.assertEqual(response.status_code, 302) querystring = QueryDict('', mutable=True) querystring['next'] = endpoint expected_url = '/{lang}/admin/login/?{next}'.format( lang=settings.LANGUAGES[0][0], next=querystring.urlencode(safe='/')) self.assertRedirects(response, expected_url) plugin = self.reload(plugin) self.assertEqual(plugin.body, 'body') # now log a staff user without permissions in and do the same as above. self.client.login(username=getattr(staff, get_user_model().USERNAME_FIELD), password=getattr(staff, get_user_model().USERNAME_FIELD)) response = self.client.post(endpoint, plugin_data) # the user is logged in and the security check fails, so it should 403. self.assertEqual(response.status_code, 403) plugin = self.reload(plugin) self.assertEqual(plugin.body, 'body')
def test_render_alias_dont_render_draft_aliases(self): alias = self._create_alias([self.plugin], published=False) alias_plugin = add_plugin( self.placeholder, Alias, language=self.language, alias=alias, ) output = self.render_template_obj( self.alias_template, {'plugin': alias_plugin}, self.get_request('/'), ) self.assertEqual(output, '') self._publish(alias) alias.clear_cache() output = self.render_template_obj( self.alias_template, {'plugin': alias_plugin}, self.get_request('/'), ) self.assertEqual(output, 'test')
def test_get_plugin_template(self): page = create_page( title="home", template="page.html", language="en", ) instance = add_plugin( placeholder=page.placeholders.get(slot="content"), plugin_type=Bootstrap4CarouselPlugin.__name__, language="en", ) template = get_plugin_template( instance, "carousel", "carousel", CAROUSEL_TEMPLATE_CHOICES, ) self.assertEqual(template, "djangocms_bootstrap4/carousel/default/carousel.html") # trigger default template template = get_plugin_template( instance, "does_not", "exist", CAROUSEL_TEMPLATE_CHOICES, ) self.assertEqual(template, "djangocms_bootstrap4/does_not/default/exist.html") # cleanup page.delete()
def test_action_token_per_session(self): # Assert that a cancel token for the same plugin # is different per user session. simple_page = create_page('test page', 'page.html', u'en') simple_placeholder = simple_page.placeholders.get(slot='content') text_plugin = add_plugin( simple_placeholder, "TextPlugin", "en", body="I'm the first", ) text_plugin_class = text_plugin.get_plugin_class_instance() with self.login_user_context(self.get_superuser()): request = self.get_request() action_token_1 = text_plugin_class.get_action_token(request, text_plugin) with self.login_user_context(self.get_superuser()): request = self.get_request() action_token_2 = text_plugin_class.get_action_token(request, text_plugin) self.assertNotEqual(action_token_1, action_token_2)
def test_plugin_author(self): post1 = self._get_post(self._post_data[0]['en']) post2 = self._get_post(self._post_data[1]['en']) request = self.get_page_request('/', AnonymousUser(), r'/en/blog/', edit=False) plugin = add_plugin(post1.content, 'BlogAuthorPostsPlugin', language='en', app_config=self.app_config_1) plugin.authors.add(self.user) self.assertEqual(len(plugin.get_posts(request)), 0) self.assertEqual(plugin.get_authors()[0].count, 0) post1.publish = True post1.save() self.assertEqual(len(plugin.get_posts(request)), 1) self.assertEqual(plugin.get_authors()[0].count, 1) post2.publish = True post2.save() self.assertEqual(len(plugin.get_posts(request)), 2) self.assertEqual(plugin.get_authors()[0].count, 2)
def test_required_form_plugin(self): # create a page populated with Cascade elements used for checkout placeholder = self.checkout_page.placeholders.get(slot='Main Content') # add shipping address to checkout page form_element = add_plugin(placeholder, RequiredFormFieldsPlugin, 'en', target=self.column_element) form_element.glossary = {'render_type': 'form'} form_element.save() self.checkout_page.publish('en') url = self.checkout_page.get_absolute_url() response = self.client.get(url) self.assertEquals(response.status_code, 200) soup = BeautifulSoup(response.content, 'html.parser') labels = soup.find_all('label') expected = '*\xa0These fields are required' for label in labels: if label.string == expected: break else: self.fail("Expected element: <label>{}</label>".format(expected))
def test_can_render_a_simple_tree_of_cms_pages_that_are_not_in_navigation( self): # Setup placeholder = Placeholder.objects.create(slot='test') model_instance = add_plugin( placeholder, cms_plugins.HtmlSitemapPlugin, 'en', in_navigation=False, ) # Run html = self.render_plugin(model_instance) html = strip_spaces_between_tags(html) # Check assert html.strip() == strip_spaces_between_tags(""" <div id="sitemap"> <ul> <li> <a href="/depth-2-page-2/" title="Depth 2 page 2">Depth 2 page 2</a> <ul> <li><a href="/depth-2-page-2/depth-3-page-1/" title="Depth 3 page 1">Depth 3 page 1</a></li> <li><a href="/depth-2-page-2/depth-3-page-2/" title="Depth 3 page 2">Depth 3 page 2</a></li> </ul> </li> <li><a href="/depth-2-page-3/" title="Depth 2 page 3">Depth 2 page 3</a></li> <li> <a href="/depth-2-page-4/" title="Depth 2 page 4">Depth 2 page 4</a> <ul> <li><a href="/depth-2-page-4/depth-3-page-3/" title="Depth 3 page 3">Depth 3 page 3</a></li> </ul> </li> </ul> </div> """).strip()
def test_render_plugin(self): from django.conf import settings if 'cms' not in settings.INSTALLED_APPS: raise unittest.SkipTest( 'django CMS not available, skipping test') from cms.api import add_plugin sample_text = '\nfake text\nen\nPage title\n\n' pages = self.get_pages() public = pages[0].get_public_object() placeholder = pages[0].placeholders.get(slot='content') plugin = add_plugin(placeholder=placeholder, plugin_type='FakePlugin', language='en') pages[0].publish('en') rendered_2 = self.render_plugin(public, 'en', plugin) if CMS_34: context = self.get_plugin_context(pages[0], 'en', plugin, edit=False) rendered_1 = plugin.render_plugin(context, placeholder) self.assertEqual(rendered_2, rendered_1) self.assertEqual(rendered_2, sample_text)
def test_plugin_with_inlines(self): page = create_page('page', 'page.html', 'en', published=True).publisher_public placeholder = page.placeholders.get(slot='content') plugin = add_plugin(placeholder, 'SliderWithInlinesPlugin', 'en', name='Slider') instance, plugin_model = plugin.get_plugin_instance() image1 = SimpleUploadedFile("image.jpg", b"content") image2 = SimpleUploadedFile("image.jpg", b"content") slide_1 = Slide.objects.create(title='slide 1', image=image1, slider=instance) slide_2 = Slide.objects.create(title='slide 2', image=image2, slider=instance) url = reverse('api:plugin-detail', kwargs={'pk': plugin.id}) response = self.client.get(url, format='json') self.assertEqual(len(response.data['inlines']), 1) self.assertEqual(len(response.data['inlines']['slides']), 2) self.assertIn(slide_1.image.url, response.data['inlines']['slides'][0]['image'])
def test_plugin_with_children(self): page = create_page('page', 'page.html', 'en', published=True) placeholder = page.placeholders.get(slot='content') columns = add_plugin(placeholder, "MultiColumnPlugin", "en") column_1 = add_plugin(placeholder, "ColumnPlugin", "en", target=columns, width='10%') column_2 = add_plugin(placeholder, "ColumnPlugin", "en", target=columns, width='30%') text_plugin_1_1 = add_plugin(placeholder, "TextPlugin", "en", target=column_1, body="I'm the first") text_plugin_1_2 = add_plugin(placeholder, "TextPlugin", "en", target=column_1, body="I'm the second") text_plugin_2_1 = add_plugin(placeholder, "TextPlugin", "en", target=column_2, body="I'm the third") url = reverse('api:plugin-detail', kwargs={'pk': columns.id}) response = self.client.get(url, format='json') data = response.data self.assertIn('children', data) self.assertEqual(len(data['children']), 2) self.assertEqual(len(data['children'][0]['children']), 2) self.assertEqual(data['children'][0]['children'][0]['body'], text_plugin_1_1.body) self.assertEqual(data['children'][0]['children'][1]['body'], text_plugin_1_2.body) self.assertEqual(len(data['children'][1]['children']), 1) self.assertEqual(data['children'][1]['children'][0]['body'], text_plugin_2_1.body)
def TTLCacheExpirationPlugin(self): page1 = create_page('test page 1', 'nav_playground.html', 'en', published=True) placeholder1 = page1.placeholders.filter(slot="body")[0] placeholder2 = page1.placeholders.filter(slot="right-column")[0] plugin_pool.register_plugin(TTLCacheExpirationPlugin) add_plugin(placeholder1, "TextPlugin", 'en', body="English") add_plugin(placeholder2, "TextPlugin", 'en', body="Deutsch") # Add *CacheExpirationPlugins, one expires in 50s, the other in 40s. # The page should expire in the least of these, or 40s. add_plugin(placeholder1, "TTLCacheExpirationPlugin", 'en') # Ensure that we're testing in an environment WITHOUT the MW cache, as # we are testing the internal page cache, not the MW cache. exclude = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.CacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ] overrides = dict() if getattr(settings, 'MIDDLEWARE', None): overrides['MIDDLEWARE'] = [ mw for mw in settings.MIDDLEWARE if mw not in exclude ] else: overrides['MIDDLEWARE_CLASSES'] = [ mw for mw in settings.MIDDLEWARE_CLASSES if mw not in exclude ] with self.settings(**overrides): page1.publish('en') request = self.get_request('/en/') request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(FuzzyInt(14, 25)): # was 14, 24 response = self.client.get('/en/') self.assertTrue('max-age=50' in response['Cache-Control'], response['Cache-Control']) plugin_pool.unregister_plugin(TTLCacheExpirationPlugin)
def test_dual_legacy_cache_plugins(self): page1 = create_page('test page 1', 'nav_playground.html', 'en', published=True) page1_url = page1.get_absolute_url() placeholder1 = page1.placeholders.filter(slot="body")[0] placeholder2 = page1.placeholders.filter(slot="right-column")[0] plugin_pool.register_plugin(LegacyCachePlugin) add_plugin(placeholder1, "TextPlugin", 'en', body="English") add_plugin(placeholder2, "TextPlugin", 'en', body="Deutsch") # Adds a no-cache plugin. In older versions of the CMS, this would # prevent the page from caching in, but since this plugin also defines # get_cache_expiration() it is ignored. add_plugin(placeholder1, "LegacyCachePlugin", 'en') # Ensure that we're testing in an environment WITHOUT the MW cache, as # we are testing the internal page cache, not the MW cache. exclude = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.CacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ] overrides = dict() if getattr(settings, 'MIDDLEWARE', None): overrides['MIDDLEWARE'] = [ mw for mw in settings.MIDDLEWARE if mw not in exclude ] else: overrides['MIDDLEWARE_CLASSES'] = [ mw for mw in settings.MIDDLEWARE_CLASSES if mw not in exclude ] with self.settings(**overrides): page1.publish('en') request = self.get_request(page1_url) request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(FuzzyInt(14, 25)): response = self.client.get(page1_url) self.assertTrue('no-cache' not in response['Cache-Control']) plugin_pool.unregister_plugin(LegacyCachePlugin)
def test_inter_placeholder_plugin_move(self): ex = TwoPlaceholderExample(char_1='one', char_2='two', char_3='tree', char_4='four') ex.save() ph1 = ex.placeholder_1 ph2 = ex.placeholder_2 ph1_pl1 = add_plugin(ph1, TextPlugin, 'en', body='ph1 plugin1').cmsplugin_ptr ph1_pl2 = add_plugin(ph1, TextPlugin, 'en', body='ph1 plugin2').cmsplugin_ptr ph1_pl3 = add_plugin(ph1, TextPlugin, 'en', body='ph1 plugin3').cmsplugin_ptr ph2_pl1 = add_plugin(ph2, TextPlugin, 'en', body='ph2 plugin1').cmsplugin_ptr ph2_pl2 = add_plugin(ph2, TextPlugin, 'en', body='ph2 plugin2').cmsplugin_ptr ph2_pl3 = add_plugin(ph2, TextPlugin, 'en', body='ph2 plugin3').cmsplugin_ptr data = { 'placeholder_id': str(ph2.pk), 'plugin_id': str(ph1_pl2.pk), 'plugin_order[]': [str(p.pk) for p in [ph2_pl3, ph2_pl1, ph2_pl2, ph1_pl2]] } endpoint = self.get_move_plugin_uri(ph1_pl2, container=TwoPlaceholderExample) response = self.client.post(endpoint, data) self.assertEqual(response.status_code, 200) self.assertEqual([ph1_pl1, ph1_pl3], list(ph1.cmsplugin_set.order_by('position'))) self.assertEqual([ ph2_pl3, ph2_pl1, ph2_pl2, ph1_pl2, ], list(ph2.cmsplugin_set.order_by('position')))
def test_datetime_cache_plugin(self): page1 = create_page('test page 1', 'nav_playground.html', 'en', published=True) page1_url = page1.get_absolute_url() placeholder1 = page1.placeholders.filter(slot="body")[0] placeholder2 = page1.placeholders.filter(slot="right-column")[0] try: plugin_pool.register_plugin(DateTimeCacheExpirationPlugin) except PluginAlreadyRegistered: pass add_plugin(placeholder1, "TextPlugin", 'en', body="English") add_plugin(placeholder2, "TextPlugin", 'en', body="Deutsch") # Add *CacheExpirationPlugins, one expires in 50s, the other in 40s. # The page should expire in the least of these, or 40s. add_plugin(placeholder1, "DateTimeCacheExpirationPlugin", 'en') # Ensure that we're testing in an environment WITHOUT the MW cache, as # we are testing the internal page cache, not the MW cache. exclude = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.CacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ] overrides = { 'MIDDLEWARE': [mw for mw in settings.MIDDLEWARE if mw not in exclude] } with self.settings(**overrides): page1.publish('en') request = self.get_request(page1_url) request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(FuzzyInt(14, 25)): # was 14, 24 response = self.client.get(page1_url) self.assertTrue('max-age=40' in response['Cache-Control'], response['Cache-Control']) plugin_pool.unregister_plugin(DateTimeCacheExpirationPlugin)
def test_alias_recursion(self): page_en = api.create_page( "Alias plugin", "col_two.html", "en", slug="page1", published=True, in_navigation=True, ) ph_1_en = page_en.placeholders.get(slot="col_left") ph_2_en = page_en.placeholders.get(slot="col_sidebar") api.add_plugin(ph_1_en, 'StylePlugin', 'en', tag_type='div', class_name='info') api.add_plugin(ph_1_en, 'AliasPlugin', 'en', alias_placeholder=ph_2_en) api.add_plugin(ph_2_en, 'AliasPlugin', 'en', alias_placeholder=ph_1_en) with self.login_user_context(self.get_superuser()): response = self.client.get(page_en.get_absolute_url() + '?edit') self.assertEqual(response.status_code, 200) self.assertContains(response, '<div class="info">', html=True)
def test_check_plugin_instances(self): self.assertCheck(True, warnings=0, errors=0 ) placeholder = Placeholder.objects.create(slot="test") add_plugin(placeholder, TextPlugin, "en", body="en body") add_plugin(placeholder, TextPlugin, "en", body="en body") add_plugin(placeholder, "LinkPlugin", "en", name="A Link", external_link="https://www.django-cms.org") # create a CMSPlugin with an unsaved instance instanceless_plugin = CMSPlugin(language="en", plugin_type="TextPlugin") instanceless_plugin.save() self.assertCheck(False, warnings=0, errors=2) # create a bogus CMSPlugin to simulate one which used to exist but # is no longer installed bogus_plugin = CMSPlugin(language="en", plugin_type="BogusPlugin") bogus_plugin.save() self.assertCheck(False, warnings=0, errors=3)
def get_add_plugin_kwargs(self, page, no, placeholder, language_code, lang_name): """ Return "content" for create the plugin. Called from self.add_plugins() """ assert placeholder.slot == "content" log.info("Add drop-down menu plugin %s for %s...", lang_name, placeholder) add_plugin( placeholder=placeholder, plugin_type=plugin_anchor_menu_constants. DROP_DOWN_ANCHOR_MENU_PLUGIN_NAME, language=language_code, ) for i in range(10): title = "dummy text no. %i" % i slug = slugify(title) # log.debug("Create ancor %r with slug %s", title, slug) add_plugin( placeholder=placeholder, plugin_type=plugin_anchor_menu_constants.ANCHOR_PLUGIN_NAME, language=language_code, title=title, slug=slug, ) add_plugin( placeholder=placeholder, plugin_type=settings.CKEDITOR, language=language_code, body=self.get_dummy_text(page, i, placeholder, language_code, lang_name), ) return { "plugin_type": "TextPlugin", "body": "<p><strong>page end</strong></p>" }
def test_inter_placeholder_plugin_move(self): ex = TwoPlaceholderExample(char_1='one', char_2='two', char_3='tree', char_4='four') ex.save() ph1 = ex.placeholder_1 ph2 = ex.placeholder_2 ph1_pl1 = add_plugin(ph1, TextPlugin, 'en', body='ph1 plugin1').cmsplugin_ptr ph1_pl2 = add_plugin(ph1, TextPlugin, 'en', body='ph1 plugin2').cmsplugin_ptr ph1_pl3 = add_plugin(ph1, TextPlugin, 'en', body='ph1 plugin3').cmsplugin_ptr ph2_pl1 = add_plugin(ph2, TextPlugin, 'en', body='ph2 plugin1').cmsplugin_ptr ph2_pl2 = add_plugin(ph2, TextPlugin, 'en', body='ph2 plugin2').cmsplugin_ptr ph2_pl3 = add_plugin(ph2, TextPlugin, 'en', body='ph2 plugin3').cmsplugin_ptr response = self.client.post( reverse('admin:placeholderapp_twoplaceholderexample_move_plugin'), { 'placeholder_id': str(ph2.pk), 'plugin_id': str(ph1_pl2.pk), 'plugin_order[]': [str(p.pk) for p in [ph2_pl3, ph2_pl1, ph2_pl2, ph1_pl2]] }) self.assertEqual(response.status_code, 200) self.assertEqual([ph1_pl1, ph1_pl3], list(ph1.cmsplugin_set.order_by('position'))) self.assertEqual([ ph2_pl3, ph2_pl1, ph2_pl2, ph1_pl2, ], list(ph2.cmsplugin_set.order_by('position')))
def test_check_plugin_instances(self): self.assertCheck(True, warnings=0, errors=0 ) apps = ["cms", "menus", "sekizai", "cms.test_utils.project.sampleapp"] with SettingsOverride(INSTALLED_APPS=apps): placeholder = Placeholder.objects.create(slot="test") add_plugin(placeholder, TextPlugin, "en", body="en body") add_plugin(placeholder, TextPlugin, "en", body="en body") add_plugin(placeholder, "LinkPlugin", "en", name="A Link", url="https://www.django-cms.org") # create a CMSPlugin with an unsaved instance instanceless_plugin = CMSPlugin(language="en", plugin_type="TextPlugin") instanceless_plugin.save() self.assertCheck(False, warnings=0, errors=2) # create a bogus CMSPlugin to simulate one which used to exist but # is no longer installed bogus_plugin = CMSPlugin(language="en", plugin_type="BogusPlugin") bogus_plugin.save() self.assertCheck(False, warnings=0, errors=3)
def test_cache_page(self): # Ensure that we're testing in an environment WITHOUT the MW cache... exclude = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware' ] overrides = dict() if getattr(settings, 'MIDDLEWARE', None): overrides['MIDDLEWARE'] = [mw for mw in settings.MIDDLEWARE if mw not in exclude] else: overrides['MIDDLEWARE_CLASSES'] = [mw for mw in settings.MIDDLEWARE_CLASSES if mw not in exclude] with self.settings(**overrides): # Silly to do these tests if this setting isn't True page_cache_setting = get_cms_setting('PAGE_CACHE') self.assertTrue(page_cache_setting) # Create a test page page1 = create_page('test page 1', 'nav_playground.html', 'en', published=True) # Add some content placeholder = page1.placeholders.filter(slot="body")[0] add_plugin(placeholder, "TextPlugin", 'en', body="English") add_plugin(placeholder, "TextPlugin", 'de', body="Deutsch") # Create a request object request = self.get_request(page1.get_path(), 'en') # Ensure that user is NOT authenticated self.assertFalse(request.user.is_authenticated()) # Test that the page is initially uncached with self.assertNumQueries(FuzzyInt(1, 24)): response = self.client.get('/en/') self.assertEqual(response.status_code, 200) # # Test that subsequent requests of the same page are cached by # asserting that they require fewer queries. # with self.assertNumQueries(0): response = self.client.get('/en/') self.assertEqual(response.status_code, 200) # # Test that the cache is invalidated on unpublishing the page # old_version = _get_cache_version() page1.unpublish('en') self.assertGreater(_get_cache_version(), old_version) # # Test that this means the page is actually not cached. # page1.publish('en') with self.assertNumQueries(FuzzyInt(1, 24)): response = self.client.get('/en/') self.assertEqual(response.status_code, 200) # # Test that the above behavior is different when CMS_PAGE_CACHE is # set to False (disabled) # with self.settings(CMS_PAGE_CACHE=False): # Test that the page is initially un-cached with self.assertNumQueries(FuzzyInt(1, 20)): response = self.client.get('/en/') self.assertEqual(response.status_code, 200) # # Test that subsequent requests of the same page are still requires DB # access. # with self.assertNumQueries(FuzzyInt(1, 20)): response = self.client.get('/en/') self.assertEqual(response.status_code, 200)
def test_expiration_cache_plugins(self): """ Tests that when used in combination, the page is cached to the shortest TTL. """ page1 = create_page('test page 1', 'nav_playground.html', 'en', published=True) placeholder1 = page1.placeholders.filter(slot="body")[0] placeholder2 = page1.placeholders.filter(slot="right-column")[0] plugin_pool.register_plugin(TTLCacheExpirationPlugin) try: plugin_pool.register_plugin(DateTimeCacheExpirationPlugin) except PluginAlreadyRegistered: pass try: plugin_pool.register_plugin(NoCachePlugin) except PluginAlreadyRegistered: pass add_plugin(placeholder1, "TextPlugin", 'en', body="English") add_plugin(placeholder2, "TextPlugin", 'en', body="Deutsch") # Add *CacheExpirationPlugins, one expires in 50s, the other in 40s. # The page should expire in the least of these, or 40s. add_plugin(placeholder1, "TTLCacheExpirationPlugin", 'en') add_plugin(placeholder2, "DateTimeCacheExpirationPlugin", 'en') # Ensure that we're testing in an environment WITHOUT the MW cache, as # we are testing the internal page cache, not the MW cache. exclude = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.CacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware', ] overrides = dict() if getattr(settings, 'MIDDLEWARE', None): overrides['MIDDLEWARE'] = [mw for mw in settings.MIDDLEWARE if mw not in exclude] else: overrides['MIDDLEWARE_CLASSES'] = [mw for mw in settings.MIDDLEWARE_CLASSES if mw not in exclude] with self.settings(**overrides): page1.publish('en') request = self.get_request('/en/') request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(FuzzyInt(14, 26)): response = self.client.get('/en/') resp1 = response.content.decode('utf8').split("$$$")[1] self.assertTrue('max-age=40' in response['Cache-Control'], response['Cache-Control']) # noqa cache_control1 = response['Cache-Control'] expires1 = response['Expires'] last_modified1 = response['Last-Modified'] time.sleep(1) # This ensures that the cache has aged measurably # Request it again, this time, it comes from the cache request = self.get_request('/en/') request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(0): response = self.client.get('/en/') resp2 = response.content.decode('utf8').split("$$$")[1] # Content will be the same self.assertEqual(resp2, resp1) # Cache-Control will be different because the cache has aged self.assertNotEqual(response['Cache-Control'], cache_control1) # However, the Expires timestamp will be the same self.assertEqual(response['Expires'], expires1) # As will the Last-Modified timestamp. self.assertEqual(response['Last-Modified'], last_modified1) plugin_pool.unregister_plugin(TTLCacheExpirationPlugin) plugin_pool.unregister_plugin(DateTimeCacheExpirationPlugin) plugin_pool.unregister_plugin(NoCachePlugin)
def test_no_cache_plugin(self): page1 = create_page('test page 1', 'nav_playground.html', 'en', published=True) placeholder1 = page1.placeholders.filter(slot='body')[0] placeholder2 = page1.placeholders.filter(slot='right-column')[0] try: plugin_pool.register_plugin(NoCachePlugin) except PluginAlreadyRegistered: pass add_plugin(placeholder1, 'TextPlugin', 'en', body="English") add_plugin(placeholder2, 'TextPlugin', 'en', body="Deutsch") template = "{% load cms_tags %}{% placeholder 'body' %}{% placeholder 'right-column' %}" # Ensure that we're testing in an environment WITHOUT the MW cache, as # we are testing the internal page cache, not the MW cache. exclude = [ 'django.middleware.cache.UpdateCacheMiddleware', 'django.middleware.cache.CacheMiddleware', 'django.middleware.cache.FetchFromCacheMiddleware' ] overrides = dict() if getattr(settings, 'MIDDLEWARE', None): overrides['MIDDLEWARE'] = [mw for mw in settings.MIDDLEWARE if mw not in exclude] else: overrides['MIDDLEWARE_CLASSES'] = [mw for mw in settings.MIDDLEWARE_CLASSES if mw not in exclude] with self.settings(**overrides): # Request the page without the 'no-cache' plugin request = self.get_request('/en/') request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(FuzzyInt(18, 25)): response1 = self.client.get('/en/') content1 = response1.content # Fetch it again, it is cached. request = self.get_request('/en/') request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(0): response2 = self.client.get('/en/') content2 = response2.content self.assertEqual(content1, content2) # Once again with PAGE_CACHE=False, to prove the cache can # be disabled request = self.get_request('/en/') request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.settings(CMS_PAGE_CACHE=False): with self.assertNumQueries(FuzzyInt(5, 24)): response3 = self.client.get('/en/') content3 = response3.content self.assertEqual(content1, content3) # Add the 'no-cache' plugin add_plugin(placeholder1, "NoCachePlugin", 'en') page1.publish('en') request = self.get_request('/en/') request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(FuzzyInt(4, 6)): output = self.render_template_obj(template, {}, request) with self.assertNumQueries(FuzzyInt(14, 24)): response = self.client.get('/en/') self.assertTrue("no-cache" in response['Cache-Control']) resp1 = response.content.decode('utf8').split("$$$")[1] request = self.get_request('/en/') request.current_page = Page.objects.get(pk=page1.pk) request.toolbar = CMSToolbar(request) with self.assertNumQueries(4): output2 = self.render_template_obj(template, {}, request) with self.settings(CMS_PAGE_CACHE=False): with self.assertNumQueries(FuzzyInt(8, 13)): response = self.client.get('/en/') resp2 = response.content.decode('utf8').split("$$$")[1] self.assertNotEqual(output, output2) self.assertNotEqual(resp1, resp2) plugin_pool.unregister_plugin(NoCachePlugin)