dynamicweb/cms/tests/test_wizards.py

848 lines
32 KiB
Python

from unittest.mock import Mock, patch
from django import forms
from django.apps import apps
from django.apps.registry import Apps
from django.contrib.sites.models import Site
from django.core.exceptions import ImproperlyConfigured
from django.forms.models import ModelForm
from django.template import TemplateSyntaxError
from django.test.utils import override_settings
from django.urls import reverse
from django.utils.encoding import smart_str
from django.utils.translation import gettext as _
from cms import app_registration
from cms.api import create_page
from cms.cms_wizards import cms_page_wizard, cms_subpage_wizard
from cms.constants import MODAL_HTML_REDIRECT, TEMPLATE_INHERITANCE_MAGIC
from cms.forms.wizards import CreateCMSPageForm, CreateCMSSubPageForm
from cms.models import Page, PageContent, UserSettings
from cms.models.permissionmodels import GlobalPagePermission
from cms.test_utils.project.backwards_wizards.wizards import wizard
from cms.test_utils.project.sampleapp.cms_wizards import sample_wizard
from cms.test_utils.testcases import CMSTestCase, TransactionCMSTestCase
from cms.toolbar.utils import (
get_object_edit_url,
get_object_preview_url,
)
from cms.utils.conf import get_cms_setting
from cms.utils.page_permissions import user_can_add_subpage
from cms.utils.setup import setup_cms_apps
from cms.utils.urlutils import admin_reverse
from cms.wizards.forms import WizardStep1Form, WizardStep2BaseForm, step2_form_factory
from cms.wizards.helpers import get_entries, get_entry
from cms.wizards.wizard_base import Wizard
from cms.wizards.wizard_pool import (
AlreadyRegisteredException,
entry_choices,
wizard_pool,
)
CreateCMSPageForm = step2_form_factory(
mixin_cls=WizardStep2BaseForm,
entry_form_class=CreateCMSPageForm,
)
CreateCMSSubPageForm = step2_form_factory(
mixin_cls=WizardStep2BaseForm,
entry_form_class=CreateCMSSubPageForm,
)
class WizardForm(forms.Form):
pass
class ModelWizardForm(ModelForm):
class Meta:
model = UserSettings
exclude = []
class BadModelForm(ModelForm):
class Meta:
pass
class WizardTestMixin:
page_wizard = None
title_wizard = None
def assertSequencesEqual(self, seq_a, seq_b):
seq_a = list(seq_a)
seq_b = list(seq_b)
zipped = list(zip(seq_a, seq_b, strict=False))
if len(zipped) < len(seq_a) or len(zipped) < len(seq_b):
self.fail("Sequence lengths are not the same.")
for idx, (a, b) in enumerate(zipped):
if a != b:
self.fail(f"Sequences differ at index {idx}")
@classmethod
def setUpClass(cls):
super().setUpClass()
# This prevents auto-discovery, which would otherwise occur as soon as
# tests start, creating unexpected starting conditions.
wizard_pool._discovered = True
class PageWizard(Wizard):
pass
# This is a basic Wizard
cls.page_wizard = PageWizard(
title=_("Page"),
weight=100,
form=WizardForm,
model=Page,
template_name="my_template.html", # This doesn't exist anywhere
)
class SettingsWizard(Wizard):
pass
# This is a Wizard that uses a ModelForm to define the model
cls.user_settings_wizard = SettingsWizard(
title=_("UserSettings"),
weight=200,
form=ModelWizardForm,
)
class PageContentWizard(Wizard):
pass
# This is a bad wizard definition as it neither defines a model, nor
# uses a ModelForm that has model defined in Meta
cls.title_wizard = PageContentWizard(
title=_("Page"),
weight=100,
form=BadModelForm,
template_name="my_template.html", # This doesn't exist anywhere
)
def setUp(self):
super().setUp()
self.site = Site.objects.get_current()
class TestWizardBase(WizardTestMixin, TransactionCMSTestCase):
def test_user_has_add_permission(self):
# Test does not have permission
user = self.get_staff_user_with_no_permissions()
self.assertFalse(self.page_wizard.user_has_add_permission(user))
# Test has permission
user = self.get_superuser()
self.assertTrue(self.page_wizard.user_has_add_permission(user))
def test_get_success_url(self):
user = self.get_superuser()
page = create_page(
title="Sample Page",
template=TEMPLATE_INHERITANCE_MAGIC,
language="en",
created_by=smart_str(user),
parent=None,
in_navigation=True,
)
url = page.get_absolute_url(language="en")
self.assertEqual(self.page_wizard.get_success_url(page, language="en"), url)
# Now again without a language code
url = page.get_absolute_url()
self.assertEqual(self.page_wizard.get_success_url(page), url)
def test_get_edit_url(self):
user = self.get_superuser()
page = create_page(
title="Sample Page",
template=TEMPLATE_INHERITANCE_MAGIC,
language="en",
created_by=smart_str(user),
parent=None,
in_navigation=True,
)
extension = apps.get_app_config("cms").cms_extension
with patch.object(extension, "toolbar_enabled_models", {Page: page}):
url = self.page_wizard.get_success_url(page, language="en")
self.assertEqual(url, get_object_edit_url(page, language="en"))
def test_get_preview_url(self):
wizard_preview_mode = Wizard(
title=_("Page"),
weight=100,
form=WizardForm,
model=Page,
template_name="my_template.html", # This doesn't exist anywhere
edit_mode_on_success=False,
)
user = self.get_superuser()
page = create_page(
title="Sample Page",
template=TEMPLATE_INHERITANCE_MAGIC,
language="en",
created_by=smart_str(user),
parent=None,
in_navigation=True,
)
extension = apps.get_app_config("cms").cms_extension
with patch.object(extension, "toolbar_enabled_models", {Page: page}):
url = wizard_preview_mode.get_success_url(page, language="en")
self.assertEqual(url, get_object_preview_url(page, language="en"))
def test_get_model(self):
self.assertEqual(self.page_wizard.get_model(), Page)
self.assertEqual(self.user_settings_wizard.get_model(), UserSettings)
with self.assertRaises(ImproperlyConfigured):
self.title_wizard.get_model()
def test_endpoint_auth_required(self):
endpoint = reverse("admin:cms_wizard_create")
staff_active = self._create_user("staff-active", is_staff=True, is_superuser=False, is_active=True)
response = self.client.get(endpoint)
self.assertEqual(response.status_code, 403)
with self.login_user_context(staff_active):
response = self.client.get(endpoint)
self.assertEqual(response.status_code, 200)
class TestWizardPool(WizardTestMixin, CMSTestCase):
def tearDown(self):
# Clean up in case anything has been removed or added to the
# registered wizards, so other tests don't have problems
extension = apps.get_app_config("cms").cms_extension
# Reset the cached property 'wizards'
if hasattr(extension, "wizards"):
del extension.wizards
configs_with_wizards = [
app.cms_config for app in app_registration.get_cms_config_apps() if hasattr(app.cms_config, "cms_wizards")
]
for config in configs_with_wizards:
extension.configure_wizards(config)
# Clean up in case cached apps are different than the defaults
app_registration.get_cms_extension_apps.cache_clear()
app_registration.get_cms_config_apps.cache_clear()
def test_is_registered_for_registered_wizard(self):
"""
Test for backwards compatibility of is_registered when checking
a registered wizard.
"""
from django.apps import apps
self.assertTrue(apps.get_app_config("cms").cms_extension.wizards)
is_registered = wizard_pool.is_registered(cms_page_wizard)
self.assertTrue(is_registered)
def test_is_registered_for_unregistered_wizard(self):
"""
Test for backwards compatibility of is_registered when checking
an unregistered wizard.
"""
is_registered = wizard_pool.is_registered(self.page_wizard)
self.assertFalse(is_registered)
def test_unregister_registered_wizard(self):
"""
Test for backwards compatibility of the unregister method.
Removes a wizard from the wizards dict.
"""
was_unregistered = wizard_pool.unregister(cms_page_wizard)
registered_wizards = apps.get_app_config("cms").cms_extension.wizards
self.assertNotIn(cms_page_wizard.id, registered_wizards)
self.assertTrue(was_unregistered)
def test_unregister_unregistered_wizard(self):
"""
Test for backwards compatibility of the unregister method.
Returns False if wizard not found.
"""
was_unregistered = wizard_pool.unregister(self.page_wizard)
self.assertFalse(was_unregistered)
def test_register_already_registered_wizard(self):
"""
Test for backwards compatibility of the register method.
Raises AlreadyRegisteredException if the wizard is already
registered.
"""
with self.assertRaises(AlreadyRegisteredException):
wizard_pool.register(cms_page_wizard)
def test_register_unregistered_wizard(self):
"""
Test for backwards compatibility of the register method.
Adds the wizard to the wizards dict.
"""
wizard_pool.register(self.page_wizard)
registered_wizards = apps.get_app_config("cms").cms_extension.wizards
self.assertIn(self.page_wizard.id, registered_wizards)
@patch("cms.wizards.wizard_pool.get_entry")
def test_get_entry(self, mocked_get_entry):
"""
Test for backwards compatibility of wizard_pool.get_entry.
Checking we use the new get_entry under the hood.
"""
wizard_pool.get_entry(cms_page_wizard)
mocked_get_entry.assert_called_once()
def test_old_registration_still_works(self):
"""
Integration-like test checking that if you register your wizard
by adding wizard_pool.register(wizard) to cms_wizards.py it will
correctly register the wizard. This ensures backwards
compatibility.
"""
# NOTE: Because of how the override_settings decorator works,
# we can't use it for this test as the app registry first
# gets loaded with the default apps and then again with
# the overridden ones.
INSTALLED_APPS = [
"cms",
"treebeard",
"cms.test_utils.project.backwards_wizards",
]
mocked_apps = Apps(installed_apps=INSTALLED_APPS)
# clear out app registration cache now that installed apps have
# changed
app_registration.get_cms_extension_apps.cache_clear()
app_registration.get_cms_config_apps.cache_clear()
# Run the setup with the mocked installed apps. Due to the order
# of imports and other fun things, apps have to be patched
# in multiple places. If functions are moved around the code
# this could get worse.
with patch("cms.app_registration.apps", mocked_apps):
with patch("cms.wizards.wizard_pool.apps", mocked_apps):
setup_cms_apps()
# Check the wizards built into the cms app and the wizard from
# the backwards_wizards app have been picked up.
# The backwards_wizards app does not have a cms_config.py but
# registers its wizard by adding wizard_pool.register(wizard)
# to cms_wizards.py which is the old way we want backwards
# compatibility with.
cms_app = mocked_apps.get_app_config("cms")
expected_wizards = {
cms_page_wizard.id: cms_page_wizard,
cms_subpage_wizard.id: cms_subpage_wizard,
wizard.id: wizard,
}
self.assertDictEqual(cms_app.cms_extension.wizards, expected_wizards)
class TestPageWizard(WizardTestMixin, CMSTestCase):
def test_str(self):
self.assertEqual(str(cms_page_wizard), cms_page_wizard.title)
def test_repr(self):
self.assertIn("cms.cms_wizards.CMSPageWizard", repr(cms_page_wizard))
self.assertIn(f"id={cms_page_wizard.id}", repr(cms_page_wizard))
self.assertIn(hex(id(cms_page_wizard)), repr(cms_page_wizard))
def test_wizard_create_child_page(self):
superuser = self.get_superuser()
with self.login_user_context(superuser):
request = self.get_request()
parent_page = create_page(
title="Parent",
template=TEMPLATE_INHERITANCE_MAGIC,
language="en",
)
data = {
"title": "Child",
"slug": "child",
"page_type": None,
}
form = CreateCMSSubPageForm(
data=data,
wizard_page=parent_page,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertTrue(form.is_valid())
child_page = form.save()
self.assertEqual(child_page.depth, 2)
self.assertEqual(child_page.parent, parent_page)
self.assertEqual(child_page.get_title("en"), "Child")
self.assertEqual(child_page.get_path("en"), "parent/child")
def test_wizard_create_atomic(self):
# Ref: https://github.com/divio/django-cms/issues/5652
# We'll simulate a scenario where a user creates a page with an
# invalid template which causes Django to throw an error when the
# template is scanned for placeholders and thus short circuits the
# creation mechanism.
superuser = self.get_superuser()
with self.login_user_context(superuser):
request = self.get_request()
data = {
"title": "page 1",
"slug": "page_1",
"page_type": None,
}
form = CreateCMSPageForm(
data=data,
wizard_page=None,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertTrue(form.is_valid())
self.assertFalse(Page.objects.filter(pagecontent_set__template=TEMPLATE_INHERITANCE_MAGIC).exists())
with patch.object(PageContent, "template_choices", [("col_invalid.html", "notvalid")]):
self.assertRaises(TemplateSyntaxError, form.save)
# The template raised an exception which should cause the database to roll back
# instead of committing a page in a partial state.
self.assertFalse(Page.objects.filter(pagecontent_set__template=TEMPLATE_INHERITANCE_MAGIC).exists())
def test_wizard_content_placeholder_setting(self):
"""
Tests that the PageWizard respects the
CMS_PAGE_WIZARD_CONTENT_PLACEHOLDER setting.
"""
superuser = self.get_superuser()
with self.login_user_context(superuser):
request = self.get_request()
templates = get_cms_setting("TEMPLATES")
# NOTE, there are 4 placeholders on this template, defined in this
# order: 'header', 'content', 'sub-content', 'footer'.
# 'footer' is a static-placeholder.
templates.append(
(
"page_wizard.html",
"page_wizard.html",
)
)
settings = {
"CMS_TEMPLATES": templates,
"CMS_PAGE_WIZARD_DEFAULT_TEMPLATE": "page_wizard.html",
"CMS_PAGE_WIZARD_CONTENT_PLACEHOLDER": "sub-content",
}
with override_settings(**settings):
page = create_page("wizard home", "page_wizard.html", "en")
content = "<p>sub-content content.</p>"
data = {
"title": "page 1",
"slug": "page_1",
"page_type": None,
"content": content,
}
form = CreateCMSPageForm(
data=data,
wizard_page=page,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertTrue(form.is_valid())
page = form.save()
with self.login_user_context(superuser):
url = page.get_absolute_url("en")
expected = f'<div class="sub-content">{content}</div>'
unexpected = f'<div class="content">{content}</div>'
response = self.client.get(url)
self.assertContains(response, expected, status_code=200)
self.assertNotContains(response, unexpected, status_code=200)
def test_wizard_content_placeholder_bad_setting(self):
"""
Tests that the PageWizard won't respect a 'bad' setting such as
targeting a static-placeholder. In this case, will just fail to
add the content (without error).
"""
superuser = self.get_superuser()
with self.login_user_context(superuser):
request = self.get_request()
templates = get_cms_setting("TEMPLATES")
# NOTE, there are 4 placeholders on this template, defined in this
# order: 'header', 'content', 'sub-content', 'footer'.
# 'footer' is a static-placeholder.
templates.append(
(
"page_wizard.html",
"page_wizard.html",
)
)
settings = {
"CMS_TEMPLATES": templates,
"CMS_PAGE_WIZARD_DEFAULT_TEMPLATE": "page_wizard.html",
# This is a bad setting.
"CMS_PAGE_WIZARD_CONTENT_PLACEHOLDER": "footer",
}
with override_settings(**settings):
page = create_page("wizard home", "page_wizard.html", "en")
content = "<p>footer content.</p>"
data = {
"title": "page 1",
"slug": "page_1",
"page_type": None,
"content": content,
}
form = CreateCMSPageForm(
data=data,
wizard_page=page,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertTrue(form.is_valid())
page = form.save()
with self.login_user_context(superuser):
url = page.get_absolute_url("en")
response = self.client.get(url)
self.assertNotContains(response, content, status_code=200)
def test_create_page_with_empty_fields(self):
superuser = self.get_superuser()
with self.login_user_context(superuser):
request = self.get_request()
data = {
"title": "",
"slug": "",
"page_type": None,
}
form = CreateCMSPageForm(
data=data,
wizard_page=None,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertFalse(form.is_valid())
def test_create_page_with_existing_slug(self):
superuser = self.get_superuser()
with self.login_user_context(superuser):
request = self.get_request()
data = {
"title": "page",
"slug": "page",
"page_type": None,
}
create_page("page", "nav_playground.html", language="en", slug="page")
# slug -> page-1
form = CreateCMSPageForm(
data=data,
wizard_page=None,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertTrue(form.is_valid())
self.assertTrue(form.save().get_urls().filter(slug="page-2"))
# slug -> page-2
form = CreateCMSPageForm(
data=data,
wizard_page=None,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertTrue(form.is_valid())
self.assertTrue(form.save().get_urls().filter(slug="page-3"))
# Now explicitly request the page-2 slug
data["slug"] = "page-2"
# slug -> page-2-2
form = CreateCMSPageForm(
data=data,
wizard_page=None,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertTrue(form.is_valid())
self.assertTrue(form.save().get_urls().filter(slug="page-2-2"))
# slug -> page-2-3
form = CreateCMSPageForm(
data=data,
wizard_page=None,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertTrue(form.is_valid())
self.assertTrue(form.save().get_urls().filter(slug="page-2-3"))
class TestPageWizardSubmission(CMSTestCase):
def test_page_wizard_submission(self):
from cms.wizards.helpers import get_entries
page = create_page("home", "nav_playground.html", "en")
entry_id = get_entries()[0].id
endpoint = admin_reverse("cms_wizard_create")
data_step1 = {
"wizard_create_view-current_step": "0",
"0-entry": entry_id,
"0-language": "en",
"0-page": page.pk,
}
data_step2 = {
"wizard_create_view-current_step": "1",
"1-title": "my test page",
"1-slug": "my-test-page",
"1-content": "",
}
with self.login_user_context(self.get_superuser()):
response = self.client.post(endpoint, data_step1, follow=True)
self.assertEqual(response.status_code, 200)
response = self.client.post(endpoint, data_step2)
edit_endpoint = get_object_edit_url(Page.objects.exclude(pk=page.pk).last().get_content_obj("en"), "en")
self.assertContains(response, MODAL_HTML_REDIRECT.format(url=edit_endpoint))
def test_subpage_wizard_submission(self):
"""Regression test for #8697: the subpage wizard must run through both
steps and create the new page as a child of the origin page.
The subpage entry is only offered while the wizard knows the origin
page, so a regression that drops the page between steps both hides the
entry (step 0 fails to validate) and detaches the created page.
"""
parent = create_page("home", "nav_playground.html", "en")
entry_id = cms_subpage_wizard.id
endpoint = admin_reverse("cms_wizard_create")
data_step1 = {
"wizard_create_view-current_step": "0",
"0-entry": entry_id,
"0-language": "en",
"0-page": parent.pk,
}
data_step2 = {
"wizard_create_view-current_step": "1",
"1-title": "my child page",
"1-slug": "my-child-page",
"1-content": "",
}
with self.login_user_context(self.get_superuser()):
# Step 0 must advance to step 1 -- i.e. the subpage entry stays a
# valid choice because the origin page survives the transition.
response = self.client.post(endpoint, data_step1, follow=True)
self.assertEqual(response.status_code, 200)
self.assertNotContains(response, "Please choose an option")
response = self.client.post(endpoint, data_step2)
new_page = Page.objects.exclude(pk=parent.pk).get()
self.assertEqual(new_page.parent_id, parent.pk)
edit_endpoint = get_object_edit_url(new_page.get_content_obj("en"), "en")
self.assertContains(response, MODAL_HTML_REDIRECT.format(url=edit_endpoint))
@override_settings(
CMS_PERMISSION=True,
CMS_LANGUAGES={
1: [{"code": "en", "name": "English"}],
2: [{"code": "en", "name": "English"}],
},
)
class TestWizardSiteIsolation(CMSTestCase):
def setUp(self):
self.site = Site.objects.get_current()
self.other_site, _ = Site.objects.get_or_create(
pk=2, defaults={"domain": "other.example", "name": "Other site"},
)
self.local_parent = create_page("Local parent", "nav_playground.html", "en", site=self.site)
self.other_parent = create_page("Other parent", "nav_playground.html", "en", site=self.other_site)
self.other_child = create_page(
"Other child", "nav_playground.html", "en", site=self.other_site, parent=self.other_parent,
)
self.writer = self._create_user(
"site_writer", is_staff=True, permissions=["add_page", "change_page"],
)
permission = GlobalPagePermission.objects.create(user=self.writer, can_add=True, can_change=True)
permission.sites.add(self.site)
def test_cross_site_origin_is_rejected(self):
self.assertFalse(user_can_add_subpage(self.writer, self.other_parent, site=self.other_site))
endpoint = admin_reverse("cms_wizard_create")
page_count = Page.objects.count()
with self.login_user_context(self.writer):
response = self.client.post(endpoint, {
"wizard_create_view-current_step": "0",
"0-entry": cms_page_wizard.id,
"0-language": "en",
"0-page": self.other_child.pk,
})
self.assertEqual(response.status_code, 200)
self.assertIn("page", response.context["wizard"]["form"].errors)
# Posting step 1 directly must not bypass the rejected origin.
response = self.client.post(endpoint, {
"wizard_create_view-current_step": "1",
"1-title": "Cross-site sibling",
"1-slug": "cross-site-sibling",
})
self.assertEqual(response.status_code, 200)
self.assertEqual(Page.objects.count(), page_count)
def test_same_site_subpage_submission(self):
endpoint = admin_reverse("cms_wizard_create")
with self.login_user_context(self.writer):
response = self.client.post(endpoint, {
"wizard_create_view-current_step": "0",
"0-entry": cms_subpage_wizard.id,
"0-language": "en",
"0-page": self.local_parent.pk,
})
self.assertEqual(response.status_code, 200)
self.assertEqual(response.context["wizard"]["steps"].current, "1")
response = self.client.post(endpoint, {
"wizard_create_view-current_step": "1",
"1-title": "Local child",
"1-slug": "local-child",
})
self.assertEqual(response.status_code, 200)
child = Page.objects.get(pagecontent_set__title="Local child")
self.assertEqual(child.site_id, self.site.pk)
self.assertEqual(child.parent_id, self.local_parent.pk)
def test_cross_site_parent_is_rejected_by_creation_forms(self):
# Tree integrity must also hold for direct form use, including
# superusers and projects without CMS per-page permissions.
with self.login_user_context(self.get_superuser()):
request = self.get_request()
for permissions_enabled in (True, False):
for form_class, origin in (
(CreateCMSPageForm, self.other_child),
(CreateCMSSubPageForm, self.other_parent),
):
with self.subTest(permissions=permissions_enabled, form=form_class):
with override_settings(CMS_PERMISSION=permissions_enabled):
form = form_class(
data={"title": "Cross-site page", "slug": "cross-site-page"},
wizard_page=origin,
wizard_site=self.site,
wizard_language="en",
wizard_request=request,
)
self.assertFalse(form.is_valid())
self.assertIn("parent_page", form.errors)
class TestWizardHelpers(CMSTestCase):
def setUp(self):
# The results of get_cms_extension_apps and get_cms_config_apps
# are cached. Clear this cache because installed apps change
# between tests and therefore unlike in a live environment,
# results of this function can change between tests
app_registration.get_cms_extension_apps.cache_clear()
app_registration.get_cms_config_apps.cache_clear()
def test_get_entries_orders_by_weight(self):
"""
The get_entries function returns the registered wizards
ordered by weight.
"""
# The test setup registers two wizards from cms itself
# (cms_page_wizard and cms_subpage_wizard) and one from
# test_utils.project.sampleapp (sample_wizard)
# We know these are definitely being ordered by weight if
# sample_wizard is in the middle because app registration
# would first add the wizards from cms to a list and then add
# those from sampleapp, so the sampleapp wizard could not
# be in the middle by default
expected = [cms_page_wizard, sample_wizard, cms_subpage_wizard]
entries = get_entries()
self.assertListEqual(entries, expected)
def test_get_entry_returns_wizard_by_id(self):
"""
The get_entry function returns the wizard when a wizard id is
supplied.
"""
entry = get_entry(sample_wizard.id)
self.assertEqual(entry, sample_wizard)
class TestEntryChoices(CMSTestCase):
def test_generates_choices_in_weighted_order(self):
"""
The entry_choices function returns the wizards ordered by weight
"""
user = self.get_superuser()
page = create_page("home", "nav_playground.html", "en")
wizard_choices = [option for option in entry_choices(user, page)]
expected = [
(cms_page_wizard.id, cms_page_wizard.title),
(sample_wizard.id, sample_wizard.title),
(cms_subpage_wizard.id, cms_subpage_wizard.title),
]
self.assertListEqual(wizard_choices, expected)
@patch.object(cms_page_wizard, "user_has_add_permission", Mock(return_value=False))
def test_doesnt_generate_choice_if_user_doesnt_have_permission(self):
"""
The entry_choices function only returns the wizards that the
user has permissions for
"""
user = self.get_superuser()
page = create_page("home", "nav_playground.html", "en")
wizard_choices = [option for option in entry_choices(user, page)]
expected = [
# Missing cms_page_wizard entry
(sample_wizard.id, sample_wizard.title),
(cms_subpage_wizard.id, cms_subpage_wizard.title),
]
self.assertListEqual(wizard_choices, expected)
def test_wizard_step1_uses_selected_site_for_root_page_entries(self):
site1 = Site.objects.get_current()
site2 = Site.objects.create(domain="second.example.com", name="Second", pk=2)
user = self._create_user("wizard-staff", is_staff=True, is_superuser=False)
self.add_permission(user, "add_page")
self.add_permission(user, "change_page")
global_permission = self.add_global_permission(user, can_add=True, can_change=True)
global_permission.sites.set([site1])
with self.login_user_context(user):
request = self.get_request()
form_site1 = WizardStep1Form(
wizard_page=None,
wizard_site=site1,
wizard_language="en",
wizard_request=request,
)
form_site2 = WizardStep1Form(
wizard_page=None,
wizard_site=site2,
wizard_language="en",
wizard_request=request,
)
choices_site1 = [choice[0] for choice in form_site1.fields["entry"].choices]
choices_site2 = [choice[0] for choice in form_site2.fields["entry"].choices]
self.assertIn(cms_page_wizard.id, choices_site1)
self.assertNotIn(cms_page_wizard.id, choices_site2)