Initial commit
This commit is contained in:
404
env/lib/python3.10/site-packages/wagtail/admin/tests/test_dashboard.py
vendored
Normal file
404
env/lib/python3.10/site-packages/wagtail/admin/tests/test_dashboard.py
vendored
Normal file
@@ -0,0 +1,404 @@
|
||||
from django.contrib.auth import get_user_model
|
||||
from django.contrib.auth.models import Group, Permission
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
from django.utils import timezone
|
||||
from freezegun import freeze_time
|
||||
|
||||
from wagtail.admin.views.home import (
|
||||
LockedPagesPanel,
|
||||
RecentEditsPanel,
|
||||
UserObjectsInWorkflowModerationPanel,
|
||||
WorkflowObjectsToModeratePanel,
|
||||
)
|
||||
from wagtail.coreutils import get_dummy_request
|
||||
from wagtail.models import GroupPagePermission, Page, Workflow, WorkflowContentType
|
||||
from wagtail.test.testapp.models import FullFeaturedSnippet, SimplePage
|
||||
from wagtail.test.utils import WagtailTestUtils
|
||||
|
||||
|
||||
class TestRecentEditsPanel(WagtailTestUtils, TestCase):
|
||||
def setUp(self):
|
||||
# Find root page
|
||||
self.root_page = Page.objects.get(id=2)
|
||||
|
||||
# Add child page
|
||||
child_page = SimplePage(
|
||||
title="Hello world!",
|
||||
slug="hello-world",
|
||||
content="Some content here",
|
||||
)
|
||||
self.root_page.add_child(instance=child_page)
|
||||
self.revision = child_page.save_revision()
|
||||
self.revision.publish()
|
||||
self.child_page = SimplePage.objects.get(id=child_page.id)
|
||||
|
||||
self.user_alice = self.create_superuser(username="alice", password="password")
|
||||
self.create_superuser(username="bob", password="password")
|
||||
|
||||
def change_something(self, title):
|
||||
post_data = {"title": title, "content": "Some content", "slug": "hello-world"}
|
||||
response = self.client.post(
|
||||
reverse("wagtailadmin_pages:edit", args=(self.child_page.id,)), post_data
|
||||
)
|
||||
|
||||
# Should be redirected to edit page
|
||||
self.assertRedirects(
|
||||
response, reverse("wagtailadmin_pages:edit", args=(self.child_page.id,))
|
||||
)
|
||||
|
||||
# The page should have "has_unpublished_changes" flag set
|
||||
child_page_new = SimplePage.objects.get(id=self.child_page.id)
|
||||
self.assertTrue(child_page_new.has_unpublished_changes)
|
||||
|
||||
def go_to_dashboard_response(self):
|
||||
response = self.client.get(reverse("wagtailadmin_home"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
return response
|
||||
|
||||
def test_your_recent_edits(self):
|
||||
# Login as Bob
|
||||
self.login(username="bob", password="password")
|
||||
|
||||
# Bob hasn't edited anything yet
|
||||
response = self.client.get(reverse("wagtailadmin_home"))
|
||||
self.assertNotIn("Your most recent edits", response.content.decode("utf-8"))
|
||||
|
||||
# Login as Alice
|
||||
self.client.logout()
|
||||
self.login(username="alice", password="password")
|
||||
|
||||
# Alice changes something
|
||||
self.change_something("Alice's edit")
|
||||
|
||||
# Edit should show up on dashboard
|
||||
response = self.go_to_dashboard_response()
|
||||
self.assertIn("Your most recent edits", response.content.decode("utf-8"))
|
||||
|
||||
# Bob changes something
|
||||
self.login(username="bob", password="password")
|
||||
self.change_something("Bob's edit")
|
||||
|
||||
# Edit shows up on Bobs dashboard
|
||||
response = self.go_to_dashboard_response()
|
||||
self.assertIn("Your most recent edits", response.content.decode("utf-8"))
|
||||
|
||||
# Login as Alice again
|
||||
self.client.logout()
|
||||
self.login(username="alice", password="password")
|
||||
|
||||
# Alice's dashboard should still list that first edit
|
||||
response = self.go_to_dashboard_response()
|
||||
self.assertIn("Your most recent edits", response.content.decode("utf-8"))
|
||||
|
||||
def test_missing_page_record(self):
|
||||
# Ensure that the panel still renders when one of the page IDs returned from querying
|
||||
# PageLogEntry has no corresponding Page object. This can happen if a page is deleted,
|
||||
# because PageLogEntry records are kept on deletion.
|
||||
|
||||
self.login(username="alice", password="password")
|
||||
self.change_something("Alice's edit")
|
||||
self.child_page.delete()
|
||||
response = self.client.get(reverse("wagtailadmin_home"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
|
||||
def test_panel(self):
|
||||
"""Test if the panel actually returns expected pages"""
|
||||
self.login(username="bob", password="password")
|
||||
# change a page
|
||||
|
||||
edit_timestamp = timezone.now()
|
||||
with freeze_time(edit_timestamp):
|
||||
self.change_something("Bob's edit")
|
||||
|
||||
# set a user to 'mock' a request
|
||||
self.client.user = get_user_model().objects.get(email="bob@example.com")
|
||||
# get the panel to get the last edits
|
||||
panel = RecentEditsPanel()
|
||||
ctx = panel.get_context_data({"request": self.client})
|
||||
|
||||
page = Page.objects.get(pk=self.child_page.id).specific
|
||||
|
||||
# check the timestamp matches the edit
|
||||
self.assertEqual(ctx["last_edits"][0][0], edit_timestamp)
|
||||
# check if the page in this list is the specific page
|
||||
self.assertEqual(ctx["last_edits"][0][1], page)
|
||||
|
||||
def test_copying_does_not_count_as_an_edit(self):
|
||||
self.login(username="bob", password="password")
|
||||
# change a page
|
||||
self.change_something("Bob was ere")
|
||||
|
||||
# copy the page
|
||||
post_data = {
|
||||
"new_title": "Goodbye world!",
|
||||
"new_slug": "goodbye-world",
|
||||
"new_parent_page": str(self.root_page.id),
|
||||
"copy_subpages": False,
|
||||
"alias": False,
|
||||
}
|
||||
self.client.post(
|
||||
reverse("wagtailadmin_pages:copy", args=(self.child_page.id,)), post_data
|
||||
)
|
||||
# check that page has been copied
|
||||
self.assertTrue(Page.objects.get(title="Goodbye world!"))
|
||||
|
||||
response = self.client.get(reverse("wagtailadmin_home"))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertContains(response, "Your most recent edits")
|
||||
self.assertContains(response, "Bob was ere")
|
||||
self.assertNotContains(response, "Goodbye world!")
|
||||
|
||||
|
||||
class TestRecentEditsQueryCount(WagtailTestUtils, TestCase):
|
||||
fixtures = ["test.json"]
|
||||
|
||||
def setUp(self):
|
||||
self.bob = self.create_superuser(username="bob", password="password")
|
||||
self.dummy_request = get_dummy_request()
|
||||
self.dummy_request.user = self.bob
|
||||
workflow = Workflow.objects.first()
|
||||
workflow_pages = {5, 6}
|
||||
locked_pages = {6, 9}
|
||||
scheduled_pages = {9, 12}
|
||||
# make a bunch of page edits (all to EventPages, so that calls to specific() don't add
|
||||
# an unpredictable number of queries)
|
||||
pages_to_edit = list(
|
||||
Page.objects.filter(id__in=[4, 5, 6, 9, 12, 13]).order_by("pk").specific()
|
||||
)
|
||||
for page in pages_to_edit:
|
||||
revision = page.save_revision(user=self.bob, log_action=True)
|
||||
if page.pk in workflow_pages:
|
||||
workflow.start(page, self.bob)
|
||||
if page.pk in locked_pages:
|
||||
page.locked = True
|
||||
page.locked_by = self.bob
|
||||
page.locked_at = timezone.now()
|
||||
page.save()
|
||||
if page.pk in scheduled_pages:
|
||||
revision.approved_go_live_at = timezone.now()
|
||||
revision.save()
|
||||
|
||||
def test_panel_query_count(self):
|
||||
panel = RecentEditsPanel()
|
||||
parent_context = {"request": self.dummy_request}
|
||||
# Warm up the cache
|
||||
html = panel.render_html(parent_context)
|
||||
|
||||
with self.assertNumQueries(5):
|
||||
# Rendering RecentEditsPanel should not generate N+1 queries -
|
||||
# i.e. any number less than 6 would be reasonable here
|
||||
html = panel.render_html(parent_context)
|
||||
# check that the panel is still actually returning results
|
||||
self.assertIn("Ameristralia Day", html)
|
||||
soup = self.get_soup(html)
|
||||
self.assertEqual(len(soup.select('svg use[href="#icon-lock"]')), 2)
|
||||
expected_statuses = [
|
||||
"live + draft",
|
||||
"live + scheduled",
|
||||
"live + scheduled",
|
||||
"in moderation",
|
||||
"in moderation",
|
||||
]
|
||||
statuses = [
|
||||
"".join(e.find_all(string=True, recursive=False)).strip()
|
||||
for e in soup.select(".w-status")
|
||||
]
|
||||
self.assertEqual(statuses, expected_statuses)
|
||||
|
||||
|
||||
class TestLockedPagesQueryCount(WagtailTestUtils, TestCase):
|
||||
fixtures = ["test.json"]
|
||||
|
||||
def setUp(self):
|
||||
self.bob = self.create_superuser(username="bob", password="password")
|
||||
self.dummy_request = get_dummy_request()
|
||||
self.dummy_request.user = self.bob
|
||||
|
||||
pages = Page.objects.filter(pk__in=[9, 12, 13]).order_by("pk")
|
||||
for i, page in enumerate(pages):
|
||||
page.locked = True
|
||||
page.locked_by = self.bob
|
||||
page.locked_at = timezone.now() + timezone.timedelta(hours=i)
|
||||
page.save()
|
||||
|
||||
def test_panel_query_count(self):
|
||||
panel = LockedPagesPanel()
|
||||
parent_context = {"request": self.dummy_request, "csrf_token": "dummy"}
|
||||
# Warm up the cache
|
||||
html = panel.render_html(parent_context)
|
||||
|
||||
with self.assertNumQueries(1):
|
||||
html = panel.render_html(parent_context)
|
||||
soup = self.get_soup(html)
|
||||
# Should be sorted descending by locked_at
|
||||
expected_titles = [
|
||||
"Saint Patrick (single event)",
|
||||
"Steal underpants",
|
||||
"Ameristralia Day",
|
||||
]
|
||||
titles = [e.get_text(strip=True) for e in soup.select(".title-wrapper a")]
|
||||
self.assertEqual(titles, expected_titles)
|
||||
|
||||
|
||||
class UserObjectsInWorkflowModerationQueryCount(WagtailTestUtils, TestCase):
|
||||
fixtures = ["test.json"]
|
||||
|
||||
def setUp(self):
|
||||
self.superuser = self.create_superuser(username="admin", password="password")
|
||||
self.bob = self.create_user(username="bob", password="password")
|
||||
self.someone_else = self.create_user(
|
||||
username="someoneelse", password="password"
|
||||
)
|
||||
editors = Group.objects.get(name="Editors")
|
||||
editors.user_set.add(self.bob, self.someone_else)
|
||||
|
||||
workflow = Workflow.objects.first()
|
||||
WorkflowContentType.objects.create(
|
||||
workflow=workflow,
|
||||
content_type=ContentType.objects.get_for_model(FullFeaturedSnippet),
|
||||
)
|
||||
GroupPagePermission.objects.create(
|
||||
group=editors, page=Page.get_first_root_node(), permission_type="change"
|
||||
)
|
||||
editors.permissions.add(
|
||||
Permission.objects.get(codename="change_fullfeaturedsnippet")
|
||||
)
|
||||
|
||||
# Pages owned by bob, but workflow started by someone else
|
||||
Page.objects.filter(id__in=[9, 12]).update(owner=self.bob)
|
||||
for page in Page.objects.filter(id__in=[9, 12]).specific():
|
||||
page.save_revision()
|
||||
workflow.start(page, self.someone_else)
|
||||
# Lock it to test the lock indicator
|
||||
page.locked = True
|
||||
page.locked_by = self.superuser
|
||||
page.locked_at = timezone.now()
|
||||
page.save()
|
||||
|
||||
# Page workflow started by bob
|
||||
for page in Page.objects.filter(id__in=[4, 13]).specific():
|
||||
page.save_revision()
|
||||
workflow.start(page, self.bob)
|
||||
|
||||
# Snippet workflow started by bob
|
||||
for i in range(1, 3):
|
||||
obj = FullFeaturedSnippet.objects.create(text=f"Some obj {i}")
|
||||
obj.save_revision()
|
||||
workflow.start(obj, self.bob)
|
||||
|
||||
self.dummy_request = get_dummy_request()
|
||||
self.dummy_request.user = self.bob
|
||||
|
||||
def test_panel_query_count(self):
|
||||
panel = UserObjectsInWorkflowModerationPanel()
|
||||
parent_context = {"request": self.dummy_request}
|
||||
# Warm up the cache
|
||||
html = panel.render_html(parent_context)
|
||||
|
||||
with self.assertNumQueries(4):
|
||||
html = panel.render_html(parent_context)
|
||||
|
||||
soup = self.get_soup(html)
|
||||
self.assertEqual(len(soup.select('svg use[href="#icon-lock"]')), 2)
|
||||
expected_titles = [
|
||||
"Some obj 2",
|
||||
"Some obj 1",
|
||||
"Saint Patrick (single event)",
|
||||
"Christmas",
|
||||
"Steal underpants",
|
||||
"Ameristralia Day",
|
||||
]
|
||||
titles = [e.get_text(strip=True) for e in soup.select(".title-wrapper a")]
|
||||
self.assertEqual(titles, expected_titles)
|
||||
|
||||
|
||||
class WorkflowObjectsToModerateQueryCount(WagtailTestUtils, TestCase):
|
||||
fixtures = ["test.json"]
|
||||
|
||||
def setUp(self):
|
||||
self.superuser = self.create_superuser(username="admin", password="password")
|
||||
self.bob = self.create_user(username="bob", password="password")
|
||||
self.moderator = self.create_user(username="moderator", password="password")
|
||||
|
||||
editors = Group.objects.get(name="Editors")
|
||||
moderators = Group.objects.get(name="Moderators")
|
||||
|
||||
editors.user_set.add(self.bob)
|
||||
moderators.user_set.add(self.moderator)
|
||||
|
||||
root = Page.get_first_root_node()
|
||||
GroupPagePermission.objects.create(
|
||||
group=editors, page=root, permission_type="change"
|
||||
)
|
||||
GroupPagePermission.objects.create(
|
||||
group=moderators, page=root, permission_type="change"
|
||||
)
|
||||
GroupPagePermission.objects.create(
|
||||
group=moderators, page=root, permission_type="publish"
|
||||
)
|
||||
|
||||
editors.permissions.add(
|
||||
Permission.objects.get(codename="change_fullfeaturedsnippet")
|
||||
)
|
||||
moderators.permissions.add(
|
||||
*Permission.objects.filter(
|
||||
codename__in=[
|
||||
"change_fullfeaturedsnippet",
|
||||
"publish_fullfeaturedsnippet",
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
workflow = Workflow.objects.first()
|
||||
WorkflowContentType.objects.create(
|
||||
workflow=workflow,
|
||||
content_type=ContentType.objects.get_for_model(FullFeaturedSnippet),
|
||||
)
|
||||
|
||||
# Pages workflow started by bob and locked by moderator
|
||||
for page in Page.objects.filter(id__in=[9, 12]).specific():
|
||||
page.save_revision()
|
||||
workflow.start(page, self.bob)
|
||||
# Lock it to test the lock indicator
|
||||
page.locked = True
|
||||
page.locked_by = self.moderator
|
||||
page.locked_at = timezone.now()
|
||||
page.save()
|
||||
|
||||
# Page workflow started by bob
|
||||
for page in Page.objects.filter(id__in=[4, 13]).specific():
|
||||
page.save_revision()
|
||||
workflow.start(page, self.bob)
|
||||
|
||||
# Snippet workflow started by bob
|
||||
for i in range(1, 3):
|
||||
obj = FullFeaturedSnippet.objects.create(text=f"Some obj {i}")
|
||||
obj.save_revision()
|
||||
workflow.start(obj, self.bob)
|
||||
|
||||
self.dummy_request = get_dummy_request()
|
||||
self.dummy_request.user = self.moderator
|
||||
|
||||
def test_panel_query_count(self):
|
||||
panel = WorkflowObjectsToModeratePanel()
|
||||
parent_context = {"request": self.dummy_request, "csrf_token": "dummy"}
|
||||
# Warm up the cache
|
||||
html = panel.render_html(parent_context)
|
||||
|
||||
with self.assertNumQueries(13):
|
||||
html = panel.render_html(parent_context)
|
||||
|
||||
soup = self.get_soup(html)
|
||||
self.assertEqual(len(soup.select('svg use[href="#icon-lock"]')), 2)
|
||||
expected_titles = [
|
||||
"Some obj 2",
|
||||
"Some obj 1",
|
||||
"Saint Patrick (single event)",
|
||||
"Christmas",
|
||||
"Steal underpants",
|
||||
"Ameristralia Day",
|
||||
]
|
||||
titles = [e.get_text(strip=True) for e in soup.select(".title-wrapper a")]
|
||||
self.assertEqual(titles, expected_titles)
|
||||
Reference in New Issue
Block a user