8000 Integrate wizards with app registration by monikasulik · Pull Request #6436 · django-cms/django-cms · GitHub
[go: up one dir, main page]

Skip to content

Integrate wizards with app registration #6436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions cms/app_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,3 +138,33 @@ def configure_cms_apps(apps_with_features):
if getattr(app_config.cms_config, enabled_property, False):
# Feature enabled for this app so configure
configure_app(app_config.cms_config)


# TODO: Remove this function once backwards compatibility is deprecated
def backwards_compatibility_config():
"""
Ensure that old ways of configuring and setting up things (plugin
pools etc.) still work.

NOTE: The autodiscover code has been copied over from
django.utils.module_loading.autodiscover_modules
This is because django's autodiscover function imports
django.apps.apps from within the body of the function, which
interferes with backwards compatibility testing. The testing is
non-trivial and requires the patching of django.apps.apps (which
is impossible when imports are done inside of functions).
"""
# The old pools defined various discover methods that looked for
# specific files and ran the register code in them. Listing the
# names of the files here.
modules_to_autodiscover = ['cms_wizards']
for module in modules_to_autodiscover:
for app_config in apps.get_app_configs():
try:
import_module('%s.%s' % (app_config.name, module))
except Exception:
# Decide whether to bubble up this error. If the app just
# doesn't have the module in question, we can ignore the error
# attempting to import it, otherwise we want it to bubble up.
if module_has_submodule(app_config.module, module):
raise
49 changes: 49 additions & 0 deletions cms/cms_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from logging import getLogger
from collections import Iterable

from django.core.exceptions import ImproperlyConfigured

from cms.app_base import CMSAppExtension, CMSAppConfig
from cms.cms_wizards import cms_page_wizard, cms_subpage_wizard
from cms.wizards.wizard_base import Wizard


logger = getLogger(__name__)


class CMSCoreConfig(CMSAppConfig):
cms_enabled = True
cms_wizards = [cms_page_wizard, cms_subpage_wizard]


class CMSCoreExtensions(CMSAppExtension):

def __init__(self):
self.wizards = {}

def configure_wizards(self, cms_config):
"""
Adds all registered wizards from apps that define them to the
wizards dictionary on this class
"""
if not isinstance(cms_config.cms_wizards, Iterable):
raise ImproperlyConfigured("cms_wizards must be iterable")
for wizard in cms_config.cms_wizards:
if not isinstance(wizard, Wizard):
raise ImproperlyConfigured(
"All wizards defined in cms_wizards must inherit "
"from cms.wizards.wizard_base.Wizard"
)
elif wizard.id in self.wizards:
msg = "Wizard for model {} has already been registered".format(
wizard.get_model()
)
logger.warning(msg)
else:
self.wizards[wizard.id] = wizard

def configure_app(self, cms_config):
# The cms_wizards settings is optional. If it's not here
# just move on.
if hasattr(cms_config, 'cms_wizards'):
self.configure_wizards(cms_config)
4 changes: 0 additions & 4 deletions cms/cms_wizards.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
from cms.models import Page
from cms.utils.page_permissions import user_can_add_page, user_can_add_subpage

from .wizards.wizard_pool import wizard_pool
from .wizards.wizard_base import Wizard

from .forms.wizards import CreateCMSPageForm, CreateCMSSubPageForm
Expand Down Expand Up @@ -52,6 +51,3 @@ def user_has_add_permission(self, user, page=None, **kwargs):
model=Page,
description=_(u"Create a page below the current page.")
)

wizard_pool.register(cms_page_wizard)
wizard_pool.register(cms_subpage_wizard)
Empty file.
8 changes: 8 additions & 0 deletions cms/test_utils/project/backwards_wizards/cms_wizards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from cms.test_utils.project.backwards_wizards.wizards import wizard
from cms.wizards.wizard_pool import wizard_pool


# NOTE: We keep this line separate from the actual wizard definition
# because if both are in the same file then importing the wizard causes
# this line to run, which makes it impossible to test properly
wizard_pool.register(wizard)
15 changes: 15 additions & 0 deletions cms/test_utils/project/backwards_wizards/wizards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from cms.wizards.wizard_base import Wizard

from cms.test_utils.project.sampleapp.forms import SampleWizardForm


class SampleWizard(Wizard):
pass


wizard = SampleWizard(
title="Sample",
weight=505,
form=SampleWizardForm,
description="Create something",
)
7 changes: 7 additions & 0 deletions cms/test_utils/project/sampleapp/cms_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from cms.app_base import CMSAppConfig
from cms.test_utils.project.sampleapp.cms_wizards import sample_wizard


class SampleAppConfig(CMSAppConfig):
cms_enabled = True
cms_wizards = [sample_wizard]
15 changes: 15 additions & 0 deletions cms/test_utils/project/sampleapp/cms_wizards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from cms.wizards.wizard_base import Wizard

from cms.test_utils.project.sampleapp.forms import SampleWizardForm


class SampleWizard(Wizard):
pass


sample_wizard = SampleWizard(
title="Sample",
weight=105,
form=SampleWizardForm,
description="Create a new Sample",
)
10 changes: 10 additions & 0 deletions cms/test_utils/project/sampleapp/forms.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# -*- coding: utf-8 -*-
from django import forms
from django.contrib.auth.forms import AuthenticationForm

from cms.test_utils.project.sampleapp.models import Category


class LoginForm(AuthenticationForm):
pass
Expand All @@ -13,3 +16,10 @@ class LoginForm2(AuthenticationForm):
class LoginForm3(AuthenticationForm):
def __init__(self, request=None, *args, **kwargs):
super(LoginForm3, self).__init__(request, *args, **kwargs)


class SampleWizardForm(forms.ModelForm):

class Meta:
model = Category
exclude = []
108 changes: 108 additions & 0 deletions cms/tests/test_cms_config_wizards.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
from mock import Mock, patch

from django.apps import apps
from django.core.exceptions import ImproperlyConfigured

from cms.app_registration import get_cms_extension_apps, get_cms_config_apps
from cms.cms_config import CMSCoreExtensions
from cms.cms_wizards import cms_page_wizard, cms_subpage_wizard
from cms.test_utils.project.sampleapp.cms_wizards import sample_wizard
from cms.test_utils.testcases import CMSTestCase
from cms.utils.setup import setup_cms_apps
from cms.wizards.wizard_base import Wizard


class ConfigureWizardsUnitTestCase(CMSTestCase):

def test_adds_wizards_to_dict(self):
"""
If the wizard setting is correctly defined, add the wizards to the
dictionary of wizards
"""
extensions = CMSCoreExtensions()
wizard1 = Mock(id=111, spec=Wizard)
wizard2 = Mock(id=222, spec=Wizard)
cms_config = Mock(
cms_enabled=True, cms_wizards=[wizard1, wizard2])
extensions.configure_wizards(cms_config)
self.assertDictEqual(
extensions.wizards, {111: wizard1, 222: wizard2})

def test_doesnt_raise_exception_when_wizards_dict_undefined(self):
"""
If the wizard setting is not present in the config, simply
ignore this. The wizard setting is optional.
"""
extensions = CMSCoreExtensions()
cms_config = Mock(cms_enabled=True, spec=[])
try:
extensions.configure_app(cms_config)
except AttributeError:
self.fail("Raises exception when cms_wizards undefined")

def test_raises_exception_if_doesnt_inherit_from_wizard_class(self):
"""
If one or more of the wizards defined in the wizard setting
do not inherit from the Wizard class, raise an exception
"""
extensions = CMSCoreExtensions()
wizard = Mock(id=3, spec=object)
cms_config = Mock(
cms_enabled=True, cms_wizards=[wizard])
with self.assertRaises(ImproperlyConfigured):
extensions.configure_wizards(cms_config)

def test_raises_exception_if_not_iterable(self):
"""
If the wizard setting isn't iterable, raise an exception.
"""
extensions = CMSCoreExtensions()
wizard = Mock(id=6, spec=Wizard)
cms_config = Mock(
cms_enabled=True, cms_wizards=wizard)
with self.assertRaises(ImproperlyConfigured):
extensions.configure_wizards(cms_config)

@patch('cms.cms_config.logger.warning')
def test_warning_if_registering_the_same_wizard_twice(self, mocked_logger):
"""
If a wizard is already added to the dict log a warning.
"""
extensions = CMSCoreExtensions()
wizard = Mock(id=81, spec=Wizard)
cms_config = Mock(
cms_enabled=True, cms_wizards=[wizard, wizard])
extensions.configure_wizards(cms_config)
warning_msg = "Wizard for model {} has already been registered".format(
wizard.get_model())
# Warning message displayed
mocked_logger.assert_called_once_with(warning_msg)
# wizards dict is still what we expect it to be
self.assertDictEqual(extensions.wizards, {81: wizard})


class ConfigureWizardsIntegrationTestCase(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
get_cms_extension_apps.cache_clear()
get_cms_config_apps.cache_clear()

def test_adds_all_wizards_to_dict(self):
"""
Check that all wizards are picked up from both cms.cms_config
and sampleapp.cms_config
"""
setup_cms_apps()
app = apps.get_app_config('cms')
# cms core defines wizards in its config, as does sampleapp
# all of these wizards should have been picked up and added
expected_wizards = {
cms_page_wizard.id: cms_page_wizard,
cms_subpage_wizard.id: cms_subpage_wizard,
sample_wizard.id: sample_wizard,
}
self.assertDictEqual(app.cms_extension.wizards, expected_wizards)
Loading
0