Don't prevent reordering of subpages when there are no 'creatable' page types: That mechanism is to prevent manual creation, but it doesn't mean that children aren't editable

pull/12213/head
Andy Babic 2024-05-10 12:13:25 +01:00 zatwierdzone przez Matt Westcott
rodzic d327a0dd50
commit 3935770020
6 zmienionych plików z 229 dodań i 4 usunięć

Wyświetl plik

@ -2,7 +2,12 @@ from django.test import TestCase
from django.urls import reverse
from wagtail.models import Page
from wagtail.test.testapp.models import BusinessChild, BusinessIndex, SimplePage
from wagtail.test.testapp.models import (
BusinessChild,
BusinessIndex,
NoCreatableSubpageTypesPage,
SimplePage,
)
from wagtail.test.utils import WagtailTestUtils
@ -140,3 +145,45 @@ class TestPageReorderWithParentPageRestrictions(TestPageReorder):
# Login
self.user = self.login()
class TestPageReorderWithNoCreatableSubPageTypes(TestPageReorder):
"""
This TestCase is the same as the TestPageReorder class above, but uses a
NoCreatableSubpageTypesPage instance as the parent page instead of SimplePage.
This ensures that a parent page having no 'creatable' page types in
its `subpage_types` list does not prevent the reorder pre-existing or
automatically generated pages beneath it.
"""
def setUp(self):
child_content = "<p>This is content</p>"
# Find root page
self.root_page = Page.objects.get(id=2)
# root
# |- parent_page (NoCreatableSubpageTypesPage)
# | |- child_1 (SimplePage)
# | |- child_2 (SimplePage)
# | |- child_3 (SimplePage)
self.index_page = NoCreatableSubpageTypesPage(title="Index", slug="index")
self.root_page.add_child(instance=self.index_page)
self.child_1 = SimplePage(
title="Child 1", slug="child-1", content=child_content
)
self.index_page.add_child(instance=self.child_1)
self.child_2 = SimplePage(
title="Child 2", slug="child-2", content=child_content
)
self.index_page.add_child(instance=self.child_2)
self.child_3 = SimplePage(
title="Child 3", slug="child-3", content=child_content
)
self.index_page.add_child(instance=self.child_3)
# Login
self.user = self.login()

Wyświetl plik

@ -3228,10 +3228,13 @@ class PagePermissionTester:
def can_reorder_children(self):
"""
Keep reorder permissions the same as publishing, since it immediately affects published pages
(and the use-cases for a non-admin needing to do it are fairly obscure...)
Reorder permission checking is similar to publishing a subpage, since it immediately
affects published pages. However, it shouldn't care about the 'creatability' of
page types, because the action only ever updates existing pages.
"""
return self.can_publish_subpage()
if not self.user.is_active:
return False
return self.user.is_superuser or ("publish" in self.permissions)
def can_move(self):
"""

Wyświetl plik

@ -0,0 +1,54 @@
# Generated by Django 4.2.11 on 2024-05-10 12:41
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
("wagtailcore", "0093_uploadedfile"),
("tests", "0039_alter_eventcategory_locale_and_more"),
]
operations = [
migrations.CreateModel(
name="NoCreatableSubpageTypesPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
],
options={
"abstract": False,
},
bases=("wagtailcore.page",),
),
migrations.CreateModel(
name="NoSubpageTypesPage",
fields=[
(
"page_ptr",
models.OneToOneField(
auto_created=True,
on_delete=django.db.models.deletion.CASCADE,
parent_link=True,
primary_key=True,
serialize=False,
to="wagtailcore.page",
),
),
],
options={
"abstract": False,
},
bases=("wagtailcore.page",),
),
]

Wyświetl plik

@ -1668,6 +1668,14 @@ class MTIChildPage(MTIBasePage):
pass
class NoCreatableSubpageTypesPage(Page):
subpage_types = [MTIBasePage]
class NoSubpageTypesPage(Page):
subpage_types = []
class AbstractPage(Page):
class Meta:
abstract = True

Wyświetl plik

@ -20,6 +20,8 @@ from wagtail.test.testapp.models import (
CustomPermissionTester,
EventIndex,
EventPage,
NoCreatableSubpageTypesPage,
NoSubpageTypesPage,
SingletonPageViaMaxCount,
)
@ -39,6 +41,19 @@ class TestPagePermission(TestCase):
def test_nonpublisher_page_permissions(self):
event_editor = get_user_model().objects.get(email="eventeditor@example.com")
homepage = Page.objects.get(url_path="/home/")
# As this is a direct child of the homepage, permission checks should
# mostly mirror those for the homepage itself
no_creatable_subpages_page = NoCreatableSubpageTypesPage(
title="No creatable subpages", slug="no-creatable-subpages"
)
homepage.add_child(instance=no_creatable_subpages_page)
# As this is a direct child of the homepage, permission checks should
# mostly mirror those for the homepage itself
no_subpages_page = NoSubpageTypesPage(title="No subpages", slug="no-subpages")
homepage.add_child(instance=no_subpages_page)
christmas_page = EventPage.objects.get(url_path="/home/events/christmas/")
unpublished_event_page = EventPage.objects.get(
url_path="/home/events/tentative-unpublished-event/"
@ -51,6 +66,10 @@ class TestPagePermission(TestCase):
)
homepage_perms = homepage.permissions_for_user(event_editor)
no_creatable_subpages_perms = no_creatable_subpages_page.permissions_for_user(
event_editor
)
no_subpages_perms = no_subpages_page.permissions_for_user(event_editor)
christmas_page_perms = christmas_page.permissions_for_user(event_editor)
unpub_perms = unpublished_event_page.permissions_for_user(event_editor)
someone_elses_event_perms = someone_elses_event_page.permissions_for_user(
@ -59,17 +78,23 @@ class TestPagePermission(TestCase):
board_meetings_perms = board_meetings_page.permissions_for_user(event_editor)
self.assertFalse(homepage_perms.can_add_subpage())
self.assertFalse(no_creatable_subpages_perms.can_add_subpage())
self.assertFalse(no_subpages_perms.can_add_subpage())
self.assertTrue(christmas_page_perms.can_add_subpage())
self.assertTrue(unpub_perms.can_add_subpage())
self.assertTrue(someone_elses_event_perms.can_add_subpage())
self.assertFalse(homepage_perms.can_edit())
self.assertFalse(no_creatable_subpages_perms.can_edit())
self.assertFalse(no_subpages_perms.can_edit())
self.assertTrue(christmas_page_perms.can_edit())
self.assertTrue(unpub_perms.can_edit())
# basic 'add' permission doesn't allow editing pages owned by someone else
self.assertFalse(someone_elses_event_perms.can_edit())
self.assertFalse(homepage_perms.can_delete())
self.assertFalse(no_creatable_subpages_perms.can_delete())
self.assertFalse(no_subpages_perms.can_delete())
self.assertFalse(
christmas_page_perms.can_delete()
) # cannot delete because it is published
@ -77,22 +102,32 @@ class TestPagePermission(TestCase):
self.assertFalse(someone_elses_event_perms.can_delete())
self.assertFalse(homepage_perms.can_publish())
self.assertFalse(no_creatable_subpages_perms.can_publish())
self.assertFalse(no_subpages_perms.can_publish())
self.assertFalse(christmas_page_perms.can_publish())
self.assertFalse(unpub_perms.can_publish())
self.assertFalse(homepage_perms.can_unpublish())
self.assertFalse(no_creatable_subpages_perms.can_unpublish())
self.assertFalse(no_subpages_perms.can_unpublish())
self.assertFalse(christmas_page_perms.can_unpublish())
self.assertFalse(unpub_perms.can_unpublish())
self.assertFalse(homepage_perms.can_publish_subpage())
self.assertFalse(no_creatable_subpages_perms.can_publish_subpage())
self.assertFalse(no_subpages_perms.can_publish_subpage())
self.assertFalse(christmas_page_perms.can_publish_subpage())
self.assertFalse(unpub_perms.can_publish_subpage())
self.assertFalse(homepage_perms.can_reorder_children())
self.assertFalse(no_creatable_subpages_perms.can_reorder_children())
self.assertFalse(no_subpages_perms.can_reorder_children())
self.assertFalse(christmas_page_perms.can_reorder_children())
self.assertFalse(unpub_perms.can_reorder_children())
self.assertFalse(homepage_perms.can_move())
self.assertFalse(no_creatable_subpages_perms.can_move())
self.assertFalse(no_subpages_perms.can_move())
# cannot move because this would involve unpublishing from its current location
self.assertFalse(christmas_page_perms.can_move())
self.assertTrue(unpub_perms.can_move())
@ -119,6 +154,19 @@ class TestPagePermission(TestCase):
email="eventmoderator@example.com"
)
homepage = Page.objects.get(url_path="/home/")
# As this is a direct child of the homepage, permission checks should
# mostly mirror those for the homepage itself
no_creatable_subpages_page = NoCreatableSubpageTypesPage(
title="No creatable subpages", slug="no-creatable-subpages"
)
homepage.add_child(instance=no_creatable_subpages_page)
# As this is a direct child of the homepage, permission checks should
# mostly mirror those for the homepage itself
no_subpages_page = NoSubpageTypesPage(title="No subpages", slug="no-subpages")
homepage.add_child(instance=no_subpages_page)
christmas_page = EventPage.objects.get(url_path="/home/events/christmas/")
unpublished_event_page = EventPage.objects.get(
url_path="/home/events/tentative-unpublished-event/"
@ -128,42 +176,61 @@ class TestPagePermission(TestCase):
)
homepage_perms = homepage.permissions_for_user(event_moderator)
no_creatable_subpages_perms = no_creatable_subpages_page.permissions_for_user(
event_moderator
)
no_subpages_perms = no_subpages_page.permissions_for_user(event_moderator)
christmas_page_perms = christmas_page.permissions_for_user(event_moderator)
unpub_perms = unpublished_event_page.permissions_for_user(event_moderator)
board_meetings_perms = board_meetings_page.permissions_for_user(event_moderator)
self.assertFalse(homepage_perms.can_add_subpage())
self.assertFalse(no_creatable_subpages_perms.can_add_subpage())
self.assertFalse(no_subpages_perms.can_add_subpage())
self.assertTrue(christmas_page_perms.can_add_subpage())
self.assertTrue(unpub_perms.can_add_subpage())
self.assertFalse(homepage_perms.can_edit())
self.assertFalse(no_creatable_subpages_perms.can_edit())
self.assertFalse(no_subpages_perms.can_edit())
self.assertTrue(christmas_page_perms.can_edit())
self.assertTrue(unpub_perms.can_edit())
self.assertFalse(homepage_perms.can_delete())
self.assertFalse(no_creatable_subpages_perms.can_delete())
self.assertFalse(no_subpages_perms.can_delete())
# can delete a published page because we have publish permission
self.assertTrue(christmas_page_perms.can_delete())
self.assertTrue(unpub_perms.can_delete())
self.assertFalse(homepage_perms.can_publish())
self.assertFalse(no_creatable_subpages_perms.can_publish())
self.assertFalse(no_subpages_perms.can_publish())
self.assertTrue(christmas_page_perms.can_publish())
self.assertTrue(unpub_perms.can_publish())
self.assertFalse(homepage_perms.can_unpublish())
self.assertFalse(no_creatable_subpages_perms.can_unpublish())
self.assertTrue(christmas_page_perms.can_unpublish())
self.assertFalse(
unpub_perms.can_unpublish()
) # cannot unpublish a page that isn't published
self.assertFalse(homepage_perms.can_publish_subpage())
self.assertFalse(no_creatable_subpages_perms.can_publish_subpage())
self.assertFalse(no_subpages_perms.can_publish_subpage())
self.assertTrue(christmas_page_perms.can_publish_subpage())
self.assertTrue(unpub_perms.can_publish_subpage())
self.assertFalse(homepage_perms.can_reorder_children())
self.assertFalse(no_creatable_subpages_perms.can_reorder_children())
self.assertFalse(no_subpages_perms.can_reorder_children())
self.assertTrue(christmas_page_perms.can_reorder_children())
self.assertTrue(unpub_perms.can_reorder_children())
self.assertFalse(homepage_perms.can_move())
self.assertFalse(no_creatable_subpages_perms.can_move())
self.assertFalse(no_subpages_perms.can_move())
self.assertTrue(christmas_page_perms.can_move())
self.assertTrue(unpub_perms.can_move())
@ -325,6 +392,19 @@ class TestPagePermission(TestCase):
def test_superuser_has_full_permissions(self):
user = get_user_model().objects.get(email="superuser@example.com")
homepage = Page.objects.get(url_path="/home/").specific
# As this is a direct child of the homepage, permission checks should
# mostly mirror those for the homepage itself
no_creatable_subpages_page = NoCreatableSubpageTypesPage(
title="No creatable subpages", slug="no-creatable-subpages"
)
homepage.add_child(instance=no_creatable_subpages_page)
# As this is a direct child of the homepage, permission checks should
# mostly mirror those for the homepage itself
no_subpages_page = NoSubpageTypesPage(title="No subpages", slug="no-subpages")
homepage.add_child(instance=no_subpages_page)
root = Page.objects.get(url_path="/").specific
unpublished_event_page = EventPage.objects.get(
url_path="/home/events/tentative-unpublished-event/"
@ -334,35 +414,64 @@ class TestPagePermission(TestCase):
)
homepage_perms = homepage.permissions_for_user(user)
no_creatable_subpages_perms = no_creatable_subpages_page.permissions_for_user(
user
)
no_subpages_perms = no_subpages_page.permissions_for_user(user)
root_perms = root.permissions_for_user(user)
unpub_perms = unpublished_event_page.permissions_for_user(user)
board_meetings_perms = board_meetings_page.permissions_for_user(user)
self.assertTrue(homepage_perms.can_add_subpage())
self.assertFalse(
no_creatable_subpages_perms.can_add_subpage()
) # There are no 'creatable' subpage types
self.assertFalse(
no_subpages_perms.can_add_subpage()
) # There are no subpage types
self.assertTrue(root_perms.can_add_subpage())
self.assertTrue(homepage_perms.can_edit())
self.assertTrue(no_creatable_subpages_perms.can_edit())
self.assertTrue(no_subpages_perms.can_edit())
self.assertFalse(
root_perms.can_edit()
) # root is not a real editable page, even to superusers
self.assertTrue(homepage_perms.can_delete())
self.assertTrue(no_creatable_subpages_perms.can_delete())
self.assertTrue(no_subpages_perms.can_delete())
self.assertFalse(root_perms.can_delete())
self.assertTrue(homepage_perms.can_publish())
self.assertTrue(no_creatable_subpages_perms.can_publish())
self.assertTrue(no_subpages_perms.can_publish())
self.assertFalse(root_perms.can_publish())
self.assertTrue(homepage_perms.can_unpublish())
self.assertTrue(no_creatable_subpages_perms.can_unpublish())
self.assertTrue(no_subpages_perms.can_unpublish())
self.assertFalse(root_perms.can_unpublish())
self.assertFalse(unpub_perms.can_unpublish())
self.assertTrue(homepage_perms.can_publish_subpage())
self.assertFalse(
no_creatable_subpages_perms.can_publish_subpage()
) # There are no 'creatable' subpages, so a new one cannot be 'created and published' here
self.assertFalse(
no_subpages_perms.can_publish_subpage()
) # There are no subpages, so a new one cannot be 'created and published' here
self.assertTrue(root_perms.can_publish_subpage())
self.assertTrue(homepage_perms.can_reorder_children())
self.assertTrue(no_creatable_subpages_perms.can_reorder_children())
self.assertTrue(no_subpages_perms.can_reorder_children())
self.assertTrue(root_perms.can_reorder_children())
self.assertTrue(homepage_perms.can_move())
self.assertTrue(no_creatable_subpages_perms.can_move())
self.assertTrue(no_subpages_perms.can_move())
self.assertFalse(root_perms.can_move())
self.assertTrue(homepage_perms.can_move_to(root))

Wyświetl plik

@ -13,6 +13,8 @@ from wagtail.test.testapp.models import (
BusinessSubIndex,
EventIndex,
EventPage,
NoCreatableSubpageTypesPage,
NoSubpageTypesPage,
SectionedRichTextPage,
SimpleChildPage,
SimplePage,
@ -287,6 +289,8 @@ class TestWagtailPageTests(WagtailPageTests):
BusinessSubIndex,
BusinessChild,
BusinessIndex,
NoCreatableSubpageTypesPage,
NoSubpageTypesPage,
SimpleParentPage,
}
self.assertAllowedParentPageTypes(BusinessIndex, all_but_business)