dynamicweb/cms/tests/test_extensions.py

495 lines
22 KiB
Python

from copy import deepcopy
from django.contrib.auth import get_user_model
from django.contrib.auth.models import Permission
from django.contrib.sites.models import Site
from cms.api import create_page, create_page_content
from cms.extensions import PageContentExtension, PageExtension, extension_pool
from cms.extensions.toolbar import ExtensionToolbar
from cms.models import Page, PageContent
from cms.test_utils.project.extensionapp.models import (
MultiTablePageContentExtension,
MultiTablePageExtension,
MyPageContentExtension,
MyPageExtension,
)
from cms.test_utils.testcases import CMSTestCase
from cms.toolbar_pool import toolbar_pool
from cms.utils.urlutils import admin_reverse
class ExtensionsTestCase(CMSTestCase):
def test_register_extension(self):
initial_extension_count = len(extension_pool.page_extensions)
# --- None extension registering -----------------------------
from cms.exceptions import SubClassNeededError
none_extension = self.get_none_extension_class()
self.assertRaises(SubClassNeededError, extension_pool.register, none_extension)
self.assertEqual(len(extension_pool.page_extensions), initial_extension_count)
self.assertEqual(len(extension_pool.page_content_extensions), initial_extension_count)
# --- Page registering ---------------------------------------
page_extension = self.get_page_extension_class()
# register first time
extension_pool.register(page_extension)
self.assertEqual(len(extension_pool.page_extensions), initial_extension_count + 1)
# register second time
extension_pool.register(page_extension)
self.assertEqual(len(extension_pool.page_extensions), initial_extension_count + 1)
# --- Page Content registering -------------------------------
page_content_extension = self.get_page_content_extension_class()
# register first time
extension_pool.register(page_content_extension)
self.assertEqual(len(extension_pool.page_content_extensions), initial_extension_count + 1)
# register second time
extension_pool.register(page_content_extension)
self.assertEqual(len(extension_pool.page_content_extensions), initial_extension_count + 1)
# --- Unregister ---------------------------------------------
extension_pool.unregister(page_extension)
self.assertEqual(len(extension_pool.page_extensions), initial_extension_count)
extension_pool.unregister(page_content_extension)
self.assertEqual(len(extension_pool.page_content_extensions), initial_extension_count)
# Unregister an object that is not registered yet
extension_pool.unregister(page_extension)
extension_pool.unregister(page_content_extension)
def get_page_extension_class(self):
from django.db import models
class TestPageExtension(PageExtension):
content = models.CharField('Content', max_length=50)
class Meta:
abstract = True
return TestPageExtension
def get_page_content_extension_class(self):
from django.db import models
class TestPageContentExtension(PageContentExtension):
content = models.CharField('Content', max_length=50)
class Meta:
abstract = True
return TestPageContentExtension
def get_none_extension_class(self):
class TestNoneExtension:
pass
return TestNoneExtension
def test_copy_extensions(self):
root = create_page('Root', "nav_playground.html", "en")
page = create_page('Test Page Extension', "nav_playground.html", "en", parent=root)
subpage = create_page('Test subpage Extension', "nav_playground.html", "en", parent=page)
page = Page.objects.get(pk=page.pk)
page_extension = MyPageExtension(extended_object=page, extra='page extension 1')
page_extension.save()
page.mypageextension = page_extension
page_content = page.get_content_obj()
page_content_extension = MyPageContentExtension(extended_object=page_content, extra_title='title extension 1')
page_content_extension.save()
page.myPageContentExtension = page_content_extension
subpage_extension = MyPageExtension(extended_object=subpage, extra='page extension 2')
subpage_extension.save()
subpage.mypageextension = subpage_extension
subpage_content = subpage.get_content_obj()
subpage_content_extension = MyPageContentExtension(
extended_object=subpage_content,
extra_title='title extension 2'
)
subpage_content_extension.save()
subpage.myPageContentExtension = subpage_content_extension
# asserting original extensions
self.assertEqual(len(extension_pool.get_page_extensions()), 2)
self.assertEqual(len(extension_pool.get_page_content_extensions()), 2)
copied_page = page.copy_with_descendants(target_page=None, position='last-child', user=self.get_superuser())
# asserting original + copied extensions
self.assertEqual(len(extension_pool.get_page_extensions()), 4)
self.assertEqual(len(extension_pool.get_page_content_extensions()), 4)
# testing extension content
old_page_extensions = [page_extension, subpage_extension]
old_title_extension = [page_content_extension, subpage_content_extension]
for index, new_page in enumerate([copied_page] + list(copied_page.get_descendant_pages())):
self.assertEqual(
extension_pool.get_page_extensions(new_page)[0].extra,
old_page_extensions[index].extra
)
self.assertEqual(
extension_pool.get_page_content_extensions(
new_page.pagecontent_set.get(language='en')
)[0].extra_title,
old_title_extension[index].extra_title
)
# check that objects are actually different
self.assertNotEqual(
extension_pool.get_page_extensions(new_page)[0].pk,
old_page_extensions[index].pk
)
self.assertNotEqual(
extension_pool.get_page_content_extensions(new_page.pagecontent_set.get(language='en'))[0].pk,
old_title_extension[index].pk
)
# Test deleting original page for #3987
page.delete()
# asserting original extensions are gone, but copied ones should still exist
self.assertEqual(len(extension_pool.get_page_extensions()), 2)
self.assertEqual(len(extension_pool.get_page_content_extensions()), 2)
def test_copy_multitable_extensions(self):
root = create_page('Root', "nav_playground.html", "en")
page = create_page('Test Multi-Table Page Extension', "nav_playground.html", "en", parent=root)
subpage = create_page('Test Multi-Table subpage Extension', "nav_playground.html", "en", parent=page)
page = Page.objects.get(pk=page.pk)
page_extension = MultiTablePageExtension(
extended_object=page,
extension_parent_field='page extension 1',
multitable_extra='multi-table page extension 1'
)
page_extension.save()
page.multitablepageextension = page_extension
title = page.get_content_obj()
title_extension = MultiTablePageContentExtension(
extended_object=title,
extension_content_parent_field='content extension 1',
multitable_extra_content='multi-table content extension 1'
)
title_extension.save()
page.multitablepagecontentextension = title_extension
subpage_extension = MultiTablePageExtension(
extended_object=subpage,
extension_parent_field='page extension 2',
multitable_extra='multi-table page extension 2'
)
subpage_extension.save()
subpage.multitablepageextension = subpage_extension
subtitle = subpage.get_content_obj()
subtitle_extension = MultiTablePageContentExtension(
extended_object=subtitle,
extension_content_parent_field='title extension 2',
multitable_extra_content='multi-table title extension 2'
)
subtitle_extension.save()
subpage.multitablepagecontentextension = subtitle_extension
# asserting original extensions
self.assertEqual(len(extension_pool.get_page_extensions()), 2)
self.assertEqual(len(extension_pool.get_page_content_extensions()), 2)
copied_page = page.copy_with_descendants(target_page=None, position='last-child', user=self.get_superuser())
# asserting original + copied extensions
self.assertEqual(len(extension_pool.get_page_extensions()), 4)
self.assertEqual(len(extension_pool.get_page_content_extensions()), 4)
# testing extension content
old_page_extensions = [page_extension, subpage_extension]
old_title_extension = [title_extension, subtitle_extension]
for index, new_page in enumerate([copied_page] + list(copied_page.get_descendant_pages())):
copied_page_extension = extension_pool.get_page_extensions(new_page)[0]
copied_title_extension = extension_pool.get_page_content_extensions(
new_page.pagecontent_set.get(language='en')
)[0]
self.assertEqual(
copied_page_extension.extension_parent_field,
old_page_extensions[index].extension_parent_field
)
self.assertEqual(
copied_page_extension.multitable_extra,
old_page_extensions[index].multitable_extra
)
self.assertEqual(
copied_title_extension.extension_content_parent_field,
old_title_extension[index].extension_content_parent_field
)
self.assertEqual(
copied_title_extension.multitable_extra_content,
old_title_extension[index].multitable_extra_content
)
# check that objects are actually different
self.assertNotEqual(
extension_pool.get_page_extensions(new_page)[0].pk,
old_page_extensions[index].pk
)
self.assertNotEqual(
extension_pool.get_page_content_extensions(new_page.pagecontent_set.get(language='en'))[0].pk,
old_title_extension[index].pk
)
# Test deleting original page for #3987
page.delete()
# asserting original extensions are gone, but copied ones should still exist
self.assertEqual(len(extension_pool.get_page_extensions()), 2)
self.assertEqual(len(extension_pool.get_page_content_extensions()), 2)
class ExtensionAdminTestCase(CMSTestCase):
def setUp(self):
User = get_user_model()
self.admin = self.get_superuser()
self.normal_guy = self.get_staff_user_with_std_permissions()
if get_user_model().USERNAME_FIELD == 'email':
self.no_page_permission_user = User.objects.create_user(
'no_page_permission', 'test2@test.com', 'test2@test.com'
)
else:
self.no_page_permission_user = User.objects.create_user(
'no_page_permission', 'test2@test.com', 'no_page_permission'
)
self.no_page_permission_user.is_staff = True
self.no_page_permission_user.is_active = True
self.no_page_permission_user.save()
[self.no_page_permission_user.user_permissions.add(p) for p in Permission.objects.filter(
codename__in=[
'change_mypageextension', 'change_myPageContentExtension',
'add_mypageextension', 'add_myPageContentExtension',
'delete_mypageextension', 'delete_myPageContentExtension',
]
)]
self.site = Site.objects.get(pk=1)
self.page = create_page(
'My Extension Page', 'nav_playground.html', 'en',
site=self.site, created_by=self.admin)
self.page_title = self.page.get_content_obj('en')
create_page_content('de', 'de title', self.page)
self.page_extension = MyPageExtension.objects.create(
extended_object=self.page,
extra="page extension text")
self.title_extension = MyPageContentExtension.objects.create(
extended_object=self.page.get_content_obj(),
extra_title="title extension text")
self.page_without_extension = create_page(
'A Page', 'nav_playground.html', 'en',
site=self.site, created_by=self.admin)
self.page_title_without_extension = self.page_without_extension.get_content_obj()
def test_duplicate_extensions(self):
with self.login_user_context(self.admin):
content = self.get_pagecontent_obj(self.page, 'en')
# create page copy
page_data = {
'title': 'type1', 'slug': 'type1', '_save': 1, 'template': 'nav_playground.html',
'site': 1, 'language': 'en', 'source': self.page.pk,
}
self.assertEqual(Page.objects.all().count(), 2)
self.assertEqual(MyPageExtension.objects.all().count(), 1)
self.assertEqual(MyPageContentExtension.objects.all().count(), 1)
response = self.client.post(
self.get_admin_url(PageContent, 'duplicate', content.pk),
data=page_data,
)
# Check that page and its extensions have been copied
self.assertRedirects(response, self.get_pages_admin_list_uri('en'))
self.assertEqual(Page.objects.all().count(), 3)
self.assertEqual(MyPageExtension.objects.all().count(), 2)
self.assertEqual(MyPageContentExtension.objects.all().count(), 2)
def test_admin_page_extension(self):
with self.login_user_context(self.admin):
# add a new extension
response = self.client.get(
admin_reverse(
'extensionapp_mypageextension_add'
) + '?extended_object=%s' % self.page_without_extension.pk
)
self.assertEqual(response.status_code, 200)
# make sure there is no extension yet
self.assertFalse(MyPageExtension.objects.filter(extended_object=self.page_without_extension).exists())
post_data = {
'extra': 'my extra'
}
response = self.client.post(
admin_reverse(
'extensionapp_mypageextension_add'
) + '?extended_object=%s' % self.page_without_extension.pk,
post_data, follow=True
)
created_page_extension = MyPageExtension.objects.get(extended_object=self.page_without_extension)
# can delete extension
response = self.client.post(
admin_reverse('extensionapp_mypageextension_delete', args=(created_page_extension.pk,)),
{'post': 'yes'}, follow=True
)
self.assertFalse(MyPageExtension.objects.filter(extended_object=self.page_without_extension).exists())
# accessing the add view on a page that already has an extension should redirect
response = self.client.get(
admin_reverse('extensionapp_mypageextension_add') + '?extended_object=%s' % self.page.pk
)
self.assertRedirects(
response, admin_reverse('extensionapp_mypageextension_change', args=(self.page_extension.pk,))
)
# saving an extension should work without the GET parameter
post_data = {
'extra': 'my extra text'
}
self.client.post(
admin_reverse('extensionapp_mypageextension_change', args=(self.page_extension.pk,)),
post_data, follow=True
)
self.assertTrue(MyPageExtension.objects.filter(extra='my extra text', pk=self.page_extension.pk).exists())
with self.login_user_context(self.no_page_permission_user):
# can't save if user does not have permissions to change the page
post_data = {
'extra': 'try to change extra text'
}
response = self.client.post(
admin_reverse('extensionapp_mypageextension_change', args=(self.page_extension.pk,)),
post_data, follow=True
)
self.assertEqual(response.status_code, 403)
# can't delete without page permission
response = self.client.post(
admin_reverse('extensionapp_mypageextension_delete', args=(self.page_extension.pk,)),
{'post': 'yes'}, follow=True
)
self.assertEqual(response.status_code, 403)
self.assertTrue(MyPageExtension.objects.filter(extended_object=self.page).exists())
def test_toolbar_page_extension(self):
old_toolbars = deepcopy(toolbar_pool.toolbars)
class SampleExtension(ExtensionToolbar):
model = MyPageExtension # The PageExtension / TitleExtension you are working with
def populate(self):
current_page_menu = self._setup_extension_toolbar()
if current_page_menu:
position = 0
page_extension, url = self.get_page_extension_admin()
if url:
current_page_menu.add_modal_item(
'TestItem',
url=url,
disabled=not self.toolbar.edit_mode_active,
position=position
)
toolbar_pool.register(SampleExtension)
with self.login_user_context(self.admin):
response = self.client.get(f'{self.page.get_absolute_url()}?edit')
self.assertIn("TestItem", response.rendered_content)
toolbar_pool.toolbars = old_toolbars
def test_toolbar_page_content_extension(self):
old_toolbars = deepcopy(toolbar_pool.toolbars)
class SampleExtension(ExtensionToolbar):
model = MyPageContentExtension
def populate(self):
current_page_menu = self._setup_extension_toolbar()
if current_page_menu:
position = 0
pagecontent_extension, url = self.get_page_content_extension_admin()
current_page_menu.add_modal_item(
'TestItem',
url=url,
disabled=not self.toolbar.edit_mode_active,
position=position
)
toolbar_pool.register(SampleExtension)
with self.login_user_context(self.admin):
response = self.client.get(f'{self.page.get_absolute_url()}?edit')
self.assertIn("TestItem", response.rendered_content)
toolbar_pool.toolbars = old_toolbars
def test_admin_title_extension(self):
with self.login_user_context(self.admin):
# add a new extension
response = self.client.get(
admin_reverse(
'extensionapp_mypagecontentextension_add'
) + '?extended_object=%s' % self.page_title_without_extension.pk
)
self.assertEqual(response.status_code, 200)
# make sure there is no extension yet
self.assertFalse(
MyPageContentExtension.objects.filter(extended_object=self.page_title_without_extension).exists()
)
post_data = {
'extra_title': 'my extra title'
}
self.client.post(
admin_reverse(
'extensionapp_mypagecontentextension_add'
) + '?extended_object=%s' % self.page_title_without_extension.pk,
post_data, follow=True
)
created_title_extension = MyPageContentExtension.objects.get(
extended_object=self.page_title_without_extension
)
# can delete extension
self.client.post(
admin_reverse('extensionapp_mypagecontentextension_delete', args=(created_title_extension.pk,)),
{'post': 'yes'}, follow=True
)
self.assertFalse(
MyPageContentExtension.objects.filter(extended_object=self.page_title_without_extension).exists()
)
# accessing the add view on a page that already has an extension should redirect
response = self.client.get(
admin_reverse('extensionapp_mypagecontentextension_add') + '?extended_object=%s' % self.page_title.pk
)
self.assertRedirects(
response, admin_reverse('extensionapp_mypagecontentextension_change', args=(self.title_extension.pk,))
)
# saving an extension should work without the GET parameter
post_data = {
'extra_title': 'my extra text'
}
self.client.post(
admin_reverse('extensionapp_mypagecontentextension_change', args=(self.title_extension.pk,)),
post_data, follow=True
)
self.assertTrue(
MyPageContentExtension.objects.filter(extra_title='my extra text', pk=self.title_extension.pk).exists()
)
with self.login_user_context(self.no_page_permission_user):
# can't save if user does not have permissions to change the page
post_data = {
'extra_title': 'try to change extra text'
}
response = self.client.post(
admin_reverse('extensionapp_mypagecontentextension_change', args=(self.title_extension.pk,)),
post_data, follow=True
)
self.assertEqual(response.status_code, 403)
# can't delete without page permission
response = self.client.post(
admin_reverse('extensionapp_mypagecontentextension_delete', args=(self.title_extension.pk,)),
{'post': 'yes'}, follow=True
)
self.assertEqual(response.status_code, 403)
self.assertTrue(MyPageContentExtension.objects.filter(extended_object=self.page_title).exists())