def test_add_edit_button_with_version_lock(self): """ Version lock is in the test requirements, lets make sure it still works with moderation """ user1 = self.get_superuser() user2 = UserFactory(is_staff=True, is_superuser=True) # Version created with the same user as toolbar user version = PageVersionFactory(created_by=user1) toolbar = self._get_toolbar(version.content, user=user1) toolbar.populate() toolbar.post_template_populate() self.assertTrue(self._button_exists("Edit", toolbar.toolbar)) # Edit button should be clickable button = self._find_buttons("Edit", toolbar.toolbar) self.assertFalse(button[0].disabled) # Now version user is different to toolbar user version = PageVersionFactory(created_by=user2) toolbar = self._get_toolbar(version.content, user=user1) toolbar.populate() toolbar.post_template_populate() self.assertTrue( self._button_exists(lambda button: button.name.endswith("Edit"), toolbar.toolbar)) # Edit button should not be clickable button = self._find_buttons( lambda button: button.name.endswith("Edit"), toolbar.toolbar) self.assertTrue(button[0].disabled)
def test_default_cms_page_changelist_view_language_with_multi_language_content( self): """A multi lingual page shows the correct values when language filters / additional grouping values are set using the default CMS PageContent view """ page = PageFactory(node__depth=1) en_version1 = PageVersionFactory( content__page=page, content__language="en", ) fr_version1 = PageVersionFactory( content__page=page, content__language="fr", ) # Use the tree endpoint which is what the pagecontent changelist depends on changelist_url = admin_reverse("cms_pagecontent_get_tree") with self.login_user_context(self.get_superuser()): en_response = self.client.get(changelist_url, {"language": "en"}) fr_response = self.client.get(changelist_url, {"language": "fr"}) # English values are only returned self.assertEqual(200, en_response.status_code) self.assertContains(en_response, en_version1.content.title) self.assertNotContains(en_response, fr_version1.content.title) # French values are only returned self.assertEqual(200, fr_response.status_code) self.assertContains(fr_response, fr_version1.content.title) self.assertNotContains(fr_response, en_version1.content.title)
def test_success_url_for_cms_wizard(self): from cms.cms_wizards import cms_page_wizard, cms_subpage_wizard from cms.toolbar.utils import get_object_preview_url from djangocms_versioning.test_utils.polls.cms_wizards import poll_wizard # Test against page creations in different languages. version = PageVersionFactory(content__language="en") self.assertEqual( cms_page_wizard.get_success_url(version.content.page, language="en"), get_object_preview_url(version.content), ) version = PageVersionFactory(content__language="en") self.assertEqual( cms_subpage_wizard.get_success_url(version.content.page, language="en"), get_object_preview_url(version.content), ) version = PageVersionFactory(content__language="de") self.assertEqual( cms_page_wizard.get_success_url(version.content.page, language="de"), get_object_preview_url(version.content, language="de"), ) # Test against a model that doesn't have a PlaceholderRelationField version = PollVersionFactory() self.assertEqual( poll_wizard.get_success_url(version.content), version.content.get_absolute_url(), )
def test_submit_for_moderation_version_locked(self): author = self.get_superuser() another_user = UserFactory(is_staff=True, is_superuser=True) version = PageVersionFactory(created_by=author) # Same user to version author is logged in toolbar = self._get_toolbar(version.content, user=author, edit_mode=True) toolbar.populate() toolbar.post_template_populate() # Submit for moderation button has been added self.assertTrue( self._button_exists("Submit for moderation", toolbar.toolbar)) # Different user to version author is logged in toolbar = self._get_toolbar(version.content, user=another_user, edit_mode=True) toolbar.populate() toolbar.post_template_populate() # No Submit for moderation button has been added self.assertFalse( self._button_exists("Submit for moderation", toolbar.toolbar))
def test_get_archive_link(self, _mock): """ VersionAdmin should call moderation's version of _get_archive_link """ version = PageVersionFactory(state=DRAFT, created_by=self.user) archive_url = reverse( "admin:{app}_{model}version_archive".format( app=version._meta.app_label, model=version.content._meta.model_name ), args=(version.pk,), ) _mock.return_value = True archive_link = self.version_admin._get_archive_link(version, self.mock_request) # We test that moderation check is called when getting an edit link self.assertEqual(1, _mock.call_count) # Edit link is inactive as `is_obj_review_locked` is True self.assertIn("inactive", archive_link) self.assertNotIn(archive_url, archive_link) _mock.return_value = None archive_link = self.version_admin._get_archive_link(version, self.mock_request) # We test that moderation check is called when getting the link self.assertEqual(2, _mock.call_count) # Archive link is active there as `get_active_moderation_request` is None self.assertNotIn("inactive", archive_link) self.assertIn(archive_url, archive_link)
def test_enable_edit_button_when_content_is_locked(self): from django.apps import apps from cms.models import Page user = self.get_superuser() version = PageVersionFactory(created_by=user) toolbar = get_toolbar(version.content, user, content_mode=True) toolbar.post_template_populate() edit_button = find_toolbar_buttons('Edit', toolbar.toolbar)[0] self.assertEqual(edit_button.name, 'Edit') cms_extension = apps.get_app_config('djangocms_versioning').cms_extension versionable = cms_extension.versionables_by_grouper[Page] admin_url = self.get_admin_url( versionable.version_model_proxy, 'edit_redirect', version.pk ) self.assertEqual(edit_button.url, admin_url) self.assertFalse(edit_button.disabled) self.assertListEqual( edit_button.extra_classes, ['cms-btn-action', 'cms-versioning-js-edit-btn'] )
def test_get_moderated_children_from_placeholder_has_only_registered_model( self): """ The moderated model is the only model registered with moderation """ pg_version = PageVersionFactory(created_by=self.user) language = pg_version.content.language # Populate page placeholder = PlaceholderFactory(source=pg_version.content) # Moderated plugin poll_version = PollVersionFactory(created_by=self.user, content__language=language) PollPluginFactory(placeholder=placeholder, poll=poll_version.content.poll) # None moderated plugin none_moderated_poll_version = NoneModeratedPollVersionFactory( created_by=self.user, content__language=language) NoneModeratedPollPluginFactory( placeholder=placeholder, poll=none_moderated_poll_version.content.poll) moderated_children = list( get_moderated_children_from_placeholder( placeholder, {"language": pg_version.content.language})) self.assertEqual(moderated_children, [poll_version])
def test_check_no_lock(self): user = self.get_superuser() version = PageVersionFactory(state=ARCHIVED) placeholder = PlaceholderFactory(source=version.content) self.assertTrue( placeholder_content_is_unlocked_for_user(placeholder, user))
def test_add_edit_button(self): user = self.get_superuser() version = PageVersionFactory(created_by=user) collection = ModerationCollectionFactory() toolbar = self._get_toolbar(version.content, user=user) toolbar.populate() toolbar.post_template_populate() # We can see the Edit button, as the version hasn't been submitted # to the moderation (collection) yet self.assertTrue(self._button_exists("Edit", toolbar.toolbar)) button = self._find_buttons("Edit", toolbar.toolbar) self.assertFalse(button[0].disabled) # Lets add the version to moderation, the Edit should no longer be # clickable collection.add_version(version=version) # refresh the toolbar toolbar = self._get_toolbar(version.content, user=user) toolbar.populate() toolbar.post_template_populate() self.assertTrue(self._button_exists("Edit", toolbar.toolbar)) button = self._find_buttons("Edit", toolbar.toolbar) self.assertTrue(button[0].disabled)
def test_disable_edit_button_when_content_is_locked(self): user = self.get_superuser() user_2 = UserFactory( is_staff=True, is_superuser=True, username='******', email='*****@*****.**', ) version = PageVersionFactory(created_by=user) toolbar = get_toolbar(version.content, user_2, content_mode=True) toolbar.post_template_populate() btn_name = format_html( '<span style="vertical-align:middle;position:relative;top:-1px" class="cms-icon cms-icon-lock"></span>{name}', # noqa: E501 name=_('Edit'), ) edit_button = find_toolbar_buttons(btn_name, toolbar.toolbar)[0] self.assertEqual(edit_button.name, btn_name) self.assertEqual(edit_button.url, 'javascript:void(0)') self.assertTrue(edit_button.disabled) self.assertListEqual( edit_button.extra_classes, ['cms-btn-action', 'cms-version-locking-btn-icon'] )
def test_get_moderated_children_from_placeholder_gets_plugin_with_m2m_fields( self): """ FIXME: Currently only checks that a M2M nested poll entry does not cause an error. """ pg_version = PageVersionFactory(created_by=self.user) language = pg_version.content.language placeholder = PlaceholderFactory(source=pg_version.content) poll_1_version = PollVersionFactory(created_by=self.user, content__language=language) poll_2_version = PollVersionFactory(created_by=self.user, content__language=language) ManytoManyPollPluginFactory(placeholder=placeholder, polls=[ poll_1_version.content.poll, poll_2_version.content.poll, ]) moderated_children = list( get_moderated_children_from_placeholder( placeholder, {"language": pg_version.content.language})) # FIXME: # This test is only covering that the M2M field doesn't cause an error. # It should see that the nested polls are found # self.assertEqual(moderated_children, [poll_1_version, poll_2_version]) self.assertEqual(moderated_children, [])
def test_is_obj_review_locked(self): page_version = PageVersionFactory() page_content = page_version.content self.assertFalse(is_obj_review_locked(page_content, self.user)) self.assertFalse(is_obj_review_locked(page_content, self.user2)) self.assertFalse(is_obj_review_locked(page_content, self.user3)) collection = ModerationCollection.objects.create( author=self.user, name="My collection 1", workflow=self.wf1) collection.add_version(page_version) # Now the version is part of the collection so it is review locked self.assertTrue(is_obj_review_locked(page_content, self.user)) self.assertTrue(is_obj_review_locked(page_content, self.user2)) self.assertTrue(is_obj_review_locked(page_content, self.user3)) mr = ModerationRequest.objects.get(collection=collection) mr.actions.create(by_user=self.user, action=ACTION_STARTED) # Now we reject the moderation request, which means that `user` can # resubmit the changes, the review lock is lifted for them mr.actions.create(by_user=self.user2, action=ACTION_REJECTED) self.assertFalse(is_obj_review_locked(page_content, self.user)) self.assertTrue(is_obj_review_locked(page_content, self.user2)) self.assertTrue(is_obj_review_locked(page_content, self.user3))
def test_check_locked_for_the_other_user(self): user1 = self.get_superuser() user2 = self.get_standard_user() version = PageVersionFactory(created_by=user1) placeholder = PlaceholderFactory(source=version.content) self.assertFalse(placeholder_content_is_unlocked_for_user(placeholder, user2))
def test_check_locked_for_the_same_user(self): user = self.get_superuser() version = PageVersionFactory(created_by=user) placeholder = PlaceholderFactory(source=version.content) self.assertTrue( placeholder_content_is_unlocked_for_user(placeholder, user))
def test_not_render_edit_button_when_not_content_mode(self): user = self.get_superuser() version = PageVersionFactory(created_by=user) toolbar = get_toolbar(version.content, user, edit_mode=True) toolbar.post_template_populate() self.assertFalse(toolbar_button_exists('Edit', toolbar.toolbar))
def test_add_items_to_collection(self): pg1_version = PageVersionFactory(created_by=self.user) pg2_version = PageVersionFactory(created_by=self.user) ModerationRequest.objects.all().delete() data = { "collection": self.collection1.pk, "versions": [pg1_version, pg2_version], } form = CollectionItemsForm(data=data, user=self.user) self.assertTrue(form.is_valid()) versions = form.clean_versions() self.assertQuerysetEqual( versions, Version.objects.filter(pk__in=[pg1_version.pk, pg2_version.pk]), transform=lambda x: x, ordered=False, )
def test_is_obj_version_unlocked_after_publish(self): self.assertIsNotNone(Version) version = PageVersionFactory(created_by=self.user) self.assertTrue(is_obj_version_unlocked(version.content, self.user)) self.assertFalse(is_obj_version_unlocked(version.content, self.user2)) version.publish(self.user) # reload version to update cache version = Version.objects.get_for_content(version.content) self.assertTrue(is_obj_version_unlocked(version.content, self.user2)) # Make sure that we are actually calling the version-lock method and it # still exists with mock.patch( "djangocms_moderation.helpers.content_is_unlocked_for_user" ) as _mock: is_obj_version_unlocked(version.content, self.user2) _mock.assert_called_once_with(version.content, self.user2)
def test_is_obj_version_unlocked_when_locking_is_not_installed(self): with mock.patch( "djangocms_moderation.helpers.content_is_unlocked_for_user" ) as _mock: _mock = None # noqa version = PageVersionFactory(created_by=self.user) self.assertTrue( is_obj_version_unlocked(version.content, self.user3))
def test_collection_choice_should_be_limited_to_current_user_and_collecting_status( self): user = User.objects.create_superuser(username="******", email="*****@*****.**", password="******") pg_version = PageVersionFactory(created_by=user) # Create valid collection collection1 = ModerationCollection.objects.create( author=user, name="Collection 1", status=constants.COLLECTING, workflow=self.wf1, ) collection2 = ModerationCollection.objects.create( author=user, name="Collection 2", status=constants.COLLECTING, workflow=self.wf2, ) # Now invalid collections, either with status in REVIEW, or different author collection3 = ModerationCollection.objects.create( author=user, name="Collection 3", status=constants.IN_REVIEW, workflow=self.wf3, ) collection4 = ModerationCollection.objects.create( author=self.user3, name="Collection 4", status=constants.COLLECTING, workflow=self.wf4, ) fixtures = ( # (collection, should_the_form_be_valid?) (collection1, True), (collection2, True), (collection3, False), (collection4, False), ) for fixture in fixtures: data = {"collection": fixture[0].pk, "versions": [pg_version]} form = CollectionItemsForm(data=data, user=user) self.assertEqual(form.is_valid(), fixture[1], "{} failed".format(fixture[0])) if not form.is_valid(): self.assertIn("collection", form.errors) self.assertQuerysetEqual( form.fields["collection"].queryset, ModerationCollection.objects.filter( pk__in=[collection1.pk, collection2.pk]), transform=lambda x: x, ordered=False, )
def test_submit_for_moderation_not_version_locked(self): user = self.get_superuser() version = PageVersionFactory(created_by=user) toolbar = self._get_toolbar(version.content, user=user, edit_mode=True) toolbar.populate() toolbar.post_template_populate() self.assertTrue( self._button_exists("Submit for moderation", toolbar.toolbar))
def test_publish_buttons_when_unregistered( self, mock_is_registered_for_moderation): mock_is_registered_for_moderation.return_value = False version = PageVersionFactory() toolbar = self._get_toolbar(version.content, edit_mode=True) toolbar.populate() toolbar.post_template_populate() self.assertTrue(self._button_exists("Publish", toolbar.toolbar))
def test_attempt_add_version_locked_version(self): pg_version_user2 = PageVersionFactory(created_by=self.user2) data = { "collection": self.collection1.pk, # pg_version_user2 is locked by user2 so it will be removed from the form during validation "versions": [pg_version_user2], } form = CollectionItemsForm(data=data, user=self.user) self.assertFalse(form.is_valid()) self.assertIn("versions", form.errors)
def test_submit_for_moderation_no_permission(self): user = self.get_standard_user() ModerationRequest.objects.all().delete() version = PageVersionFactory(created_by=user) toolbar = self._get_toolbar(version.content, user=user, edit_mode=True) toolbar.populate() toolbar.post_template_populate() self.assertFalse( self._button_exists("Submit for moderation", toolbar.toolbar))
def test_add_edit_buttons_when_unregistered( self, mock_is_registered_for_moderation): user = self.get_superuser() mock_is_registered_for_moderation.return_value = False version = PageVersionFactory(created_by=user) toolbar = self._get_toolbar(version.content, preview_mode=True, user=user) toolbar.populate() toolbar.post_template_populate() self.assertTrue(self._button_exists("Edit", toolbar.toolbar))
def test_get_title_cache(self): """Check that patched Page._get_title_cache fills the title_cache with _prefetched_objects_cache data. """ version = PageVersionFactory(content__language="en") page = version.content.page page._prefetched_objects_cache = {"pagecontent_set": [version.content]} page._get_title_cache(language="en", fallback=False, force_reload=False) self.assertEqual({"en": version.content}, page.title_cache)
def test_add_manage_collection_item_to_moderation_menu_no_permission(self): user = self.get_standard_user() version = PageVersionFactory(created_by=user) toolbar = self._get_toolbar(version.content, preview_mode=True, user=user) toolbar.populate() toolbar.post_template_populate() cms_toolbar = toolbar.toolbar manage_collection_item = self._find_menu_item( "Moderation collections...", cms_toolbar) self.assertIsNone(manage_collection_item)
def setUp(self): super().setUp() self._page_1 = PageVersionFactory( content__title="page_content_1", content__menu_title="", content__in_navigation=True, content__limit_visibility_in_menu=None, content__language="en", content__page__node__path="0001", ) self._page_2 = PageVersionFactory( content__title="page_content_2", content__menu_title="", content__in_navigation=True, content__limit_visibility_in_menu=None, content__language="en", content__page__node__path="0002", ) self._page_2_1 = PageVersionFactory( content__title="page_content_2_1", content__menu_title="", content__in_navigation=True, content__limit_visibility_in_menu=None, content__language="en", content__page__node__path="00020001", content__page__node__parent=self._page_2.content.page.node, ) self._page_2_2 = PageVersionFactory( content__title="page_content_2_2", content__menu_title="", content__in_navigation=True, content__limit_visibility_in_menu=None, content__language="en", content__page__node__path="00020002", content__page__node__parent=self._page_2.content.page.node, ) self._page_3 = PageVersionFactory( content__title="page_content_3", content__menu_title="", content__in_navigation=True, content__limit_visibility_in_menu=None, content__language="en", content__page__node__path="0003", )
def test_get_admin_model_object(self): """ PageContent normally won't be able to fetch objects in draft. With the mocked get_admin_model_object_by_id it is able to fetch objects in draft mode. """ from cms.utils.helpers import get_admin_model_object_by_id version = PageVersionFactory() content = get_admin_model_object_by_id(PageContent, version.content.pk) self.assertEqual(version.state, 'draft') self.assertEqual(content.pk, version.content.pk)
def setUp(self): self.user = self.get_superuser() page = PageFactory() self.source_version = PageVersionFactory(content__page=page, content__language="en") self.target_version = PageVersionFactory(content__page=page, content__language="it") # Add default placeholders source_placeholder = PlaceholderFactory( source=self.source_version.content, slot="content") self.source_version.content.placeholders.add(source_placeholder) target_placeholder = PlaceholderFactory( source=self.target_version.content, slot="content") self.target_version.content.placeholders.add(target_placeholder) # Populate only the source placeholder as this is what we will be copying! TextPluginFactory(placeholder=source_placeholder) # Use the endpoint that the toolbar copy uses, this indirectly runs the monkey patched logic! # Simulating the user selecting in the Language menu "Copy all plugins" in the Versioned Page toolbar self.copy_url = admin_reverse('cms_pagecontent_copy_language', args=(self.source_version.content.pk, )) self.copy_url_data = {'source_language': "en", 'target_language': "it"}
def setUp(self): super().setUp() self._page_1 = PageVersionFactory( content__title='page_content_1', content__menu_title='', content__in_navigation=True, content__limit_visibility_in_menu=None, content__language='en', content__page__node__path='0001', ) self._page_2 = PageVersionFactory( content__title='page_content_2', content__menu_title='', content__in_navigation=True, content__limit_visibility_in_menu=None, content__language='en', content__page__node__path='0002', ) self._page_2_1 = PageVersionFactory( content__title='page_content_2_1', content__menu_title='', content__in_navigation=True, content__limit_visibility_in_menu=None, content__language='en', content__page__node__path='00020001', content__page__node__parent=self._page_2.content.page.node, ) self._page_2_2 = PageVersionFactory( content__title='page_content_2_2', content__menu_title='', content__in_navigation=True, content__limit_visibility_in_menu=None, content__language='en', content__page__node__path='00020002', content__page__node__parent=self._page_2.content.page.node, ) self._page_3 = PageVersionFactory( content__title='page_content_3', content__menu_title='', content__in_navigation=True, content__limit_visibility_in_menu=None, content__language='en', content__page__node__path='0003', )