dynamicweb/cms/tests/test_placeholder_app_admin.py

887 lines
36 KiB
Python

from unittest.mock import patch
from django.forms.models import model_to_dict
from cms.api import add_plugin
from cms.models import CMSPlugin, Placeholder, UserSettings
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.utils.urlutils import admin_reverse
class AppAdminTestCase(CMSTestCase):
def setUp(self):
self._obj = self._get_example_obj()
def _add_plugin_to_placeholder(self, placeholder,
plugin_type='LinkPlugin', language='en'):
plugin_data = {
'StylePlugin': {'tag_type': 'div'},
'LinkPlugin': {'name': 'A Link', 'external_link': 'https://www.django-cms.org'},
'PlaceholderPlugin': {'name': 'Content'},
}
plugin = add_plugin(
placeholder,
plugin_type,
language,
**plugin_data[plugin_type]
)
return plugin
def _get_move_data(self, plugin, position, placeholder=None, parent=None):
try:
placeholder_id = placeholder.pk
except AttributeError:
placeholder_id = ''
try:
parent_id = parent.pk
except AttributeError:
parent_id = ''
data = {
'placeholder_id': placeholder_id,
'target_language': 'en',
'target_position': position,
'plugin_id': plugin.pk,
'plugin_parent': parent_id,
}
return data
def _get_add_plugin_uri(self, plugin_type='LinkPlugin', language='en'):
uri = self.get_add_plugin_uri(
placeholder=self._obj.placeholder,
plugin_type=plugin_type,
language=language,
)
return uri
def _get_example_obj(self):
obj = Example1.objects.create(
char_1='one',
char_2='two',
char_3='tree',
char_4='four'
)
return obj
class AppAdminTest(AppAdminTestCase):
placeholderconf = {'placeholder': {
'limits': {
'global': 2,
'StylePlugin': 1,
}
}
}
def test_global_limit_on_plugin_add(self):
"""
Ensures placeholder global plugin limit is respected
when adding plugins to the placeholder.
"""
superuser = self.get_superuser()
endpoint = self._get_add_plugin_uri()
with self.login_user_context(superuser):
with override_placeholder_conf(CMS_PLACEHOLDER_CONF=self.placeholderconf):
data = {'name': 'A Link', 'external_link': 'https://www.django-cms.org'}
response = self.client.post(endpoint, data) # first
self.assertEqual(response.status_code, 200)
response = self.client.post(endpoint, data) # second
self.assertEqual(response.status_code, 200)
response = self.client.post(endpoint, data) # third
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.content,
b"This placeholder already has the maximum number of plugins (2).",
)
def test_global_limit_on_plugin_move(self):
"""
Ensures placeholder global plugin limit is respected
when moving plugins to the placeholder.
"""
superuser = self.get_superuser()
source_placeholder = self._obj.placeholder
target_placeholder = self._get_example_obj().placeholder
plugin_1 = self._add_plugin_to_placeholder(source_placeholder)
plugin_2 = self._add_plugin_to_placeholder(source_placeholder)
plugin_3 = self._add_plugin_to_placeholder(source_placeholder)
with self.login_user_context(superuser):
with override_placeholder_conf(self.placeholderconf):
data = self._get_move_data(plugin_1, position=1, placeholder=target_placeholder)
endpoint = self.get_move_plugin_uri(plugin_1)
response = self.client.post(endpoint, data) # first
self.assertEqual(response.status_code, 200)
data = self._get_move_data(plugin_2, position=2, placeholder=target_placeholder)
endpoint = self.get_move_plugin_uri(plugin_2)
response = self.client.post(endpoint, data) # second
self.assertEqual(response.status_code, 200)
data = self._get_move_data(plugin_3, position=3, placeholder=target_placeholder)
endpoint = self.get_move_plugin_uri(plugin_3)
response = self.client.post(endpoint, data) # third
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.content,
b"This placeholder already has the maximum number of plugins (2)."
)
def test_no_global_limit_check_same_placeholder_move(self):
"""
Ensures no global limit exception is raised
when moving plugins inside a placeholder.
"""
superuser = self.get_superuser()
source_placeholder = self._obj.placeholder
plugin_1 = self._add_plugin_to_placeholder(source_placeholder)
plugin_2 = self._add_plugin_to_placeholder(source_placeholder)
with self.login_user_context(superuser):
with override_placeholder_conf(self.placeholderconf):
data = self._get_move_data(plugin_1, position=1)
endpoint = self.get_move_plugin_uri(plugin_1)
response = self.client.post(endpoint, data) # first
self.assertEqual(response.status_code, 200)
data = self._get_move_data(plugin_2, position=2)
endpoint = self.get_move_plugin_uri(plugin_2)
response = self.client.post(endpoint, data) # second
self.assertEqual(response.status_code, 200)
def test_type_limit_on_plugin_add(self):
"""
Ensures placeholder plugin type limit is respected
when adding plugins to the placeholder.
"""
superuser = self.get_superuser()
endpoint = self._get_add_plugin_uri('StylePlugin')
with self.login_user_context(superuser):
with override_placeholder_conf(CMS_PLACEHOLDER_CONF=self.placeholderconf):
data = {'tag_type': 'div'}
response = self.client.post(endpoint, data) # first
self.assertEqual(response.status_code, 200)
response = self.client.post(endpoint, data) # second
self.assertEqual(response.status_code, 400)
self.assertEqual(
response.content,
b"This placeholder already has the "
b"maximum number (1) of allowed Style plugins."
)
def test_type_limit_on_plugin_move(self):
"""
Ensures placeholder plugin type limit is respected
when moving plugins to the placeholder.
"""
superuser = self.get_superuser()
source_placeholder = self._obj.placeholder
target_placeholder = self._get_example_obj().placeholder
plugin_1 = self._add_plugin_to_placeholder(source_placeholder, 'StylePlugin')
plugin_2 = self._add_plugin_to_placeholder(source_placeholder, 'StylePlugin')
with self.login_user_context(superuser):
with override_placeholder_conf(CMS_PLACEHOLDER_CONF=self.placeholderconf):
data = self._get_move_data(plugin_1, position=1, placeholder=target_placeholder)
endpoint = self.get_move_plugin_uri(plugin_1)
response = self.client.post(endpoint, data) # first
self.assertEqual(response.status_code, 200)
data = self._get_move_data(plugin_2, position=1, placeholder=target_placeholder)
endpoint = self.get_move_plugin_uri(plugin_2)
response = self.client.post(endpoint, data) # second
self.assertEqual(response.status_code, 400)
self.assertEqual(response.content,
b"This placeholder already has the maximum number (1) of allowed Style plugins.")
def test_no_type_limit_check_same_placeholder_move(self):
"""
Ensures no plugin type limit exception is raised
when moving plugins inside of a placeholder.
"""
superuser = self.get_superuser()
source_placeholder = self._obj.placeholder
plugin_1 = self._add_plugin_to_placeholder(source_placeholder, 'StylePlugin')
with self.login_user_context(superuser):
with override_placeholder_conf(CMS_PLACEHOLDER_CONF=self.placeholderconf):
data = self._get_move_data(plugin_1, position=1)
endpoint = self.get_move_plugin_uri(plugin_1)
response = self.client.post(endpoint, data) # first
self.assertEqual(response.status_code, 200)
class AppAdminPermissionsTest(AppAdminTestCase):
def setUp(self):
self._obj = self._get_example_obj()
self._staff_user = self.get_staff_user_with_no_permissions()
def test_user_can_add_plugin(self):
"""
User can add a new plugin if he has change permissions
on the model attached to the placeholder and he has
add permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugins = placeholder.get_plugins('en').filter(plugin_type='LinkPlugin')
endpoint = self._get_add_plugin_uri()
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'add_link')
with self.login_user_context(staff_user):
data = {'name': 'A Link', 'external_link': 'https://www.django-cms.org'}
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 200)
self.assertEqual(plugins.count(), 1)
def test_user_cant_add_plugin(self):
"""
User can't add a new plugin if he does not have
change permissions on the model attached to the placeholder
and/or does not have add permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugins = placeholder.get_plugins('en').filter(plugin_type='LinkPlugin')
endpoint = self._get_add_plugin_uri()
self.add_permission(staff_user, 'add_example1')
self.add_permission(staff_user, 'delete_example1')
self.add_permission(staff_user, 'add_link')
with self.login_user_context(staff_user):
data = {'name': 'A Link', 'external_link': 'https://www.django-cms.org'}
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertEqual(plugins.count(), 0)
self.add_permission(staff_user, 'change_example1')
self.remove_permission(staff_user, 'add_link')
with self.login_user_context(staff_user):
data = {'name': 'A Link', 'external_link': 'https://www.django-cms.org'}
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertEqual(plugins.count(), 0)
def test_user_can_edit_plugin(self):
"""
User can edit a plugin if he has change permissions
on the model attached to the placeholder and he has
change permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self.get_change_plugin_uri(plugin)
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
data = model_to_dict(plugin, fields=['name', 'external_link'])
data['name'] = 'A link 2'
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 200)
plugin.refresh_from_db()
self.assertEqual(plugin.name, data['name'])
def test_user_cant_edit_plugin(self):
"""
User can't edit a plugin if he does not have
change permissions on the model attached to the placeholder
and/or does not have change permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self.get_change_plugin_uri(plugin)
self.add_permission(staff_user, 'add_example1')
self.add_permission(staff_user, 'delete_example1')
self.add_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
data = model_to_dict(plugin, fields=['name', 'external_link'])
data['name'] = 'A link 2'
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
plugin.refresh_from_db()
self.assertNotEqual(plugin.name, data['name'])
self.add_permission(staff_user, 'change_example1')
self.remove_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
data = model_to_dict(plugin, fields=['name', 'external_link'])
data['name'] = 'A link 2'
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
plugin.refresh_from_db()
self.assertNotEqual(plugin.name, data['name'])
def test_user_can_delete_plugin(self):
"""
User can delete a plugin if he has change permissions
on the model attached to the placeholder and he has
delete permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self.get_delete_plugin_uri(plugin)
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'delete_link')
with self.login_user_context(staff_user):
data = {'post': True}
response = self.client.post(endpoint, data)
self.assertContains(response, '<div class="success"></div>')
self.assertFalse(CMSPlugin.objects.filter(pk=plugin.pk).exists())
def test_user_cant_delete_plugin(self):
"""
User can't delete a plugin if he does not have
change permissions on the model attached to the placeholder
and/or does not have delete permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self.get_delete_plugin_uri(plugin)
self.add_permission(staff_user, 'add_example1')
self.add_permission(staff_user, 'delete_example1')
self.add_permission(staff_user, 'delete_link')
with self.login_user_context(staff_user):
data = {'post': True}
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertTrue(CMSPlugin.objects.filter(pk=plugin.pk).exists())
self.add_permission(staff_user, 'change_example1')
self.remove_permission(staff_user, 'delete_link')
with self.login_user_context(staff_user):
data = {'post': True}
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertTrue(CMSPlugin.objects.filter(pk=plugin.pk).exists())
def test_user_can_move_plugin(self):
"""
User can move a plugin if he has change permissions
on the model attached to the placeholder and he has
change permissions on the plugin model.
"""
staff_user = self._staff_user
source_placeholder = self._obj.placeholder
target_placeholder = self._get_example_obj().placeholder
plugin = self._add_plugin_to_placeholder(source_placeholder)
data = self._get_move_data(plugin, position=1, placeholder=target_placeholder)
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
endpoint = self.get_move_plugin_uri(plugin)
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 200)
self.assertTrue(target_placeholder.get_plugins('en').filter(pk=plugin.pk))
self.assertFalse(source_placeholder.get_plugins('en').filter(pk=plugin.pk))
def test_user_cant_move_plugin(self):
"""
User can't move a plugin if he does not have
change permissions on the model attached to the placeholder
and/or does not have change permissions on the plugin model.
"""
staff_user = self._staff_user
source_placeholder = self._obj.placeholder
target_placeholder = self._get_example_obj().placeholder
plugin = self._add_plugin_to_placeholder(source_placeholder)
data = self._get_move_data(plugin, position=1, placeholder=target_placeholder)
self.add_permission(staff_user, 'add_example1')
self.add_permission(staff_user, 'delete_example1')
self.add_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
endpoint = self.get_move_plugin_uri(plugin)
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertFalse(target_placeholder.get_plugins('en').filter(pk=plugin.pk))
self.assertTrue(source_placeholder.get_plugins('en').filter(pk=plugin.pk))
self.add_permission(staff_user, 'change_example1')
self.remove_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertFalse(target_placeholder.get_plugins('en').filter(pk=plugin.pk))
self.assertTrue(source_placeholder.get_plugins('en').filter(pk=plugin.pk))
def test_user_can_copy_plugin(self):
"""
User can copy a plugin if he has change permissions
on the model attached to the placeholder and he has
add permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self.get_copy_plugin_uri(plugin)
source_placeholder = plugin.placeholder
target_placeholder = self._get_example_obj().placeholder
data = {
'source_plugin_id': plugin.pk,
'source_placeholder_id': source_placeholder.pk,
'source_language': plugin.language,
'target_language': 'en',
'target_placeholder_id': target_placeholder.pk,
}
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'add_link')
with self.login_user_context(staff_user):
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 200)
self.assertTrue(source_placeholder.get_plugins('en').filter(pk=plugin.pk).exists())
self.assertTrue(
target_placeholder
.get_plugins('en')
.filter(plugin_type=plugin.plugin_type)
.exists()
)
def test_user_cant_copy_plugin(self):
"""
User can't copy a plugin if he does not have
change permissions on the model attached to the placeholder
and/or does not have add permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self.get_copy_plugin_uri(plugin)
source_placeholder = plugin.placeholder
target_placeholder = self._get_example_obj().placeholder
data = {
'source_plugin_id': plugin.pk,
'source_placeholder_id': source_placeholder.pk,
'source_language': plugin.language,
'target_language': 'en',
'target_placeholder_id': target_placeholder.pk,
}
self.add_permission(staff_user, 'add_example1')
self.add_permission(staff_user, 'delete_example1')
self.add_permission(staff_user, 'add_link')
with self.login_user_context(staff_user):
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertTrue(source_placeholder.get_plugins('en').filter(pk=plugin.pk).exists())
self.assertFalse(
target_placeholder
.get_plugins('en')
.filter(plugin_type=plugin.plugin_type)
.exists()
)
self.add_permission(staff_user, 'change_example1')
self.remove_permission(staff_user, 'add_link')
with self.login_user_context(staff_user):
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertTrue(source_placeholder.get_plugins('en').filter(pk=plugin.pk).exists())
self.assertFalse(
target_placeholder
.get_plugins('en')
.filter(plugin_type=plugin.plugin_type)
.exists()
)
def test_user_can_clear_empty_placeholder(self):
"""
User can clear a placeholder if he has change permissions
on the model attached to the placeholder.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
endpoint = self.get_clear_placeholder_url(placeholder)
self.add_permission(staff_user, 'change_example1')
with self.login_user_context(staff_user):
response = self.client.post(endpoint, {'test': 0})
self.assertEqual(response.status_code, 200)
def test_user_cant_clear_empty_placeholder(self):
"""
User can't clear a placeholder if he does not have
change permissions on the model attached to the placeholder.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
endpoint = self.get_clear_placeholder_url(placeholder)
with self.login_user_context(staff_user):
response = self.client.post(endpoint, {'test': 0})
self.assertEqual(response.status_code, 403)
def test_user_can_clear_non_empty_placeholder(self):
"""
User can clear a placeholder with plugins if he has
change permissions on the model attached to the placeholder
and delete permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugins = [
self._add_plugin_to_placeholder(placeholder, 'StylePlugin'),
self._add_plugin_to_placeholder(placeholder, 'LinkPlugin'),
]
placeholder = plugins[0].placeholder
endpoint = self.get_clear_placeholder_url(placeholder)
self.add_permission(staff_user, 'delete_style')
self.add_permission(staff_user, 'delete_link')
self.add_permission(staff_user, 'change_example1')
with self.login_user_context(staff_user):
response = self.client.post(endpoint, {'test': 0})
self.assertEqual(response.status_code, 200)
self.assertEqual(placeholder.get_plugins('en').count(), 0)
def test_user_cant_clear_non_empty_placeholder(self):
"""
User can't clear a placeholder with plugins if he does not have
change permissions on the model attached to the placeholder
and/or does not have delete permissions on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugins = [
self._add_plugin_to_placeholder(placeholder, 'StylePlugin'),
self._add_plugin_to_placeholder(placeholder, 'LinkPlugin'),
]
placeholder = plugins[0].placeholder
endpoint = self.get_clear_placeholder_url(placeholder)
self.add_permission(staff_user, 'delete_text')
self.add_permission(staff_user, 'delete_link')
with self.login_user_context(staff_user):
response = self.client.post(endpoint, {'test': 0})
self.assertEqual(response.status_code, 403)
self.assertEqual(placeholder.get_plugins('en').count(), 2)
def test_user_can_copy_placeholder_to_clipboard(self):
"""
User can copy a placeholder to the clipboard
if he has add permissions on the plugin models
being copied.
"""
staff_user = self._staff_user
source_placeholder = self._obj.placeholder
endpoint = self.get_copy_placeholder_uri(source_placeholder)
self._add_plugin_to_placeholder(source_placeholder, 'StylePlugin')
self._add_plugin_to_placeholder(source_placeholder, 'LinkPlugin')
user_settings = UserSettings.objects.create(
language="en",
user=staff_user,
clipboard=Placeholder.objects.create(),
)
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'add_link')
self.add_permission(staff_user, 'add_style')
data = {
'source_plugin_id': '',
'source_placeholder_id': source_placeholder.pk,
'source_language': 'en',
'target_language': 'en',
'target_placeholder_id': user_settings.clipboard.pk,
}
with self.login_user_context(staff_user):
# Copy plugins into the clipboard
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 200)
clipboard_plugins = user_settings.clipboard.get_plugins()
# assert the clipboard has a PlaceholderPlugin
self.assertTrue(clipboard_plugins.filter(plugin_type='PlaceholderPlugin').exists())
self.assertEqual(len(clipboard_plugins), 1)
placeholder_plugin = clipboard_plugins[0].get_plugin_instance()[0]
ref_placeholder = placeholder_plugin.placeholder_ref
# assert there's only two plugins in the clipboard
self.assertEqual(ref_placeholder.get_plugins().count(), 2)
def test_user_cant_copy_placeholder_to_clipboard(self):
"""
User cant copy a placeholder to the clipboard if he does not
have add permissions on the plugin models being copied.
"""
staff_user = self._staff_user
source_placeholder = self._obj.placeholder
endpoint = self.get_copy_placeholder_uri(source_placeholder)
self._add_plugin_to_placeholder(source_placeholder, 'StylePlugin')
self._add_plugin_to_placeholder(source_placeholder, 'LinkPlugin')
user_settings = UserSettings.objects.create(
language="en",
user=staff_user,
clipboard=Placeholder.objects.create(),
)
self.add_permission(staff_user, 'change_link')
self.add_permission(staff_user, 'delete_link')
self.add_permission(staff_user, 'change_style')
self.add_permission(staff_user, 'delete_style')
data = {
'source_plugin_id': '',
'source_placeholder_id': source_placeholder.pk,
'source_language': 'en',
'target_language': 'en',
'target_placeholder_id': user_settings.clipboard.pk,
}
with self.login_user_context(staff_user):
# Copy plugins into the clipboard
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
clipboard_plugins = user_settings.clipboard.get_plugins()
self.assertEqual(len(clipboard_plugins), 0)
def test_user_can_paste_from_clipboard(self):
"""
User can paste plugins from the clipboard if he has
change permissions on the model attached to the target
placeholder and he has add permissions on the plugin models
being copied.
"""
staff_user = self._staff_user
target_placeholder = self._obj.placeholder
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'add_link')
user_settings = UserSettings.objects.create(
language="en",
user=staff_user,
clipboard=Placeholder.objects.create(),
)
placeholder_plugin = self._add_plugin_to_placeholder(
user_settings.clipboard,
'PlaceholderPlugin',
)
ref_placeholder = placeholder_plugin.placeholder_ref
self._add_plugin_to_placeholder(ref_placeholder)
self._add_plugin_to_placeholder(ref_placeholder)
with self.login_user_context(staff_user):
# Paste plugins from clipboard into placeholder
# under the french language.
data = {
'placeholder_id': target_placeholder.pk,
'plugin_id': placeholder_plugin.pk,
'plugin_parent': '',
'target_language': 'fr',
'move_a_copy': True,
'target_position': target_placeholder.get_next_plugin_position('fr', insert_order='last'),
}
endpoint = self.get_move_plugin_uri(placeholder_plugin)
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 200)
self.assertEqual(target_placeholder.get_plugins('fr').count(), 2)
def test_user_cant_paste_from_clipboard(self):
"""
User cant paste plugins from the clipboard if he does not have
change permissions on the model attached to the target placeholder
and/or does not have add permissions on the plugin models
being copied.
"""
staff_user = self._staff_user
target_placeholder = self._obj.placeholder
self.add_permission(staff_user, 'add_example1')
self.add_permission(staff_user, 'delete_example1')
self.add_permission(staff_user, 'add_link')
user_settings = UserSettings.objects.create(
language="en",
user=staff_user,
clipboard=Placeholder.objects.create(),
)
placeholder_plugin = self._add_plugin_to_placeholder(
user_settings.clipboard,
'PlaceholderPlugin',
)
ref_placeholder = placeholder_plugin.placeholder_ref
self._add_plugin_to_placeholder(ref_placeholder)
self._add_plugin_to_placeholder(ref_placeholder)
with self.login_user_context(staff_user):
# Paste plugins from clipboard into placeholder
# under the french language.
data = {
'placeholder_id': target_placeholder.pk,
'plugin_id': placeholder_plugin.pk,
'plugin_parent': '',
'target_language': 'fr',
'move_a_copy': True,
'target_position': target_placeholder.get_next_plugin_position('fr', insert_order='last'),
}
endpoint = self.get_move_plugin_uri(placeholder_plugin)
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertEqual(target_placeholder.get_plugins('fr').count(), 0)
self.add_permission(staff_user, 'change_example1')
self.remove_permission(staff_user, 'add_link')
with self.login_user_context(staff_user):
# Paste plugins from clipboard into placeholder
# under the french language.
data = {
'placeholder_id': target_placeholder.pk,
'plugin_id': placeholder_plugin.pk,
'plugin_parent': '',
'target_language': 'fr',
'move_a_copy': True,
'target_position': target_placeholder.get_next_plugin_position('fr', insert_order='last'),
}
response = self.client.post(endpoint, data)
self.assertEqual(response.status_code, 403)
self.assertEqual(target_placeholder.get_plugins('fr').count(), 0)
class AppAdminInlineEditPermissionsTest(AppAdminTestCase):
"""Tests that the PlaceholderAdmin's edit_field endpoint (inline editing)
checks plugin change permissions and runs the placeholder's check_source method."""
def setUp(self):
from cms.test_utils.project.pluginapp.plugins.link.cms_plugins import LinkPlugin
self._obj = self._get_example_obj()
self._staff_user = self.get_staff_user_with_no_permissions()
# LinkPlugin does not define frontend_editable_fields by default,
# so we patch it for these tests to enable inline editing of the "name" field.
self._fe_patcher = patch.object(LinkPlugin, "frontend_editable_fields", ("name",), create=True)
self._fe_patcher.start()
def tearDown(self):
self._fe_patcher.stop()
def _get_edit_field_endpoint(self, plugin):
return (
admin_reverse("cms_placeholder_edit_field", args=(plugin.pk, "en"))
+ "?edit_fields=name"
)
def test_inline_edit_checks_change_plugin_permission(self):
"""
Inline editing a plugin via PlaceholderAdmin's edit_field endpoint
requires change permission on the model attached to the placeholder
and change permission on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self._get_edit_field_endpoint(plugin)
# Give change permission on the plugin model but NOT on the source model
self.add_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
response = self.client.get(endpoint)
# Should be denied because user lacks change_example1 permission
self.assertContains(response, "You do not have permission to edit this item")
def test_inline_edit_allowed_with_correct_permissions(self):
"""
Inline editing a plugin via PlaceholderAdmin's edit_field endpoint
succeeds when user has both change permission on the source model
and change permission on the plugin model.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self._get_edit_field_endpoint(plugin)
# Give all required permissions
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
response = self.client.get(endpoint)
# Should show the edit form
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, "You do not have permission to edit this item")
def test_inline_edit_calls_check_source(self):
"""
Inline editing a plugin via PlaceholderAdmin's edit_field endpoint
runs the placeholder's check_source method to verify source-level
permissions.
"""
staff_user = self._staff_user
placeholder = self._obj.placeholder
plugin = self._add_plugin_to_placeholder(placeholder)
endpoint = self._get_edit_field_endpoint(plugin)
self.add_permission(staff_user, 'change_example1')
self.add_permission(staff_user, 'change_link')
with self.login_user_context(staff_user):
with patch.object(
Placeholder, "check_source", return_value=False
) as mock_check_source:
response = self.client.get(endpoint)
# check_source should have been called
mock_check_source.assert_called_once_with(staff_user)
# Should be denied because check_source returned False
self.assertContains(response, "You do not have permission to edit this item")