def test_menuitem_change_view_redirects_if_not_latest_version_post( self, mocked_messages ): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, content__language="en", state=UNPUBLISHED) factories.MenuVersionFactory(content__menu=menu, content__language="en", state=PUBLISHED) factories.MenuVersionFactory(content__menu=menu, content__language="en", state=DRAFT) item = factories.ChildMenuItemFactory(parent=version.content.root) change_url = reverse( "admin:djangocms_navigation_menuitem_change", kwargs={"menu_content_id": version.content.pk, "object_id": item.pk}, ) content_type = ContentType.objects.get(app_label="cms", model="page") data = { "title": "My new Title", "content_type": content_type.pk, "object_id": item.content.pk, "_ref_node_id": version.content.root.id, "numchild": 1, "link_target": "_blank", "_position": "first-child", } response = self.client.post(change_url, data) # Redirect happened and error message displayed self.assertRedirectsToVersionList(response, version.content) self.assertDjangoErrorMessage("Version is not a draft", mocked_messages) # Menu item object was not changed item.refresh_from_db() self.assertNotEqual(item.title, "My new Title")
def test_menuitem_add_view_redirects_if_not_latest_version_post( self, mocked_messages ): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, state=UNPUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=PUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=DRAFT) add_url = reverse( "admin:djangocms_navigation_menuitem_add", args=(version.content.id,) ) content_type = ContentType.objects.get(app_label="cms", model="page") page = factories.PageContentFactory().page data = { "title": "My new Title", "content_type": content_type.pk, "object_id": page.pk, "_ref_node_id": version.content.root.id, "numchild": 1, "link_target": "_blank", "_position": "first-child", } response = self.client.post(add_url, data) # Redirect happened and error message displayed self.assertRedirectsToVersionList(response, version.content) self.assertDjangoErrorMessage("Version is not a draft", mocked_messages) # Menu item object was not added self.assertEqual(MenuItem.objects.filter(title="My new Title").count(), 0)
def test_menuitem_move_node_permission_denied_if_not_latest_version( self, mocked_messages ): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, state=UNPUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=PUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=DRAFT) child = factories.ChildMenuItemFactory(parent=version.content.root) child_of_child = factories.ChildMenuItemFactory(parent=child) move_url = reverse( "admin:djangocms_navigation_menuitem_move_node", args=(version.content.id,) ) data = { "node_id": child_of_child.pk, "sibling_id": version.content.root.pk, "as_child": 1, } response = self.client.post(move_url, data=data) # 400 error with error msg and node has not been moved self.assertEqual(response.status_code, 400) self.assertEqual(b"Version is not a draft", response.content) child.refresh_from_db() child_of_child.refresh_from_db() self.assertFalse(child_of_child.is_sibling_of(child))
def test_preview_link(self): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, state=UNPUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=PUBLISHED) menu_content = version.content preview_endpoint = reverse("admin:djangocms_navigation_menuitem_preview", args=(version.pk,),) func = self.modeladmin._list_actions(self.get_request("/admin")) response = func(menu_content) self.assertIn("cms-versioning-action-preview", response) self.assertIn('title="Preview"', response) self.assertIn(preview_endpoint, response)
def test_menuitem_changelist_redirects_if_not_latest_version(self, mocked_messages): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, state=UNPUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=PUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=DRAFT) list_url = reverse( "admin:djangocms_navigation_menuitem_list", args=(version.content.id,) ) response = self.client.get(list_url) # Redirect happened and error message displayed self.assertRedirectsToVersionList(response, version.content) self.assertDjangoErrorMessage("Version is not a draft", mocked_messages)
def test_list_display_without_version_locking(self): request = self.get_request("/") request.user = self.get_superuser() nav_admin.using_version_lock = False site_2 = Site.objects.create(domain="site_2.com", name="site_2") menu_1 = factories.MenuFactory(site=site_2) site_2_menu_version = factories.MenuVersionFactory(content__menu=menu_1, state=PUBLISHED) menu_content_admin = nav_admin.MenuContentAdmin(MenuContent, admin.AdminSite()) func = menu_content_admin._list_actions(request) list_display_icons = func(site_2_menu_version.content) list_display = menu_content_admin.get_list_display(request) list_display[-1] = list_display_icons self.assertEqual(len(list_display), 5) self.assertEqual( list_display[0:4], ["title", "get_author", "get_modified_date", "get_versioning_state"] ) self.assertIn("cms-versioning-action-btn", list_display[-1]) # The preview button is present self.assertIn("cms-versioning-action-preview", list_display[-1]) # The edit button is present self.assertIn("cms-versioning-action-edit", list_display[-1]) self.assertIn("cms-form-get-method", list_display[-1]) self.assertIn("js-versioning-action", list_display[-1]) self.assertIn("js-versioning-admin-keep-sideframe", list_display[-1])
def test_navigation_compare_view(self): """ When comparing navigation content, the original and new version should be in the context """ original_root = factories.RootMenuItemFactory() original_version = factories.MenuVersionFactory( content__root=original_root) original_child = factories.ChildMenuItemFactory(parent=original_root, soft_root=True, hide_node=True) new_version = original_version.copy(self.user) new_root = new_version.content.root # If this throws DoesNotExist then the child clearly wasn't duplicated MenuItem.objects.exclude( pk__in=[original_root.pk, original_child.pk, new_root.pk]).get() endpoint = "/en/admin/djangocms_versioning/menucontentversion/" endpoint += "%d/compare/?compare_to=%d" % (new_version.pk, original_version.pk) with self.login_user_context(self.user): response = self.client.get(endpoint) self.assertEqual(response.status_code, 200) self.assertContains(response, "Comparing Version #{}".format(new_version.number)) self.assertContains(response, "Version #{}".format(new_version.number)) self.assertContains(response, "Version #{}".format(original_version.number))
def test_select_node_from_deeply_nested_nodes(self): """ Performance check to retrieve a page from node with and without soft_root node """ page_content = factories.PageContentWithVersionFactory( version__created_by=self.get_superuser(), title="test", menu_title="test", page_title="test", version__state=PUBLISHED) menuversions = factories.MenuVersionFactory( state=PUBLISHED, content__language=self.language) factories.ChildMenuItemFactory(parent=menuversions.content.root, content=page_content.page) factories.ChildMenuItemFactory(parent=menuversions.content.root) child3 = factories.ChildMenuItemFactory( parent=menuversions.content.root) factories.ChildMenuItemFactory(parent=child3) max_queries = 52 page_url = page_content.page.get_absolute_url() with self.assertNumQueries(FuzzyInt(3, max_queries)): self.client.get(page_url) child3.soft_root = True with self.assertNumQueries(FuzzyInt(3, max_queries)): self.client.get(page_url)
def test_very_nested_menu_items_are_copied(self): """The implementation of versioning for MenuContent correctly copies very nested MenuItem structures """ original_version = factories.MenuVersionFactory() original_item1 = factories.ChildMenuItemFactory( parent=original_version.content.root) original_item2 = factories.SiblingMenuItemFactory( sibling=original_item1) original_item11 = factories.ChildMenuItemFactory(parent=original_item1) original_item111 = factories.ChildMenuItemFactory( parent=original_item11) factories.ChildMenuItemFactory(parent=original_item11) factories.ChildMenuItemFactory(parent=original_item111) original_item21 = factories.ChildMenuItemFactory(parent=original_item2) factories.SiblingMenuItemFactory(sibling=original_item21) new_version = original_version.copy(self.user) root_path = new_version.content.root.path expected_paths = [ root_path + item.path[4:] for item in MenuItem.get_tree(original_version.content.root) ] new_paths = [ item.path for item in MenuItem.get_tree(new_version.content.root) ] self.assertListEqual(new_paths, expected_paths)
def test_sibling_menu_items_are_copied(self): """The implementation of versioning for MenuContent correctly copies sibling MenuItem objects """ original_root = factories.RootMenuItemFactory() original_version = factories.MenuVersionFactory( content__root=original_root) original_child = factories.ChildMenuItemFactory(parent=original_root) original_sibling = factories.SiblingMenuItemFactory( sibling=original_child, hide_node=True) new_version = original_version.copy(self.user) new_root = new_version.content.root # If this throws DoesNotExist then the sibling clearly wasn't duplicated new_sibling = MenuItem.objects.get(path=new_root.path + original_sibling.path[4:]) # The fields in the sibling have been copied over correctly self.assertEqual(new_sibling.title, original_sibling.title) self.assertEqual(new_sibling.content, original_sibling.content) self.assertEqual(new_sibling.link_target, original_sibling.link_target) self.assertEqual(new_sibling.soft_root, original_sibling.soft_root) self.assertEqual(new_sibling.hide_node, original_sibling.hide_node) # The new sibling is indeed a sibling node of the new child new_child = MenuItem.objects.get(path=new_root.path + original_child.path[4:]) self.assertTrue(new_child.is_sibling_of(new_child))
def test_child_menu_items_are_copied(self): """The implementation of versioning for MenuContent correctly copies child MenuItem objects """ original_root = factories.RootMenuItemFactory() original_version = factories.MenuVersionFactory( content__root=original_root) original_child = factories.ChildMenuItemFactory(parent=original_root, soft_root=True, hide_node=True) new_version = original_version.copy(self.user) new_root = new_version.content.root # If this throws DoesNotExist then the child clearly wasn't duplicated new_child = MenuItem.objects.exclude( pk__in=[original_root.pk, original_child.pk, new_root.pk]).get() # The fields in the child have been copied over correctly self.assertEqual(new_child.title, original_child.title) self.assertEqual(new_child.content, original_child.content) self.assertEqual(new_child.link_target, original_child.link_target) self.assertEqual(new_child.soft_root, original_child.soft_root) self.assertEqual(new_child.hide_node, original_child.hide_node) # The new child is indeed a child node of the new root self.assertTrue(new_child.is_child_of(new_root))
def test_get_roots_with_draft_mode_not_active(self): """This test to check versioning would group all the versions of menu content and return latest of all distinct menu content when renderer draft_mode_active is false """ menucontent_1_v1 = factories.MenuVersionFactory(state=ARCHIVED) menucontent_1_v2 = factories.MenuVersionFactory( content__menu=menucontent_1_v1.content.menu, state=DRAFT) menucontent_2_v1 = factories.MenuVersionFactory(state=PUBLISHED) menucontent_3_v1 = factories.MenuVersionFactory(state=UNPUBLISHED) # Assert to check draft_mode_active is false self.assertFalse(self.menu.renderer.draft_mode_active) roots = self.menu.get_roots(self.request) # Renderer should only render published menucontent self.assertEqual(roots.count(), 1) self.assertListEqual(list(roots), [menucontent_2_v1.content.root])
def test_edit_link_not_shown(self): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, state=UNPUBLISHED) func = self.modeladmin._list_actions(self.get_request("/")) response = func(version.content) self.assertNotIn("cms-versioning-action-edit ", response)
def test_menuitem_change_view_redirects_if_not_latest_version_get( self, mocked_messages ): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, state=UNPUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=PUBLISHED) factories.MenuVersionFactory(content__menu=menu, state=DRAFT) item = factories.ChildMenuItemFactory(parent=version.content.root) change_url = reverse( "admin:djangocms_navigation_menuitem_change", kwargs={"menu_content_id": version.content.pk, "object_id": item.pk}, ) response = self.client.get(change_url) # Redirect happened and error message displayed self.assertRedirectsToVersionList(response, version.content) self.assertDjangoErrorMessage("Version is not a draft", mocked_messages)
def test_menucontent_change_view_limited_to_site(self): """ The admin change list is limited to show only the menus for the current site. No other menus should be shown that belong to other sites. """ site_2 = Site.objects.create(domain="site_2.com", name="site_2") site_3 = Site.objects.create(domain="site_3.com", name="site_3") menu_1 = factories.MenuFactory(site=site_2) menu_2 = factories.MenuFactory(site=site_3) site_2_menu_version = factories.MenuVersionFactory( content__menu=menu_1, state=PUBLISHED) site_3_menu_version = factories.MenuVersionFactory( content__menu=menu_2, state=PUBLISHED) menu_content_admin = self.admin_site._registry[MenuContent] # Site 1 has no menus and should be empty with self.settings(SITE_ID=1): request = RequestFactory().get( "/admin/djangocms_navigation/menucontent/") site1_query_result = menu_content_admin.get_queryset(request) self.assertEqual(site1_query_result.count(), 0) # Site 2 has a menu and should it should only be the one created for that site with self.settings(SITE_ID=site_2.pk): request = RequestFactory().get( "/admin/djangocms_navigation/menucontent/") request.site = site_2 site2_query_result = menu_content_admin.get_queryset(request) self.assertEqual(site2_query_result.count(), 1) self.assertEqual(site2_query_result.first(), site_2_menu_version.content) # Site 3 has a menu and should it should only be the one created for that site with self.settings(SITE_ID=site_3.pk): request = RequestFactory().get( "/admin/djangocms_navigation/menucontent/") request.site = site_3 site3_query_result = menu_content_admin.get_queryset(request) self.assertEqual(site3_query_result.count(), 1) self.assertEqual(site3_query_result.first(), site_3_menu_version.content)
def test_get_roots_with_draft_mode_active(self): """This test to check versioning would group all the versions of menu content and return latest of all distinct menu content when renderer draft_mode_active is True """ menucontent_1_v1 = factories.MenuVersionFactory(state=ARCHIVED) menucontent_1_v2 = factories.MenuVersionFactory( content__menu=menucontent_1_v1.content.menu, state=DRAFT) menucontent_2_v1 = factories.MenuVersionFactory(state=PUBLISHED) menucontent_3_v1 = factories.MenuVersionFactory(state=UNPUBLISHED) # Getting renderer to set draft_mode_active renderer = self.renderer renderer.draft_mode_active = True menu = CMSMenu(renderer) roots = menu.get_roots(self.request) self.assertEqual(roots.count(), 2) self.assertListEqual( list(roots), [menucontent_1_v2.content.root, menucontent_2_v1.content.root])
def test_edit_link_inactive(self): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, state=DRAFT) request = self.get_request("/") func = self.modeladmin._list_actions(request) edit_endpoint = reverse("admin:djangocms_versioning_menucontentversion_edit_redirect", args=(version.pk,),) response = func(version.content) self.assertIn("inactive", response) self.assertIn('title="Edit"', response) self.assertNotIn(edit_endpoint, response)
def test_edit_link(self): menu = factories.MenuFactory() request = self.get_request("/") request.user = self.get_superuser() version = factories.MenuVersionFactory(content__menu=menu, state=DRAFT, created_by=request.user) menu_content = version.content func = self.modeladmin._list_actions(request) edit_endpoint = reverse("admin:djangocms_versioning_menucontentversion_edit_redirect", args=(version.pk,),) response = func(menu_content) self.assertIn("cms-versioning-action-btn", response) self.assertIn('title="Edit"', response) self.assertIn(edit_endpoint, response)
def test_menu_cache_invalidate_after_menucontent_unpublish(self): # NOTE: This test is based on a similar one from django-cms: # https://github.com/divio/django-cms/blob/2daeb7d63cb5fee49575a834d0f23669ce46144e/cms/tests/test_plugins.py#L160 # Set up a versioned page with one placeholder page_content = factories.PageContentWithVersionFactory( language=self.language, version__created_by=self.get_superuser()) placeholder = factories.PlaceholderFactory(source=page_content) menu_content_version = factories.MenuVersionFactory( content__language=self.language) menu_content = menu_content_version.content child = factories.ChildMenuItemFactory(parent=menu_content.root) # grandchild factories.ChildMenuItemFactory(parent=child) menu_content_version.publish(user=self.get_superuser()) # TODO: Use a factory instead # Add nav plugin to placeholder self._add_nav_plugin_and_assert(placeholder, menu_content.menu, "menu/menu.html") # Now publish the page content containing the plugin, # so the page can be viewed version = page_content.versions.get() version.publish(self.get_superuser()) # Making sure there is no cachekey existed before rendering page cache_key = CacheKey.objects.all().count() self.assertEqual(cache_key, 0) # And view the page page_url = page_content.page.get_absolute_url() response = self.client.get(page_url) cache_key = CacheKey.objects.all().count() self.assertEqual(response.status_code, 200) # Rendering should generate cachekey object self.assertEqual(cache_key, 1) menu_content_version.unpublish(user=self.get_superuser()) # Version unpublish action should be invalidated cache_key object cache_key = CacheKey.objects.all().count() self.assertEqual(cache_key, 0)
def test_menu_content_object_gets_duplicated_with_its_root_menuitem(self): """The implementation of versioning for MenuContent correctly copies the MenuContent object and the root MenuItem object """ original_version = factories.MenuVersionFactory() new_version = original_version.copy(self.user) # Created a new content record self.assertNotEqual(original_version.content.pk, new_version.content.pk) # Is version of the same menu as the original version self.assertEqual(original_version.content.menu, new_version.content.menu) # The root MenuItem has been duplicated into a new MenuItem original_root = original_version.content.root new_root = new_version.content.root self.assertNotEqual(original_root.pk, new_root.pk) self.assertEqual(original_root.title, new_root.title) self.assertIsNone(new_root.content) # The root is indeed a root node self.assertTrue(new_root.is_root())
def test_menuitem_changelist_should_have_get_url_column(self): menu = factories.MenuFactory() version = factories.MenuVersionFactory(content__menu=menu, state=PUBLISHED) mock_request = RequestFactory() ma = MenuItemAdmin(MenuItem, admin.AdminSite()) add_url = reverse( "admin:djangocms_navigation_menuitem_add", args=(version.content.id,) ) content_type = ContentType.objects.get(app_label="cms", model="page") page = factories.PageContentFactory().page data = { "title": "My new Title", "content_type": content_type.pk, "object_id": page.pk, "_ref_node_id": version.content.root.id, "numchild": 1, "link_target": "_blank", "_position": "first-child", } self.client.post(add_url, data) self.assertEqual(len(ma.get_list_display(mock_request)), 4) self.assertIn("get_object_url", ma.get_list_display(mock_request))