diff --git a/.editorconfig b/.editorconfig index a8e5db7c..e8c0f7d3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -17,6 +17,7 @@ quote_type = single [*.{scss,js,html}] max_line_length = 120 indent_style = space +insert_final_newline = false quote_type = double [*.js] diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 28be67ff..7f2c6888 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -1,42 +1,17 @@ -name: Lint +name: Ruff -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -on: [push, pull_request] +on: + push: + pull_request: jobs: - flake8: - name: flake8 + ruff: runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - name: Install flake8 - run: pip install --upgrade flake8 - - name: Run flake8 - uses: liskin/gh-problem-matcher-wrap@v3 - with: - linters: flake8 - run: flake8 - isort: - runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.10" - - run: python -m pip install isort - - name: isort - uses: liskin/gh-problem-matcher-wrap@v3 - with: - linters: isort - run: isort --check-only --diff ./ + - uses: actions/checkout@v4 + + - run: python -Im pip install --user ruff + + - name: Run ruff + run: ruff --output-format=github djangocms_alias diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 72459b58..8810c118 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -20,19 +20,16 @@ repos: - id: django-upgrade args: [--target-version, "3.2"] - - repo: https://github.com/PyCQA/flake8 - rev: 6.1.0 + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.2.0 hooks: - - id: flake8 - additional_dependencies: - - flake8-bugbear - - flake8-builtins - - flake8-comprehensions -# - flake8-eradicate - - flake8-tidy-imports - - pep8-naming + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - id: ruff-format - - repo: https://github.com/pycqa/isort - rev: 5.13.2 + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.5.0 hooks: - - id: isort + - id: check-yaml + - id: end-of-file-fixer + - id: trailing-whitespace diff --git a/.tx/config b/.tx/config index e4b1e0b2..88bab0fb 100755 --- a/.tx/config +++ b/.tx/config @@ -7,4 +7,3 @@ source_file = djangocms_alias/locale/en/LC_MESSAGES/django.po type = PO minimum_perc = 0 resource_name = django.po - diff --git a/LICENSE.txt b/LICENSE.txt index 2db1165f..66a81a69 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -21,4 +21,4 @@ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/djangocms_alias/__init__.py b/djangocms_alias/__init__.py index afced147..8c0d5d5b 100644 --- a/djangocms_alias/__init__.py +++ b/djangocms_alias/__init__.py @@ -1 +1 @@ -__version__ = '2.0.0' +__version__ = "2.0.0" diff --git a/djangocms_alias/admin.py b/djangocms_alias/admin.py index 0400bbbe..cd653b55 100644 --- a/djangocms_alias/admin.py +++ b/djangocms_alias/admin.py @@ -34,13 +34,13 @@ __all__ = [ - 'AliasAdmin', - 'CategoryAdmin', - 'AliasContentAdmin', + "AliasAdmin", + "CategoryAdmin", + "AliasContentAdmin", ] alias_admin_classes = [GrouperModelAdmin] -alias_admin_list_display = ['content__name', 'category', 'admin_list_actions'] +alias_admin_list_display = ["content__name", "category", "admin_list_actions"] djangocms_versioning_enabled = AliasCMSConfig.djangocms_versioning_enabled if djangocms_versioning_enabled: @@ -59,7 +59,7 @@ @admin.register(Category) class CategoryAdmin(TranslatableAdmin): - list_display = ['name'] + list_display = ["name"] def save_model(self, request, obj, form, change): change = not obj._state.adding @@ -77,9 +77,12 @@ def save_model(self, request, obj, form, change): class AliasAdmin(*alias_admin_classes): list_display = alias_admin_list_display list_display_links = None - list_filter = (SiteFilter, CategoryFilter,) - fields = ('content__name', 'category', 'site', 'content__language') - readonly_fields = ('static_code', ) + list_filter = ( + SiteFilter, + CategoryFilter, + ) + fields = ("content__name", "category", "site", "content__language") + readonly_fields = ("static_code",) form = AliasGrouperAdminForm extra_grouping_fields = ("language",) EMPTY_CONTENT_VALUE = mark_safe(_("Missing language")) @@ -91,7 +94,9 @@ def get_actions_list(self) -> list: """Add alias usage list actions""" return super().get_actions_list() + [self._get_alias_usage_link] - def can_change_content(self, request: HttpRequest, content_obj: AliasContent) -> bool: + def can_change_content( + self, request: HttpRequest, content_obj: AliasContent + ) -> bool: """Returns True if user can change content_obj""" if content_obj and is_versioning_enabled(): version = Version.objects.get_for_content(content_obj) @@ -104,12 +109,14 @@ def has_delete_permission(self, request: HttpRequest, obj: Alias = None) -> bool if obj: if not obj.is_in_use: return request.user.has_perm( - get_model_permission_codename(self.model, 'add'), + get_model_permission_codename(self.model, "add"), ) return request.user.is_superuser return False - def save_model(self, request: HttpRequest, obj: Alias, form: forms.Form, change: bool) -> None: + def save_model( + self, request: HttpRequest, obj: Alias, form: forms.Form, change: bool + ) -> None: super().save_model(request, obj, form, change) # Only emit content changes if Versioning is not installed because @@ -121,10 +128,15 @@ def save_model(self, request: HttpRequest, obj: Alias, form: forms.Form, change: ) def get_deleted_objects(self, objs, request: HttpRequest) -> tuple: - deleted_objects, model_count, perms_needed, protected = super().get_deleted_objects(objs, request) + ( + deleted_objects, + model_count, + perms_needed, + protected, + ) = super().get_deleted_objects(objs, request) # This is bad and I should feel bad. - if 'placeholder' in perms_needed: - perms_needed.remove('placeholder') + if "placeholder" in perms_needed: + perms_needed.remove("placeholder") return deleted_objects, model_count, perms_needed, protected def delete_model(self, request: HttpRequest, obj: Alias): @@ -138,14 +150,20 @@ def delete_model(self, request: HttpRequest, obj: Alias): sender=self.model, ) - def _get_alias_usage_link(self, obj: Alias, request: HttpRequest, disabled: bool = False) -> str: + def _get_alias_usage_link( + self, obj: Alias, request: HttpRequest, disabled: bool = False + ) -> str: url = admin_reverse(USAGE_ALIAS_URL_NAME, args=[obj.pk]) return self.admin_action_button(url, "info", _("View usage"), disabled=disabled) def _get_alias_delete_link(self, obj: Alias, request: HttpRequest) -> str: url = admin_reverse(DELETE_ALIAS_URL_NAME, args=[obj.pk]) - return self.admin_action_button(url, "bin", _("Delete Alias"), - disabled=not self.has_delete_permission(request, obj)) + return self.admin_action_button( + url, + "bin", + _("Delete Alias"), + disabled=not self.has_delete_permission(request, obj), + ) @admin.register(AliasContent) @@ -154,20 +172,31 @@ class AliasContentAdmin(admin.ModelAdmin): actions = None change_form_template = "admin/djangocms_alias/aliascontent/change_form.html" - def changelist_view(self, request: HttpRequest, extra_context: dict = None) -> HttpResponse: + def changelist_view( + self, request: HttpRequest, extra_context: dict = None + ) -> HttpResponse: """Needed for the Alias Content Admin breadcrumbs""" - return HttpResponseRedirect(admin_reverse( - LIST_ALIAS_URL_NAME, - )) - - def change_view(self, request: HttpRequest, object_id: int, form_url: str = '', extra_context: dict = None) -> HttpResponse: + return HttpResponseRedirect( + admin_reverse( + LIST_ALIAS_URL_NAME, + ) + ) + + def change_view( + self, + request: HttpRequest, + object_id: int, + form_url: str = "", + extra_context: dict = None, + ) -> HttpResponse: """Needed for the Alias Content Admin breadcrumbs""" obj = self.model.admin_manager.filter(pk=object_id).first() if not obj: raise Http404() - return HttpResponseRedirect(admin_reverse( - CHANGE_ALIAS_URL_NAME, args=(obj.alias_id,) - ) + f"?language={obj.language}") + return HttpResponseRedirect( + admin_reverse(CHANGE_ALIAS_URL_NAME, args=(obj.alias_id,)) + + f"?language={obj.language}" + ) def has_module_permission(self, request: HttpRequest) -> bool: """Hides admin class in admin site overview""" diff --git a/djangocms_alias/apps.py b/djangocms_alias/apps.py index 9b7374ad..bdb05b64 100644 --- a/djangocms_alias/apps.py +++ b/djangocms_alias/apps.py @@ -3,5 +3,5 @@ class AliasConfig(AppConfig): - name = 'djangocms_alias' - verbose_name = _('django CMS Alias') + name = "djangocms_alias" + verbose_name = _("django CMS Alias") diff --git a/djangocms_alias/cms_config.py b/djangocms_alias/cms_config.py index fd34e197..463b4d3f 100644 --- a/djangocms_alias/cms_config.py +++ b/djangocms_alias/cms_config.py @@ -8,7 +8,7 @@ try: - apps.get_app_config('djangocms_internalsearch') + apps.get_app_config("djangocms_internalsearch") from .internal_search import AliasContentConfig except (ImportError, LookupError): AliasContentConfig = None @@ -22,12 +22,14 @@ class AliasCMSConfig(CMSAppConfig): moderated_models = [AliasContent] djangocms_moderation_enabled = getattr( - settings, 'MODERATING_ALIAS_MODELS_ENABLED', True) - djangocms_versioning_enabled = getattr( - settings, 'VERSIONING_ALIAS_MODELS_ENABLED', True) and djangocms_versioning_installed + settings, "MODERATING_ALIAS_MODELS_ENABLED", True + ) + djangocms_versioning_enabled = ( + getattr(settings, "VERSIONING_ALIAS_MODELS_ENABLED", True) + and djangocms_versioning_installed + ) if djangocms_versioning_enabled: - from cms.utils.i18n import get_language_tuple from djangocms_versioning.datastructures import VersionableItem @@ -35,7 +37,7 @@ class AliasCMSConfig(CMSAppConfig): versioning = [ VersionableItem( content_model=AliasContent, - grouper_field_name='alias', + grouper_field_name="alias", extra_grouping_fields=["language"], version_list_filter_lookups={"language": get_language_tuple}, copy_function=copy_alias_content, @@ -44,9 +46,10 @@ class AliasCMSConfig(CMSAppConfig): ] djangocms_references_enabled = getattr( - settings, 'REFERENCES_ALIAS_MODELS_ENABLED', True) + settings, "REFERENCES_ALIAS_MODELS_ENABLED", True + ) reference_fields = [ - (AliasPlugin, 'alias'), + (AliasPlugin, "alias"), ] # Internalsearch configuration diff --git a/djangocms_alias/cms_menus.py b/djangocms_alias/cms_menus.py index 96c72124..bfad7a62 100644 --- a/djangocms_alias/cms_menus.py +++ b/djangocms_alias/cms_menus.py @@ -9,9 +9,8 @@ class AliasDisableMenu(Modifier): """Disable menu rendering on alias pages""" def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb): - if ( - request.toolbar.app_name == PLUGIN_URL_NAME_PREFIX - or isinstance(request.toolbar.obj, AliasContent) + if request.toolbar.app_name == PLUGIN_URL_NAME_PREFIX or isinstance( + request.toolbar.obj, AliasContent ): return [] return nodes diff --git a/djangocms_alias/cms_plugins.py b/djangocms_alias/cms_plugins.py index 05284e72..a426f355 100644 --- a/djangocms_alias/cms_plugins.py +++ b/djangocms_alias/cms_plugins.py @@ -20,13 +20,13 @@ __all__ = [ - 'Alias', + "Alias", ] @plugin_pool.register_plugin class Alias(CMSPluginBase): - name = _('Alias') + name = _("Alias") model = AliasPlugin form = AliasPluginForm @@ -35,8 +35,8 @@ def get_render_template(self, context, instance, placeholder): isinstance(instance.placeholder.source, AliasContent) and instance.is_recursive() ): - return 'djangocms_alias/alias_recursive.html' - return f'djangocms_alias/{instance.template}/alias.html' + return "djangocms_alias/alias_recursive.html" + return f"djangocms_alias/{instance.template}/alias.html" @classmethod def get_extra_plugin_menu_items(cls, request, plugin): @@ -49,10 +49,10 @@ def get_extra_plugin_menu_items(cls, request, plugin): plugin_menu_items = [ PluginMenuItem( - _('Edit Alias'), + _("Edit Alias"), edit_endpoint, - action='sideframe', - attributes={'cms-icon': 'alias'}, + action="sideframe", + attributes={"cms-icon": "alias"}, ), ] @@ -63,42 +63,42 @@ def get_extra_plugin_menu_items(cls, request, plugin): ): plugin_menu_items.append( PluginMenuItem( - _('Detach Alias'), + _("Detach Alias"), detach_endpoint, - action='modal', - attributes={'cms-icon': 'alias'}, + action="modal", + attributes={"cms-icon": "alias"}, ) ) return plugin_menu_items data = { - 'plugin': plugin.pk, - 'language': get_language_from_request(request, check_path=True), + "plugin": plugin.pk, + "language": get_language_from_request(request, check_path=True), } endpoint = add_url_parameters(admin_reverse(CREATE_ALIAS_URL_NAME), **data) return [ PluginMenuItem( - _('Create Alias'), + _("Create Alias"), endpoint, - action='modal', - attributes={'cms-icon': 'alias'}, + action="modal", + attributes={"cms-icon": "alias"}, ), ] @classmethod def get_extra_placeholder_menu_items(cls, request, placeholder): data = { - 'placeholder': placeholder.pk, - 'language': get_language_from_request(request, check_path=True), + "placeholder": placeholder.pk, + "language": get_language_from_request(request, check_path=True), } endpoint = add_url_parameters(admin_reverse(CREATE_ALIAS_URL_NAME), **data) menu_items = [ PluginMenuItem( - _('Create Alias'), + _("Create Alias"), endpoint, - action='modal', - attributes={'cms-icon': 'alias'}, + action="modal", + attributes={"cms-icon": "alias"}, ), ] return menu_items @@ -106,7 +106,7 @@ def get_extra_placeholder_menu_items(cls, request, placeholder): @classmethod def can_create_alias(cls, user, plugins=None, replace=False): if not user.has_perm( - get_model_permission_codename(AliasModel, 'add'), + get_model_permission_codename(AliasModel, "add"), ): return False @@ -114,9 +114,8 @@ def can_create_alias(cls, user, plugins=None, replace=False): return True elif replace: target_placeholder = plugins[0].placeholder - if ( - not target_placeholder.check_source(user) - or not has_plugin_permission(user, Alias.__name__, 'add') + if not target_placeholder.check_source(user) or not has_plugin_permission( + user, Alias.__name__, "add" ): return False @@ -124,8 +123,9 @@ def can_create_alias(cls, user, plugins=None, replace=False): has_plugin_permission( user, plugin.plugin_type, - 'add', - ) for plugin in plugins + "add", + ) + for plugin in plugins ) @classmethod @@ -134,13 +134,16 @@ def can_detach(cls, user, target_placeholder, plugins): has_plugin_permission( user, plugin.plugin_type, - 'add', - ) for plugin in plugins + "add", + ) + for plugin in plugins ) and target_placeholder.check_source(user) @classmethod def detach_alias_plugin(cls, plugin, language): - source_placeholder = plugin.alias.get_placeholder(language, show_draft_content=True) # We're in edit mode + source_placeholder = plugin.alias.get_placeholder( + language, show_draft_content=True + ) # We're in edit mode target_placeholder = plugin.placeholder # Deleting uses a copy of a plugin to preserve pk on existing diff --git a/djangocms_alias/cms_toolbars.py b/djangocms_alias/cms_toolbars.py index faca20c5..13bf9146 100644 --- a/djangocms_alias/cms_toolbars.py +++ b/djangocms_alias/cms_toolbars.py @@ -38,19 +38,19 @@ __all__ = [ - 'AliasToolbar', + "AliasToolbar", ] -ALIAS_MENU_IDENTIFIER = 'alias' -ALIAS_MENU_CREATE_IDENTIFIER = 'alias-add' -ALIAS_LANGUAGE_BREAK = 'alias-language' +ALIAS_MENU_IDENTIFIER = "alias" +ALIAS_MENU_CREATE_IDENTIFIER = "alias-add" +ALIAS_LANGUAGE_BREAK = "alias-language" @toolbar_pool.register class AliasToolbar(CMSToolbar): - name = _('Alias') - plural_name = _('Aliases') + name = _("Alias") + plural_name = _("Aliases") def populate(self): self.add_aliases_link_to_admin_menu() @@ -65,13 +65,17 @@ def post_template_populate(self): self.enable_create_wizard_button() def add_aliases_link_to_admin_menu(self): - if not self.request.user.has_perm('djangocms_alias.change_category'): + if not self.request.user.has_perm("djangocms_alias.change_category"): return admin_menu = self.toolbar.get_or_create_menu(ADMIN_MENU_IDENTIFIER) url = admin_reverse(LIST_ALIAS_URL_NAME) obj = self.toolbar.get_object() - language = obj.language if hasattr(obj, "language") else get_language_from_request(self.request) + language = ( + obj.language + if hasattr(obj, "language") + else get_language_from_request(self.request) + ) if language is None: language = get_default_language() url += f'?{urlencode({"language": language})}' @@ -90,18 +94,18 @@ def add_alias_menu(self): ) can_change = self.request.user.has_perm( - get_model_permission_codename(Alias, 'change'), + get_model_permission_codename(Alias, "change"), ) alias_menu.add_modal_item( - _('Change alias settings'), + _("Change alias settings"), url=admin_reverse( - 'djangocms_alias_alias_change', + "djangocms_alias_alias_change", args=[self.toolbar.obj.alias_id], ), disabled=not can_change, ) alias_menu.add_modal_item( - _('View usage'), + _("View usage"), url=admin_reverse( USAGE_ALIAS_URL_NAME, args=[self.toolbar.obj.alias_id], @@ -111,10 +115,10 @@ def add_alias_menu(self): # Only show deletion if versioning is not enabled if not is_versioning_enabled(): alias_menu.add_modal_item( - _('Delete alias'), + _("Delete alias"), url=admin_reverse( DELETE_ALIAS_URL_NAME, - args=(self.toolbar.obj.alias_id, ), + args=(self.toolbar.obj.alias_id,), ), on_close=admin_reverse( LIST_ALIAS_URL_NAME, @@ -137,7 +141,7 @@ def get_insert_position(cls, admin_menu, item_name): start = admin_menu.find_first(Break, identifier=SHORTCUTS_BREAK) end = admin_menu.find_first(Break, identifier=ADMINISTRATION_BREAK) - items = admin_menu.get_items()[start.index + 1: end.index] + items = admin_menu.get_items()[start.index + 1 : end.index] for idx, item in enumerate(items): try: if force_str(item_name.lower()) < force_str(item.name.lower()): # noqa: E501 @@ -149,21 +153,17 @@ def get_insert_position(cls, admin_menu, item_name): def enable_create_wizard_button(self): button_lists = [ - result.item - for result in self.toolbar.find_items(item_type=ButtonList) + result.item for result in self.toolbar.find_items(item_type=ButtonList) ] buttons = list( # flatten the list - itertools.chain.from_iterable([ - item.buttons - for item in button_lists - ]) + itertools.chain.from_iterable([item.buttons for item in button_lists]) ) # There will always be this button, because we are in the context of # alias app views create_wizard_button = [ - button for button in buttons if button.name == gettext('Create') + button for button in buttons if button.name == gettext("Create") ][0] from cms.wizards.wizard_pool import entry_choices @@ -177,7 +177,7 @@ def enable_create_wizard_button(self): create_wizard_button.disabled = not enable_create_wizard_button def override_language_switcher(self): - language_menu = self.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER, _('Language')) + language_menu = self.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER, _("Language")) if not language_menu: return # Remove all existing language links @@ -195,12 +195,14 @@ def override_language_switcher(self): if alias_content: with force_language(code): url = alias_content.get_absolute_url() - language_menu.add_link_item(name, url=url, active=self.current_lang == code) + language_menu.add_link_item( + name, url=url, active=self.current_lang == code + ) def change_language_menu(self): if self.toolbar.edit_mode_active and isinstance(self.toolbar.obj, AliasContent): can_change = self.request.user.has_perm( - get_model_permission_codename(Alias, 'change'), + get_model_permission_codename(Alias, "change"), ) else: can_change = False @@ -223,7 +225,9 @@ def change_language_menu(self): copy = [ (code, name) for code, name in languages.items() - if code != self.current_lang and (code, name) in remove and current_placeholder + if code != self.current_lang + and (code, name) in remove + and current_placeholder ] if add or remove or copy: @@ -231,19 +235,21 @@ def change_language_menu(self): if add: add_plugins_menu = language_menu.get_or_create_menu( - f'{LANGUAGE_MENU_IDENTIFIER}-add', - _('Add Translation'), + f"{LANGUAGE_MENU_IDENTIFIER}-add", + _("Add Translation"), ) - add_url = admin_reverse('djangocms_alias_aliascontent_add') + add_url = admin_reverse("djangocms_alias_aliascontent_add") for code, name in add: - url = add_url_parameters(add_url, language=code, alias=alias_content.alias_id) + url = add_url_parameters( + add_url, language=code, alias=alias_content.alias_id + ) add_plugins_menu.add_modal_item(name, url=url) if remove: remove_plugins_menu = language_menu.get_or_create_menu( - f'{LANGUAGE_MENU_IDENTIFIER}-del', - _('Delete Translation'), + f"{LANGUAGE_MENU_IDENTIFIER}-del", + _("Delete Translation"), ) disabled = len(remove) == 1 for code, name in remove: @@ -252,7 +258,7 @@ def change_language_menu(self): show_draft_content=True, ) translation_delete_url = admin_reverse( - 'djangocms_alias_aliascontent_delete', + "djangocms_alias_aliascontent_delete", args=(alias_content.pk,), ) url = add_url_parameters(translation_delete_url, language=code) @@ -260,16 +266,15 @@ def change_language_menu(self): if copy: copy_plugins_menu = language_menu.get_or_create_menu( - f'{LANGUAGE_MENU_IDENTIFIER}-copy', - _('Copy all plugins') + f"{LANGUAGE_MENU_IDENTIFIER}-copy", _("Copy all plugins") ) - title = _('from %s') - question = _('Are you sure you want to copy all plugins from %s?') + title = _("from %s") + question = _("Are you sure you want to copy all plugins from %s?") try: - copy_url = admin_reverse('cms_placeholder_copy_plugins') + copy_url = admin_reverse("cms_placeholder_copy_plugins") except NoReverseMatch: - copy_url = admin_reverse('djangocms_alias_alias_copy_plugins') + copy_url = admin_reverse("djangocms_alias_alias_copy_plugins") for code, name in copy: source_placeholder = alias_content.alias.get_placeholder( @@ -280,11 +285,11 @@ def change_language_menu(self): title % name, action=copy_url, data={ - 'source_language': code, - 'source_placeholder_id': source_placeholder.pk, - 'target_language': self.current_lang, - 'target_placeholder_id': current_placeholder.pk, + "source_language": code, + "source_placeholder_id": source_placeholder.pk, + "target_language": self.current_lang, + "target_placeholder_id": current_placeholder.pk, }, question=question % name, - on_success=self.toolbar.REFRESH_PAGE + on_success=self.toolbar.REFRESH_PAGE, ) diff --git a/djangocms_alias/cms_wizards.py b/djangocms_alias/cms_wizards.py index 55620c88..45573b6e 100644 --- a/djangocms_alias/cms_wizards.py +++ b/djangocms_alias/cms_wizards.py @@ -10,32 +10,30 @@ class CreateAliasWizard(Wizard): - def user_has_add_permission(self, user, **kwargs): return Alias.can_create_alias(user) class CreateAliasCategoryWizard(Wizard): - def user_has_add_permission(self, user, **kwargs): return user.has_perm( - get_model_permission_codename(Category, 'add'), + get_model_permission_codename(Category, "add"), ) create_alias_wizard = CreateAliasWizard( - title=_('New alias'), + title=_("New alias"), weight=200, form=CreateAliasWizardForm, model=AliasModel, - description=_('Create a new alias.'), + description=_("Create a new alias."), ) create_alias_category_wizard = CreateAliasCategoryWizard( - title=_('New alias category'), + title=_("New alias category"), weight=200, form=CreateCategoryWizardForm, model=Category, - description=_('Create a new alias category.'), + description=_("Create a new alias category."), ) wizard_pool.register(create_alias_wizard) diff --git a/djangocms_alias/constants.py b/djangocms_alias/constants.py index c6722319..a0950044 100644 --- a/djangocms_alias/constants.py +++ b/djangocms_alias/constants.py @@ -1,17 +1,16 @@ -PLUGIN_URL_NAME_PREFIX = 'djangocms_alias' +PLUGIN_URL_NAME_PREFIX = "djangocms_alias" # Alias Url endpoint names -CREATE_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_create' -DELETE_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_delete' -DETACH_ALIAS_PLUGIN_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_detach_plugin' -CATEGORY_LIST_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_category_changelist' -CHANGE_CATEGORY_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_category_change' -SELECT2_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_select2' -USAGE_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_alias_usage' -LIST_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_alias_changelist' -CHANGE_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_alias_change' -DELETE_ALIAS_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_alias_delete' -CATEGORY_SELECT2_URL_NAME = f'{PLUGIN_URL_NAME_PREFIX}_category_list_select2' +CREATE_ALIAS_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_create" +DETACH_ALIAS_PLUGIN_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_detach_plugin" +CATEGORY_LIST_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_category_changelist" +CHANGE_CATEGORY_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_category_change" +SELECT2_ALIAS_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_select2" +USAGE_ALIAS_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_alias_usage" +LIST_ALIAS_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_alias_changelist" +CHANGE_ALIAS_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_alias_change" +DELETE_ALIAS_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_alias_delete" +CATEGORY_SELECT2_URL_NAME = f"{PLUGIN_URL_NAME_PREFIX}_category_list_select2" # Static Alias DEFAULT_STATIC_ALIAS_CATEGORY_NAME = "Static Alias" diff --git a/djangocms_alias/filters.py b/djangocms_alias/filters.py index fd2f1f46..9ed8da67 100644 --- a/djangocms_alias/filters.py +++ b/djangocms_alias/filters.py @@ -61,9 +61,13 @@ class CategoryFilter(admin.SimpleListFilter): def lookups(self, request, model_admin): # Only offer categories available qs = model_admin.get_queryset(request) - cat_id = qs.values_list('category', flat=True) + cat_id = qs.values_list("category", flat=True) # Ensure the category is ordered by the name alphabetically by default - cat = Category.objects.filter(pk__in=cat_id).translated(get_language()).order_by('translations__name') + cat = ( + Category.objects.filter(pk__in=cat_id) + .translated(get_language()) + .order_by("translations__name") + ) for obj in cat: yield str(obj.pk), smart_str(obj) diff --git a/djangocms_alias/forms.py b/djangocms_alias/forms.py index a958d3ff..31c0047f 100644 --- a/djangocms_alias/forms.py +++ b/djangocms_alias/forms.py @@ -30,35 +30,35 @@ __all__ = [ - 'AliasPluginForm', - 'BaseCreateAliasForm', - 'CreateAliasForm', - 'CreateAliasWizardForm', - 'CreateCategoryWizardForm', + "AliasPluginForm", + "BaseCreateAliasForm", + "CreateAliasForm", + "CreateAliasWizardForm", + "CreateCategoryWizardForm", ] def get_category_widget(formfield, user): - dbfield = AliasModel._meta.get_field('category') + dbfield = AliasModel._meta.get_field("category") return RelatedFieldWidgetWrapper( formfield.widget, dbfield.remote_field, admin_site=admin.site, can_add_related=user.has_perm( - get_model_permission_codename(Category, 'add'), + get_model_permission_codename(Category, "add"), ), can_change_related=user.has_perm( - get_model_permission_codename(Category, 'change'), + get_model_permission_codename(Category, "change"), ), can_delete_related=user.has_perm( - get_model_permission_codename(Category, 'delete'), + get_model_permission_codename(Category, "delete"), ), ) class BaseCreateAliasForm(forms.Form): plugin = forms.ModelChoiceField( - queryset=CMSPlugin.objects.exclude(plugin_type='Alias'), + queryset=CMSPlugin.objects.exclude(plugin_type="Alias"), required=False, widget=forms.HiddenInput(), ) @@ -72,19 +72,19 @@ class BaseCreateAliasForm(forms.Form): def clean(self): cleaned_data = super().clean() - plugin = cleaned_data.get('plugin') - placeholder = cleaned_data.get('placeholder') + plugin = cleaned_data.get("plugin") + placeholder = cleaned_data.get("placeholder") if not plugin and not placeholder: raise forms.ValidationError( - _('A plugin or placeholder is required to create an alias.') + _("A plugin or placeholder is required to create an alias.") ) if plugin and placeholder: raise forms.ValidationError( _( - 'An alias can only be created from a plugin or placeholder, ' # noqa: E501 - 'not both.' + "An alias can only be created from a plugin or placeholder, " # noqa: E501 + "not both." ) ) @@ -102,18 +102,18 @@ class CreateAliasForm(BaseCreateAliasForm): required=True, ) replace = forms.BooleanField( - label=_('Replace current plugin'), - help_text=_('Replace current plugin with alias'), + label=_("Replace current plugin"), + help_text=_("Replace current plugin with alias"), required=False, ) def __init__(self, *args, **kwargs): - self.user = kwargs.pop('user') + self.user = kwargs.pop("user") super().__init__(*args, **kwargs) - if not has_plugin_permission(self.user, 'Alias', 'add'): - self.fields['replace'].widget = forms.HiddenInput() + if not has_plugin_permission(self.user, "Alias", "add"): + self.fields["replace"].widget = forms.HiddenInput() self.set_category_widget(self.user) self.fields["site"].initial = get_current_site() @@ -122,27 +122,27 @@ def clean(self): cleaned_data = super().clean() if AliasContent.objects.filter( - name=cleaned_data.get('name'), - language=cleaned_data.get('language'), - alias__category=cleaned_data.get('category'), + name=cleaned_data.get("name"), + language=cleaned_data.get("language"), + alias__category=cleaned_data.get("category"), ).exists(): raise forms.ValidationError( - _('Alias with this Name and Category already exists.') + _("Alias with this Name and Category already exists.") ) return cleaned_data def set_category_widget(self, user): - formfield = self.fields['category'] + formfield = self.fields["category"] formfield.widget = get_category_widget(formfield, user) def get_plugins(self): - plugin = self.cleaned_data.get('plugin') - placeholder = self.cleaned_data.get('placeholder') + plugin = self.cleaned_data.get("plugin") + placeholder = self.cleaned_data.get("placeholder") if placeholder: plugins = placeholder.get_plugins( - self.cleaned_data.get('language'), + self.cleaned_data.get("language"), ) else: plugins = [plugin] + list(plugin.get_descendants()) @@ -150,20 +150,21 @@ def get_plugins(self): def save(self): alias = AliasModel.objects.create( - category=self.cleaned_data.get('category'), - site=self.cleaned_data.get('site'), + category=self.cleaned_data.get("category"), + site=self.cleaned_data.get("site"), ) alias_content = AliasContent.objects.create( alias=alias, - name=self.cleaned_data.get('name'), - language=self.cleaned_data.get('language'), + name=self.cleaned_data.get("name"), + language=self.cleaned_data.get("language"), ) if is_versioning_enabled(): from djangocms_versioning.models import Version + Version.objects.create(content=alias_content, created_by=self.user) - if self.cleaned_data.get('replace'): - placeholder = self.cleaned_data.get('placeholder') - plugin = self.cleaned_data.get('plugin') + if self.cleaned_data.get("replace"): + placeholder = self.cleaned_data.get("placeholder") + plugin = self.cleaned_data.get("plugin") source_plugins = None else: placeholder, plugin = None, None @@ -178,9 +179,7 @@ def save(self): class CreateAliasWizardForm(forms.Form): name = forms.CharField( - label=_('Name'), - required=True, - widget=AdminTextInputWidget() + label=_("Name"), required=True, widget=AdminTextInputWidget() ) site = forms.ModelChoiceField( queryset=Site.objects.all(), @@ -193,30 +192,31 @@ class CreateAliasWizardForm(forms.Form): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - if not getattr(self, 'user', None): + if not getattr(self, "user", None): self.user = self._request.user self.set_category_widget(self.user) self.fields["site"].initial = get_current_site() def set_category_widget(self, user): - formfield = self.fields['category'] + formfield = self.fields["category"] formfield.widget = get_category_widget(formfield, user) @transaction.atomic def save(self): alias = AliasModel.objects.create( - category=self.cleaned_data.get('category'), - site=self.cleaned_data.get('site'), + category=self.cleaned_data.get("category"), + site=self.cleaned_data.get("site"), ) alias_content = AliasContent( alias=alias, - name=self.cleaned_data.get('name'), + name=self.cleaned_data.get("name"), language=self.language_code, ) alias_content.save() # Does not create a Version object if is_versioning_enabled(): from djangocms_versioning.models import Version + Version.objects.create(content=alias_content, created_by=self._request.user) emit_content_change([alias_content]) @@ -224,25 +224,23 @@ def save(self): class CreateCategoryWizardForm(TranslatableModelForm): - class Meta: model = Category fields = [ - 'name', + "name", ] class Select2Mixin: - class Media: css = { - 'all': ('cms/js/select2/select2.css', ), + "all": ("cms/js/select2/select2.css",), } js = ( - 'admin/js/jquery.init.js', - 'cms/js/select2/select2.js', - 'djangocms_alias/js/dist/bundle.alias.create.min.js', - 'djangocms_alias/js/alias_plugin.js', + "admin/js/jquery.init.js", + "cms/js/select2/select2.js", + "djangocms_alias/js/dist/bundle.alias.create.min.js", + "djangocms_alias/js/alias_plugin.js", ) @@ -252,18 +250,17 @@ def get_url(self): def build_attrs(self, *args, **kwargs): attrs = super().build_attrs(*args, **kwargs) - attrs.setdefault('data-select2-url', self.get_url()) + attrs.setdefault("data-select2-url", self.get_url()) return attrs class AliasSelectWidget(Select2Mixin, forms.TextInput): - def get_url(self): return admin_reverse(SELECT2_ALIAS_URL_NAME) def build_attrs(self, *args, **kwargs): attrs = super().build_attrs(*args, **kwargs) - attrs.setdefault('data-select2-url', self.get_url()) + attrs.setdefault("data-select2-url", self.get_url()) return attrs @@ -276,22 +273,24 @@ class AliasPluginForm(forms.ModelForm): ) category = forms.ModelChoiceField( - label=_('Category'), + label=_("Category"), queryset=Category.objects.all(), widget=CategorySelectWidget( attrs={ - 'data-placeholder': _('Select category to restrict the list of aliases below'), # noqa: E501 + "data-placeholder": _( + "Select category to restrict the list of aliases below" + ), # noqa: E501 }, ), - empty_label='', + empty_label="", required=False, ) alias = forms.ModelChoiceField( - label=_('Alias'), + label=_("Alias"), queryset=AliasModel.objects.all(), widget=AliasSelectWidget( attrs={ - 'data-placeholder': _('Select an alias'), + "data-placeholder": _("Select an alias"), }, ), ) @@ -307,20 +306,20 @@ def _set_category_widget_value(self): # If the form is changing an existing Alias # Be sure to show the values for an Alias if self.instance and self.instance.pk: - self.fields['category'].initial = self.instance.alias.category + self.fields["category"].initial = self.instance.alias.category # Otherwise this is creation # Set the site to the current site by default else: pass - self.fields['site'].initial = get_current_site() + self.fields["site"].initial = get_current_site() class Meta: model = AliasPlugin fields = ( - 'site', - 'category', - 'alias', - 'template', + "site", + "category", + "alias", + "template", ) @@ -332,12 +331,12 @@ class Meta: def clean(self): cleaned_data = super().clean() if AliasContent.admin_manager.filter( - name=cleaned_data.get('name'), - language=cleaned_data.get('language'), - alias__category=cleaned_data.get('category'), + name=cleaned_data.get("name"), + language=cleaned_data.get("language"), + alias__category=cleaned_data.get("category"), ).exists(): raise forms.ValidationError( - _('Alias with this Name and Category already exists.') + _("Alias with this Name and Category already exists.") ) return cleaned_data diff --git a/djangocms_alias/internal_search.py b/djangocms_alias/internal_search.py index acb0e5e3..f7bfdced 100644 --- a/djangocms_alias/internal_search.py +++ b/djangocms_alias/internal_search.py @@ -14,14 +14,14 @@ def get_title(obj): return obj.result.title -get_title.short_description = _('Title') +get_title.short_description = _("Title") def get_category(obj): return obj.result.category -get_category.short_description = _('Category') +get_category.short_description = _("Category") def get_language(obj): @@ -63,8 +63,8 @@ class AliasContentConfig(BaseSearchConfig): def prepare_text(self, obj): request = get_request(obj.language) context = RequestContext(request) - if 'request' not in context: - context['request'] = request + if "request" not in context: + context["request"] = request toolbar = get_toolbar_from_request(request) renderer = toolbar.get_content_renderer() diff --git a/djangocms_alias/locale/de/LC_MESSAGES/django.po b/djangocms_alias/locale/de/LC_MESSAGES/django.po index 1543d222..08f3023c 100644 --- a/djangocms_alias/locale/de/LC_MESSAGES/django.po +++ b/djangocms_alias/locale/de/LC_MESSAGES/django.po @@ -2,10 +2,10 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# # Translators: # Fabian Braun , 2023 -# +# #, fuzzy msgid "" msgstr "" diff --git a/djangocms_alias/locale/nl/LC_MESSAGES/django.po b/djangocms_alias/locale/nl/LC_MESSAGES/django.po index f31ac73c..9721514e 100644 --- a/djangocms_alias/locale/nl/LC_MESSAGES/django.po +++ b/djangocms_alias/locale/nl/LC_MESSAGES/django.po @@ -2,11 +2,11 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# # Translators: # Fabian Braun , 2023 # Stefan van den Eertwegh , 2023 -# +# #, fuzzy msgid "" msgstr "" diff --git a/djangocms_alias/locale/sq/LC_MESSAGES/django.po b/djangocms_alias/locale/sq/LC_MESSAGES/django.po index 34e4509b..fa4319ec 100644 --- a/djangocms_alias/locale/sq/LC_MESSAGES/django.po +++ b/djangocms_alias/locale/sq/LC_MESSAGES/django.po @@ -2,10 +2,10 @@ # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. -# +# # Translators: # Besnik Bleta , 2023 -# +# #, fuzzy msgid "" msgstr "" diff --git a/djangocms_alias/migrations/0001_initial.py b/djangocms_alias/migrations/0001_initial.py index f8b02372..a8b484d9 100644 --- a/djangocms_alias/migrations/0001_initial.py +++ b/djangocms_alias/migrations/0001_initial.py @@ -10,86 +10,183 @@ class Migration(migrations.Migration): - initial = True dependencies = [ - ('cms', '0034_remove_pagecontent_placeholders'), + ("cms", "0034_remove_pagecontent_placeholders"), ] operations = [ migrations.CreateModel( - name='Alias', + name="Alias", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('position', models.PositiveIntegerField(default=0, verbose_name='position')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "position", + models.PositiveIntegerField(default=0, verbose_name="position"), + ), ], options={ - 'verbose_name': 'alias', - 'verbose_name_plural': 'aliases', - 'ordering': ['position'], + "verbose_name": "alias", + "verbose_name_plural": "aliases", + "ordering": ["position"], }, ), migrations.CreateModel( - name='AliasContent', + name="AliasContent", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('name', models.CharField(max_length=120, verbose_name='name')), - ('language', models.CharField(choices=settings.LANGUAGES, default=cms.utils.i18n.get_current_language, max_length=10)), - ('alias', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contents', to='djangocms_alias.Alias')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("name", models.CharField(max_length=120, verbose_name="name")), + ( + "language", + models.CharField( + choices=settings.LANGUAGES, + default=cms.utils.i18n.get_current_language, + max_length=10, + ), + ), + ( + "alias", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="contents", + to="djangocms_alias.Alias", + ), + ), ], options={ - 'verbose_name': 'alias content', - 'verbose_name_plural': 'alias contents', + "verbose_name": "alias content", + "verbose_name_plural": "alias contents", }, ), migrations.CreateModel( - name='AliasPlugin', + name="AliasPlugin", fields=[ - ('cmsplugin_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='djangocms_alias_aliasplugin', serialize=False, to='cms.CMSPlugin')), - ('template', models.CharField(choices=get_templates(), default=TEMPLATE_DEFAULT, max_length=255, verbose_name='template')), - ('alias', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='cms_plugins', to='djangocms_alias.Alias', verbose_name='alias')), + ( + "cmsplugin_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + related_name="djangocms_alias_aliasplugin", + serialize=False, + to="cms.CMSPlugin", + ), + ), + ( + "template", + models.CharField( + choices=get_templates(), + default=TEMPLATE_DEFAULT, + max_length=255, + verbose_name="template", + ), + ), + ( + "alias", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="cms_plugins", + to="djangocms_alias.Alias", + verbose_name="alias", + ), + ), ], options={ - 'verbose_name': 'alias plugin model', - 'verbose_name_plural': 'alias plugin models', + "verbose_name": "alias plugin model", + "verbose_name_plural": "alias plugin models", }, - bases=('cms.cmsplugin',), + bases=("cms.cmsplugin",), ), migrations.CreateModel( - name='Category', + name="Category", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), ], options={ - 'verbose_name': 'category', - 'verbose_name_plural': 'categories', + "verbose_name": "category", + "verbose_name_plural": "categories", }, bases=(parler.models.TranslatableModelMixin, models.Model), ), migrations.CreateModel( - name='CategoryTranslation', + name="CategoryTranslation", fields=[ - ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), - ('language_code', models.CharField(db_index=True, max_length=15, verbose_name='Language')), - ('name', models.CharField(max_length=120, unique=True, verbose_name='name')), - ('master', models.ForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='djangocms_alias.Category')), + ( + "id", + models.AutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "language_code", + models.CharField( + db_index=True, max_length=15, verbose_name="Language" + ), + ), + ( + "name", + models.CharField(max_length=120, unique=True, verbose_name="name"), + ), + ( + "master", + models.ForeignKey( + editable=False, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="translations", + to="djangocms_alias.Category", + ), + ), ], options={ - 'verbose_name': 'category Translation', - 'db_table': 'djangocms_alias_category_translation', - 'db_tablespace': '', - 'managed': True, - 'default_permissions': (), + "verbose_name": "category Translation", + "db_table": "djangocms_alias_category_translation", + "db_tablespace": "", + "managed": True, + "default_permissions": (), }, ), migrations.AddField( - model_name='alias', - name='category', - field=models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, related_name='aliases', to='djangocms_alias.Category', verbose_name='category'), + model_name="alias", + name="category", + field=models.ForeignKey( + on_delete=django.db.models.deletion.PROTECT, + related_name="aliases", + to="djangocms_alias.Category", + verbose_name="category", + ), ), migrations.AlterUniqueTogether( - name='categorytranslation', - unique_together={('language_code', 'master')}, + name="categorytranslation", + unique_together={("language_code", "master")}, ), ] diff --git a/djangocms_alias/migrations/0002_auto_20200723_1424.py b/djangocms_alias/migrations/0002_auto_20200723_1424.py index ab296d63..dbc91d23 100644 --- a/djangocms_alias/migrations/0002_auto_20200723_1424.py +++ b/djangocms_alias/migrations/0002_auto_20200723_1424.py @@ -6,35 +6,57 @@ class Migration(migrations.Migration): - dependencies = [ - ('sites', '0002_alter_domain_unique'), - ('djangocms_alias', '0001_initial'), + ("sites", "0002_alter_domain_unique"), + ("djangocms_alias", "0001_initial"), ] operations = [ migrations.AddField( - model_name='alias', - name='creation_method', - field=models.CharField(blank=True, choices=[('template', 'by template'), ('code', 'by code')], default='code', max_length=20, verbose_name='creation_method'), + model_name="alias", + name="creation_method", + field=models.CharField( + blank=True, + choices=[("template", "by template"), ("code", "by code")], + default="code", + max_length=20, + verbose_name="creation_method", + ), ), migrations.AddField( - model_name='alias', - name='site', - field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='sites.Site'), + model_name="alias", + name="site", + field=models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.CASCADE, + to="sites.Site", + ), ), migrations.AddField( - model_name='alias', - name='static_code', - field=models.CharField(blank=True, help_text='To render the alias in templates.', max_length=255, null=True, verbose_name='static code'), + model_name="alias", + name="static_code", + field=models.CharField( + blank=True, + help_text="To render the alias in templates.", + max_length=255, + null=True, + verbose_name="static code", + ), ), migrations.AlterField( - model_name='categorytranslation', - name='master', - field=parler.fields.TranslationsForeignKey(editable=False, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='translations', to='djangocms_alias.Category'), + model_name="categorytranslation", + name="master", + field=parler.fields.TranslationsForeignKey( + editable=False, + null=True, + on_delete=django.db.models.deletion.CASCADE, + related_name="translations", + to="djangocms_alias.Category", + ), ), migrations.AlterUniqueTogether( - name='alias', - unique_together={('static_code', 'site')}, + name="alias", + unique_together={("static_code", "site")}, ), ] diff --git a/djangocms_alias/migrations/0003_auto_20230725_1547.py b/djangocms_alias/migrations/0003_auto_20230725_1547.py index 04473f86..872e77de 100644 --- a/djangocms_alias/migrations/0003_auto_20230725_1547.py +++ b/djangocms_alias/migrations/0003_auto_20230725_1547.py @@ -3,26 +3,34 @@ from django.db import migrations, models import django.db.models.deletion -class Migration(migrations.Migration): +class Migration(migrations.Migration): dependencies = [ - ('cms', '__first__'), - ('djangocms_alias', '0002_auto_20200723_1424'), + ("cms", "__first__"), + ("djangocms_alias", "0002_auto_20200723_1424"), ] operations = [ migrations.AlterField( - model_name='aliasplugin', - name='cmsplugin_ptr', - field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, related_name='%(app_label)s_%(class)s', serialize=False, to='cms.cmsplugin'), + model_name="aliasplugin", + name="cmsplugin_ptr", + field=models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + related_name="%(app_label)s_%(class)s", + serialize=False, + to="cms.cmsplugin", + ), ), migrations.AlterField( - model_name='categorytranslation', - name='name', - field=models.CharField(max_length=120, verbose_name='name'), + model_name="categorytranslation", + name="name", + field=models.CharField(max_length=120, verbose_name="name"), ), migrations.AlterUniqueTogether( - name='categorytranslation', - unique_together={('language_code', 'master'), ('name', 'language_code')}, + name="categorytranslation", + unique_together={("language_code", "master"), ("name", "language_code")}, ), ] diff --git a/djangocms_alias/migrations/0004_alter_aliascontent_language.py b/djangocms_alias/migrations/0004_alter_aliascontent_language.py index 122efd72..0fdd5bff 100644 --- a/djangocms_alias/migrations/0004_alter_aliascontent_language.py +++ b/djangocms_alias/migrations/0004_alter_aliascontent_language.py @@ -5,15 +5,16 @@ class Migration(migrations.Migration): - dependencies = [ - ('djangocms_alias', '0003_auto_20230725_1547'), + ("djangocms_alias", "0003_auto_20230725_1547"), ] operations = [ migrations.AlterField( - model_name='aliascontent', - name='language', - field=models.CharField(default=django.utils.translation.get_language, max_length=10), + model_name="aliascontent", + name="language", + field=models.CharField( + default=django.utils.translation.get_language, max_length=10 + ), ), ] diff --git a/djangocms_alias/models.py b/djangocms_alias/models.py index 1bd9793c..183f2ee6 100644 --- a/djangocms_alias/models.py +++ b/djangocms_alias/models.py @@ -24,24 +24,24 @@ __all__ = [ - 'Category', - 'Alias', - 'AliasContent', - 'AliasPlugin', + "Category", + "Alias", + "AliasContent", + "AliasPlugin", ] # Add additional choices through the ``settings.py``. -TEMPLATE_DEFAULT = 'default' +TEMPLATE_DEFAULT = "default" def get_templates(): choices = [ - (TEMPLATE_DEFAULT, _('Default')), + (TEMPLATE_DEFAULT, _("Default")), ] choices += getattr( settings, - 'DJANGOCMS_ALIAS_TEMPLATES', + "DJANGOCMS_ALIAS_TEMPLATES", [], ) return choices @@ -50,15 +50,15 @@ def get_templates(): class Category(TranslatableModel): translations = TranslatedFields( name=models.CharField( - verbose_name=_('name'), + verbose_name=_("name"), max_length=120, ), - meta={'unique_together': [('name', 'language_code')]}, + meta={"unique_together": [("name", "language_code")]}, ) class Meta: - verbose_name = _('category') - verbose_name_plural = _('categories') + verbose_name = _("category") + verbose_name_plural = _("categories") def __str__(self): # Be sure to be able to see the category name even if it's not in the current language @@ -70,40 +70,45 @@ def get_absolute_url(self): class Alias(models.Model): - CREATION_BY_TEMPLATE = 'template' - CREATION_BY_CODE = 'code' + CREATION_BY_TEMPLATE = "template" + CREATION_BY_CODE = "code" CREATION_METHODS = ( - (CREATION_BY_TEMPLATE, _('by template')), - (CREATION_BY_CODE, _('by code')), + (CREATION_BY_TEMPLATE, _("by template")), + (CREATION_BY_CODE, _("by code")), ) creation_method = models.CharField( - verbose_name=_('creation_method'), choices=CREATION_METHODS, - default=CREATION_BY_CODE, max_length=20, blank=True, + verbose_name=_("creation_method"), + choices=CREATION_METHODS, + default=CREATION_BY_CODE, + max_length=20, + blank=True, ) category = models.ForeignKey( Category, - verbose_name=_('category'), - related_name='aliases', + verbose_name=_("category"), + related_name="aliases", on_delete=models.PROTECT, ) position = models.PositiveIntegerField( - verbose_name=_('position'), + verbose_name=_("position"), default=0, ) static_code = models.CharField( - verbose_name=_('static code'), + verbose_name=_("static code"), max_length=255, blank=True, null=True, - help_text=_('To render the alias in templates.') + help_text=_("To render the alias in templates."), ) site = models.ForeignKey(Site, on_delete=models.CASCADE, null=True, blank=True) class Meta: - verbose_name = _('alias') - verbose_name_plural = _('aliases') - ordering = ['position'] - unique_together = (('static_code', 'site'),) # Only restrict instances that have a site specified + verbose_name = _("alias") + verbose_name_plural = _("aliases") + ordering = ["position"] + unique_together = ( + ("static_code", "site"), + ) # Only restrict instances that have a site specified def __init__(self, *args, **kwargs): self._plugins_cache = {} @@ -117,7 +122,7 @@ def __str__(self): @cached_property def name(self): """Show alias name for current language""" - return self.get_name() or '' + return self.get_name() or "" @cached_property def is_in_use(self): @@ -127,36 +132,41 @@ def is_in_use(self): def objects_using(self): objects = set() object_ids = defaultdict(set) - plugins = self.cms_plugins.select_related('placeholder').prefetch_related('placeholder__source') + plugins = self.cms_plugins.select_related("placeholder").prefetch_related( + "placeholder__source" + ) for plugin in plugins: obj = plugin.placeholder.source obj_class_name = obj.__class__.__name__ - if obj_class_name.endswith('Content'): - attr_name = obj_class_name.replace('Content', '').lower() + if obj_class_name.endswith("Content"): + attr_name = obj_class_name.replace("Content", "").lower() attr_related_model = obj._meta.get_field(attr_name).related_model - id_attr = getattr(obj, f'{attr_name}_id') + id_attr = getattr(obj, f"{attr_name}_id") if id_attr: object_ids[attr_related_model].update([id_attr]) else: objects.update([obj]) else: objects.update([obj]) - objects.update([ - obj - for model_class, ids in object_ids.items() - for obj in model_class.objects.filter(pk__in=ids) - ]) + objects.update( + [ + obj + for model_class, ids in object_ids.items() + for obj in model_class.objects.filter(pk__in=ids) + ] + ) return list(objects) def get_name(self, language=None): content = self.get_content(language, show_draft_content=True) - name = getattr(content, 'name', f'Alias {self.pk} (No content)') + name = getattr(content, "name", f"Alias {self.pk} (No content)") if is_versioning_enabled() and content: from djangocms_versioning.constants import DRAFT + version = content.versions.first() if version.state == DRAFT: - return f'{name} (Not published)' + return f"{name} (Not published)" return name @@ -182,18 +192,22 @@ def get_content(self, language=None, show_draft_content=False): qs = self.contents(manager="admin_manager").latest_content() else: qs = self.contents.all() - qs = qs.select_related( - 'alias__category', - ).prefetch_related( - 'placeholders' - ).filter(language=language) + qs = ( + qs.select_related( + "alias__category", + ) + .prefetch_related("placeholders") + .filter(language=language) + ) self._content_cache[language] = qs.first() return self._content_cache[language] def get_placeholder(self, language=None, show_draft_content=False): - content = self.get_content(language=language, show_draft_content=show_draft_content) - return getattr(content, 'placeholder', None) + content = self.get_content( + language=language, show_draft_content=show_draft_content + ) + return getattr(content, "placeholder", None) def get_plugins(self, language=None): if not language: @@ -209,7 +223,7 @@ def get_plugins(self, language=None): def get_languages(self): if not self._content_languages_cache: queryset = self.contents(manager="admin_manager").current_content() - self._content_languages_cache = queryset.values_list('language', flat=True) + self._content_languages_cache = queryset.values_list("language", flat=True) return self._content_languages_cache def clear_cache(self): @@ -221,7 +235,7 @@ def clear_cache(self): def delete(self, *args, **kwargs): super().delete(*args, **kwargs) self.category.aliases.filter(position__gt=self.position).update( - position=F('position') - 1, + position=F("position") - 1, ) def save(self, *args, **kwargs): @@ -246,11 +260,12 @@ def _set_position(self, position): self.position = position self.save() - self.category.aliases.filter(*filters).update(position=op(F('position'), 1)) # noqa: E501 + self.category.aliases.filter(*filters).update(position=op(F("position"), 1)) # noqa: E501 class AliasContentManager(WithUserMixin, models.Manager): """Adds with_user syntax to AliasContent w/o using versioning""" + pass @@ -258,14 +273,14 @@ class AliasContent(models.Model): alias = models.ForeignKey( Alias, on_delete=models.CASCADE, - related_name='contents', + related_name="contents", ) name = models.CharField( - verbose_name=_('name'), + verbose_name=_("name"), max_length=120, ) placeholders = PlaceholderRelationField() - placeholder_slotname = 'content' + placeholder_slotname = "content" language = models.CharField( max_length=10, default=get_language, @@ -274,15 +289,15 @@ class AliasContent(models.Model): objects = AliasContentManager() class Meta: - verbose_name = _('alias content') - verbose_name_plural = _('alias contents') + verbose_name = _("alias content") + verbose_name_plural = _("alias contents") def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self._meta.get_field('language').choices = settings.LANGUAGES + self._meta.get_field("language").choices = settings.LANGUAGES def __str__(self): - return f'{self.name} ({self.language})' + return f"{self.name} ({self.language})" @cached_property def placeholder(self): @@ -290,6 +305,7 @@ def placeholder(self): return self.placeholders.get(slot=self.placeholder_slotname) except Placeholder.DoesNotExist: from cms.utils.placeholder import rescan_placeholders_for_obj + rescan_placeholders_for_obj(self) return self.placeholders.get(slot=self.placeholder_slotname) @@ -300,7 +316,7 @@ def get_absolute_url(self): return get_object_preview_url(self) def get_template(self): - return 'djangocms_alias/alias_content.html' + return "djangocms_alias/alias_content.html" @transaction.atomic def delete(self, *args, **kwargs): @@ -325,7 +341,7 @@ def populate(self, replaced_placeholder=None, replaced_plugin=None, plugins=None id__in=[replaced_plugin.pk] + replaced_plugin._get_descendants_ids(), ) placeholder = replaced_plugin.placeholder - add_plugin_kwargs = {'position': 'left', 'target': replaced_plugin} + add_plugin_kwargs = {"position": "left", "target": replaced_plugin} copy_plugins_to_placeholder( plugins, @@ -337,14 +353,14 @@ def populate(self, replaced_placeholder=None, replaced_plugin=None, plugins=None new_plugin = add_plugin( placeholder, - plugin_type='Alias', + plugin_type="Alias", language=self.language, alias=self.alias, - **add_plugin_kwargs + **add_plugin_kwargs, ) if replaced_plugin: new_plugin.position = replaced_plugin.position - new_plugin.save(update_fields=['position']) + new_plugin.save(update_fields=["position"]) return new_plugin @@ -371,10 +387,10 @@ def copy_alias_content(original_content): for field in Placeholder._meta.fields # don't copy primary key because we're creating a new obj # and handle the source field later - if field.name not in [Placeholder._meta.pk.name, 'source'] + if field.name not in [Placeholder._meta.pk.name, "source"] } if placeholder.source: - placeholder_fields['source'] = new_content + placeholder_fields["source"] = new_content new_placeholder = Placeholder.objects.create(**placeholder_fields) # Copy plugins placeholder.copy_plugins(new_placeholder) @@ -387,20 +403,20 @@ def copy_alias_content(original_content): class AliasPlugin(CMSPlugin): alias = models.ForeignKey( Alias, - verbose_name=_('alias'), - related_name='cms_plugins', + verbose_name=_("alias"), + related_name="cms_plugins", on_delete=models.CASCADE, ) template = models.CharField( - verbose_name=_('template'), + verbose_name=_("template"), choices=get_templates(), default=TEMPLATE_DEFAULT, max_length=255, ) class Meta: - verbose_name = _('alias plugin model') - verbose_name_plural = _('alias plugin models') + verbose_name = _("alias plugin model") + verbose_name_plural = _("alias plugin models") def __str__(self): return force_str(self.alias.name) diff --git a/djangocms_alias/rendering.py b/djangocms_alias/rendering.py index 7b699af1..08430b1b 100644 --- a/djangocms_alias/rendering.py +++ b/djangocms_alias/rendering.py @@ -2,6 +2,6 @@ def render_alias_content(request, alias_content): - template = 'djangocms_alias/alias_content_preview.html' - context = {'alias_content': alias_content} + template = "djangocms_alias/alias_content_preview.html" + context = {"alias_content": alias_content} return TemplateResponse(request, template, context) diff --git a/djangocms_alias/static/djangocms_alias/js/dist/bundle.alias.create.min.js b/djangocms_alias/static/djangocms_alias/js/dist/bundle.alias.create.min.js index 65944e2a..1319911c 100644 --- a/djangocms_alias/static/djangocms_alias/js/dist/bundle.alias.create.min.js +++ b/djangocms_alias/static/djangocms_alias/js/dist/bundle.alias.create.min.js @@ -1 +1 @@ -!function(t){var e={};function n(r){if(e[r])return e[r].exports;var a=e[r]={i:r,l:!1,exports:{}};return t[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)n.d(r,a,function(e){return t[e]}.bind(null,a));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([function(t,e){t.exports=CMS.$},function(t,e,n){"use strict";n.r(e);var r=n(0),a=n.n(r);a()((function(){var t=a()("#id_site"),e=a()("#id_category"),n=a()("#id_alias"),r=e.attr("data-select2-url"),i=n.attr("data-select2-url");e.select2({allowClear:!0,ajax:{url:r,dataType:"json",quietMillis:250,data:function(e,n){return{term:e,page:n,limit:30,site:t.val()}},results:function(t){return t}},initSelection:function(t,e){var n=t.val();a.a.ajax({url:r,dataType:"json",data:{pk:n}}).done((function(t){var r=n;t.results.length&&(r=t.results[0].text),e({id:n,text:r})})).fail((function(){e({id:n,text:n})}))}}),n.select2({ajax:{url:i,dataType:"json",quietMillis:250,data:function(n,r){return{term:n,page:r,limit:30,site:t.val(),category:e.val()}},results:function(t){return t}},initSelection:function(t,e){var n=t.val();a.a.ajax({url:i,dataType:"json",data:{pk:n}}).done((function(t){var r=n;t.results.length&&(r=t.results[0].text),e({id:n,text:r})})).fail((function(){e({id:n,text:n})}))}})}))}]); \ No newline at end of file +!function(t){var e={};function n(r){if(e[r])return e[r].exports;var a=e[r]={i:r,l:!1,exports:{}};return t[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var a in t)n.d(r,a,function(e){return t[e]}.bind(null,a));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=1)}([function(t,e){t.exports=CMS.$},function(t,e,n){"use strict";n.r(e);var r=n(0),a=n.n(r);a()((function(){var t=a()("#id_site"),e=a()("#id_category"),n=a()("#id_alias"),r=e.attr("data-select2-url"),i=n.attr("data-select2-url");e.select2({allowClear:!0,ajax:{url:r,dataType:"json",quietMillis:250,data:function(e,n){return{term:e,page:n,limit:30,site:t.val()}},results:function(t){return t}},initSelection:function(t,e){var n=t.val();a.a.ajax({url:r,dataType:"json",data:{pk:n}}).done((function(t){var r=n;t.results.length&&(r=t.results[0].text),e({id:n,text:r})})).fail((function(){e({id:n,text:n})}))}}),n.select2({ajax:{url:i,dataType:"json",quietMillis:250,data:function(n,r){return{term:n,page:r,limit:30,site:t.val(),category:e.val()}},results:function(t){return t}},initSelection:function(t,e){var n=t.val();a.a.ajax({url:i,dataType:"json",data:{pk:n}}).done((function(t){var r=n;t.results.length&&(r=t.results[0].text),e({id:n,text:r})})).fail((function(){e({id:n,text:n})}))}})}))}]); diff --git a/djangocms_alias/templates/admin/djangocms_alias/aliascontent/change_form.html b/djangocms_alias/templates/admin/djangocms_alias/aliascontent/change_form.html index d014f1c8..ace493d1 100644 --- a/djangocms_alias/templates/admin/djangocms_alias/aliascontent/change_form.html +++ b/djangocms_alias/templates/admin/djangocms_alias/aliascontent/change_form.html @@ -13,4 +13,3 @@ {{ block.super }} {% endblock %} - diff --git a/djangocms_alias/templatetags/djangocms_alias_tags.py b/djangocms_alias/templatetags/djangocms_alias_tags.py index 6fa39f9d..1d1f036d 100644 --- a/djangocms_alias/templatetags/djangocms_alias_tags.py +++ b/djangocms_alias/templatetags/djangocms_alias_tags.py @@ -37,7 +37,7 @@ def verbose_name(obj): @register.simple_tag(takes_context=True) def render_alias(context, instance, editable=False): - request = context['request'] + request = context["request"] toolbar = get_toolbar_from_request(request) renderer = toolbar.get_content_renderer() @@ -51,8 +51,8 @@ def render_alias(context, instance, editable=False): context=context, editable=editable, ) - return content or '' - return '' + return content or "" + return "" class StaticAlias(Tag): @@ -67,25 +67,26 @@ class StaticAlias(Tag): static_code -- the unique identifier of the Alias site -- If site is supplied an Alias instance will be created per site. """ - name = 'static_alias' + + name = "static_alias" options = PlaceholderOptions( - Argument('static_code', resolve=True), - MultiValueArgument('extra_bits', required=False, resolve=False), + Argument("static_code", resolve=True), + MultiValueArgument("extra_bits", required=False, resolve=False), blocks=[ - ('endstatic_alias', 'nodelist'), + ("endstatic_alias", "nodelist"), ], ) def _get_alias(self, request, static_code, extra_bits): alias_filter_kwargs = { - 'static_code': static_code, + "static_code": static_code, } # Site current_site = get_current_site() - if 'site' in extra_bits: - alias_filter_kwargs['site'] = current_site + if "site" in extra_bits: + alias_filter_kwargs["site"] = current_site else: - alias_filter_kwargs['site_id__isnull'] = True + alias_filter_kwargs["site_id__isnull"] = True if hasattr(request, "toolbar"): # Try getting language from the toolbar first (end and view endpoints) @@ -104,27 +105,34 @@ def _get_alias(self, request, static_code, extra_bits): alias = Alias.objects.filter(**alias_filter_kwargs).first() # If there is no alias found we need to create one if not alias: - # If versioning is enabled we can only create the records with a logged-in user / staff member if is_versioning_enabled() and not request.user.is_authenticated: return None # Parler's get_or_create doesn't work well with translations, so we must perform our own get or create - default_category = Category.objects.filter(translations__name=DEFAULT_STATIC_ALIAS_CATEGORY_NAME).first() + default_category = Category.objects.filter( + translations__name=DEFAULT_STATIC_ALIAS_CATEGORY_NAME + ).first() if not default_category: - default_category = Category.objects.create(name=DEFAULT_STATIC_ALIAS_CATEGORY_NAME) + default_category = Category.objects.create( + name=DEFAULT_STATIC_ALIAS_CATEGORY_NAME + ) alias_creation_kwargs = { - 'static_code': static_code, - 'creation_method': Alias.CREATION_BY_TEMPLATE + "static_code": static_code, + "creation_method": Alias.CREATION_BY_TEMPLATE, } # Site - if 'site' in extra_bits: - alias_creation_kwargs['site'] = current_site + if "site" in extra_bits: + alias_creation_kwargs["site"] = current_site - alias = Alias.objects.create(category=default_category, **alias_creation_kwargs) + alias = Alias.objects.create( + category=default_category, **alias_creation_kwargs + ) - if not AliasContent._base_manager.filter(alias=alias, language=language).exists(): + if not AliasContent._base_manager.filter( + alias=alias, language=language + ).exists(): # Create a first content object if none exists in the given language. # If versioning is enabled we can only create the records with a logged-in user / staff member if is_versioning_enabled() and not request.user.is_authenticated: @@ -146,13 +154,13 @@ def _get_alias(self, request, static_code, extra_bits): return alias def render_tag(self, context, static_code, extra_bits, nodelist=None): - request = context.get('request') + request = context.get("request") if not static_code or not request: # an empty string was passed in or the variable is not available in the context if nodelist: return nodelist.render(context) - return '' + return "" validate_placeholder_name(static_code) @@ -161,7 +169,7 @@ def render_tag(self, context, static_code, extra_bits, nodelist=None): alias = self._get_alias(request, static_code, extra_bits) if not alias: - return '' + return "" # Get draft contents in edit or preview mode? get_draft_content = False @@ -169,7 +177,9 @@ def render_tag(self, context, static_code, extra_bits, nodelist=None): get_draft_content = True language = get_language_from_request(request) - placeholder = alias.get_placeholder(language=language, show_draft_content=get_draft_content) + placeholder = alias.get_placeholder( + language=language, show_draft_content=get_draft_content + ) if placeholder: content = renderer.render_placeholder( @@ -179,7 +189,7 @@ def render_tag(self, context, static_code, extra_bits, nodelist=None): use_cache=True, ) return content - return '' + return "" register.tag(StaticAlias.name, StaticAlias) diff --git a/djangocms_alias/test_utils/text/cms_plugins.py b/djangocms_alias/test_utils/text/cms_plugins.py index bef37044..ba4003a6 100644 --- a/djangocms_alias/test_utils/text/cms_plugins.py +++ b/djangocms_alias/test_utils/text/cms_plugins.py @@ -7,6 +7,6 @@ @plugin_pool.register_plugin class TextPlugin(CMSPluginBase): model = Text - name = 'Text' + name = "Text" allow_children = True - render_template = 'text/text.html' + render_template = "text/text.html" diff --git a/djangocms_alias/test_utils/text/templates/text/text.html b/djangocms_alias/test_utils/text/templates/text/text.html index 041f8ea6..a7e9c555 100644 --- a/djangocms_alias/test_utils/text/templates/text/text.html +++ b/djangocms_alias/test_utils/text/templates/text/text.html @@ -1 +1 @@ -{{ instance.body|safe }} \ No newline at end of file +{{ instance.body|safe }} diff --git a/djangocms_alias/urls.py b/djangocms_alias/urls.py index 161a1d98..28c5d6d5 100644 --- a/djangocms_alias/urls.py +++ b/djangocms_alias/urls.py @@ -6,35 +6,33 @@ urlpatterns = [ path( - 'create-alias/', + "create-alias/", views.create_alias_view, name=constants.CREATE_ALIAS_URL_NAME, ), path( - 'aliases//usage/', + "aliases//usage/", views.alias_usage_view, name=constants.USAGE_ALIAS_URL_NAME, ), path( - 'detach-alias//', + "detach-alias//", views.detach_alias_plugin_view, name=constants.DETACH_ALIAS_PLUGIN_URL_NAME, ), path( - 'delete-alias//', + "delete-alias//", views.delete_alias_view, name=constants.DELETE_ALIAS_URL_NAME, ), path( - 'select2/', + "select2/", views.AliasSelect2View.as_view(), name=constants.SELECT2_ALIAS_URL_NAME, ), path( - 'category-select2/', + "category-select2/", views.CategorySelect2View.as_view(), name=constants.CATEGORY_SELECT2_URL_NAME, ), - - ] diff --git a/djangocms_alias/utils.py b/djangocms_alias/utils.py index 2458a6b7..4bfbfccc 100644 --- a/djangocms_alias/utils.py +++ b/djangocms_alias/utils.py @@ -3,8 +3,9 @@ def is_versioning_enabled(): from .models import AliasContent + try: - app_config = apps.get_app_config('djangocms_versioning') + app_config = apps.get_app_config("djangocms_versioning") return app_config.cms_extension.is_content_model_versioned(AliasContent) except LookupError: return False diff --git a/djangocms_alias/views.py b/djangocms_alias/views.py index b1788de4..0928ade2 100644 --- a/djangocms_alias/views.py +++ b/djangocms_alias/views.py @@ -35,18 +35,18 @@ def detach_alias_plugin_view(request, plugin_pk): instance = get_object_or_404(AliasPlugin, pk=plugin_pk) - if request.method == 'GET': + if request.method == "GET": opts = Alias.model._meta context = { - 'has_change_permission': True, - 'opts': opts, - 'root_path': reverse('admin:index'), - 'is_popup': True, - 'app_label': opts.app_label, - 'object_name': _('Alias'), - 'object': instance.alias, + "has_change_permission": True, + "opts": opts, + "root_path": reverse("admin:index"), + "is_popup": True, + "app_label": opts.app_label, + "object_name": _("Alias"), + "object": instance.alias, } - return render(request, 'djangocms_alias/detach_alias.html', context) + return render(request, "djangocms_alias/detach_alias.html", context) language = get_language_from_request(request, check_path=True) @@ -93,8 +93,8 @@ def create_alias_view(request): else: initial_data = None - if request.method == 'GET' and not form.is_valid(): - return HttpResponseBadRequest('Form received unexpected values') + if request.method == "GET" and not form.is_valid(): + return HttpResponseBadRequest("Form received unexpected values") user = request.user @@ -107,24 +107,24 @@ def create_alias_view(request): if not create_form.is_valid(): opts = Alias.model._meta context = { - 'form': create_form, - 'has_change_permission': True, - 'opts': opts, - 'root_path': reverse('admin:index'), - 'is_popup': True, - 'app_label': opts.app_label, - 'media': (Alias().media + create_form.media), + "form": create_form, + "has_change_permission": True, + "opts": opts, + "root_path": reverse("admin:index"), + "is_popup": True, + "app_label": opts.app_label, + "media": (Alias().media + create_form.media), } - return render(request, 'djangocms_alias/create_alias.html', context) + return render(request, "djangocms_alias/create_alias.html", context) plugins = create_form.get_plugins() if not plugins: return HttpResponseBadRequest( - 'Plugins are required to create an alias', + "Plugins are required to create an alias", ) - replace = create_form.cleaned_data.get('replace') + replace = create_form.cleaned_data.get("replace") if not Alias.can_create_alias(user, plugins, replace): raise PermissionDenied @@ -132,8 +132,8 @@ def create_alias_view(request): emit_content_change([alias_content]) if replace: - plugin = create_form.cleaned_data.get('plugin') - placeholder = create_form.cleaned_data.get('placeholder') + plugin = create_form.cleaned_data.get("plugin") + placeholder = create_form.cleaned_data.get("placeholder") return render_replace_response( request, new_plugins=[alias_plugin], @@ -144,8 +144,9 @@ def create_alias_view(request): return HttpResponse(JAVASCRIPT_SUCCESS_RESPONSE) -def render_replace_response(request, new_plugins, source_placeholder=None, - source_plugin=None): +def render_replace_response( + request, new_plugins, source_placeholder=None, source_plugin=None +): move_plugins, add_plugins = [], [] for plugin in new_plugins: root = plugin.parent.get_bound_plugin() if plugin.parent else plugin @@ -158,46 +159,52 @@ def render_replace_response(request, new_plugins, source_placeholder=None, ) plugin_tree = get_plugin_tree_as_json(request, plugins) move_data = get_plugin_toolbar_info(plugin) - move_data['plugin_order'] = plugin_order + move_data["plugin_order"] = plugin_order move_data.update(json.loads(plugin_tree)) move_plugins.append(json.dumps(move_data)) - add_plugins.append(( - json.dumps(get_plugin_toolbar_info(plugin)), - plugin_tree, - )) + add_plugins.append( + ( + json.dumps(get_plugin_toolbar_info(plugin)), + plugin_tree, + ) + ) context = { - 'added_plugins': add_plugins, - 'moved_plugins': move_plugins, - 'is_popup': True, + "added_plugins": add_plugins, + "moved_plugins": move_plugins, + "is_popup": True, } if source_plugin is not None: - context['replaced_plugin'] = json.dumps( + context["replaced_plugin"] = json.dumps( get_plugin_toolbar_info(source_plugin), ) if source_placeholder is not None: - context['replaced_placeholder'] = json.dumps({ - 'placeholder_id': source_placeholder.pk, - 'deleted': True, - }) - return render(request, 'djangocms_alias/alias_replace.html', context) + context["replaced_placeholder"] = json.dumps( + { + "placeholder_id": source_placeholder.pk, + "deleted": True, + } + ) + return render(request, "djangocms_alias/alias_replace.html", context) class CategorySelect2View(ListView): - queryset = Category.objects.order_by('translations__name') + queryset = Category.objects.order_by("translations__name") def get(self, request, *args, **kwargs): self.object_list = self.get_queryset() context = self.get_context_data() - return JsonResponse({ - 'results': [ - { - 'text': str(obj), - 'id': obj.pk, - } - for obj in context['object_list'] - ], - 'more': context['page_obj'].has_next(), - }) + return JsonResponse( + { + "results": [ + { + "text": str(obj), + "id": obj.pk, + } + for obj in context["object_list"] + ], + "more": context["page_obj"].has_next(), + } + ) def dispatch(self, request, *args, **kwargs): if not request.user.is_staff: @@ -209,16 +216,14 @@ def get_queryset(self): Only show Categories that have an Alias attached. If site is selected, use that to filter further. """ - term = self.request.GET.get('term') - site = self.request.GET.get('site') + term = self.request.GET.get("term") + site = self.request.GET.get("site") queryset = super().get_queryset() # Only get categories that have aliases attached - queryset = queryset.filter( - aliases__isnull=False - ) + queryset = queryset.filter(aliases__isnull=False) try: - pk = int(self.request.GET.get('pk')) + pk = int(self.request.GET.get("pk")) except (TypeError, ValueError): pk = None @@ -233,25 +238,27 @@ def get_queryset(self): return queryset.translated(get_language()).filter(q).distinct() def get_paginate_by(self, queryset): - return self.request.GET.get('limit', 30) + return self.request.GET.get("limit", 30) class AliasSelect2View(ListView): - queryset = AliasModel.objects.order_by('category__translations__name', 'position') + queryset = AliasModel.objects.order_by("category__translations__name", "position") def get(self, request, *args, **kwargs): self.object_list = self.get_queryset() context = self.get_context_data() - return JsonResponse({ - 'results': [ - { - 'text': str(obj), - 'id': obj.pk, - } - for obj in context['object_list'] - ], - 'more': context['page_obj'].has_next(), - }) + return JsonResponse( + { + "results": [ + { + "text": str(obj), + "id": obj.pk, + } + for obj in context["object_list"] + ], + "more": context["page_obj"].has_next(), + } + ) def dispatch(self, request, *args, **kwargs): if not request.user.is_staff: @@ -259,16 +266,21 @@ def dispatch(self, request, *args, **kwargs): return super().dispatch(request, *args, **kwargs) def get_queryset(self): - term = self.request.GET.get('term') - category = self.request.GET.get('category') - site = self.request.GET.get('site') + term = self.request.GET.get("term") + category = self.request.GET.get("category") + site = self.request.GET.get("site") # Showing published and unpublished aliases - queryset = super().get_queryset().filter( - contents__language=get_language(), - ).distinct() + queryset = ( + super() + .get_queryset() + .filter( + contents__language=get_language(), + ) + .distinct() + ) try: - pk = int(self.request.GET.get('pk')) + pk = int(self.request.GET.get("pk")) except (TypeError, ValueError): pk = None @@ -285,7 +297,7 @@ def get_queryset(self): return queryset.filter(q).distinct() def get_paginate_by(self, queryset): - return self.request.GET.get('limit', 30) + return self.request.GET.get("limit", 30) def alias_usage_view(request, pk): @@ -294,23 +306,23 @@ def alias_usage_view(request, pk): alias = get_object_or_404(AliasModel.objects.all(), pk=pk) opts = Alias.model._meta - title = _(f'Objects using alias: {alias}') + title = _(f"Objects using alias: {alias}") context = { - 'has_change_permission': True, - 'opts': opts, - 'root_path': reverse('admin:index'), - 'is_popup': True, - 'app_label': opts.app_label, - 'object_name': _('Alias'), - 'object': alias, - 'title': title, - 'original': title, - 'show_back_btn': request.GET.get('back'), - 'objects_list': sorted( + "has_change_permission": True, + "opts": opts, + "root_path": reverse("admin:index"), + "is_popup": True, + "app_label": opts.app_label, + "object_name": _("Alias"), + "object": alias, + "title": title, + "original": title, + "show_back_btn": request.GET.get("back"), + "objects_list": sorted( alias.objects_using, # First show Pages on list key=lambda obj: isinstance(obj, Page), reverse=True, ), } - return render(request, 'djangocms_alias/alias_usage.html', context) + return render(request, "djangocms_alias/alias_usage.html", context) diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..a10167bc --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,23 @@ +[tool.ruff.lint] +select=[ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "C", # flake8-comprehensions + "B", # flake8-bugbear + "PLE", # pylint error + "PLR", # pylint refactor + "PLW", # pylint warning + "UP", # pyupgrade +] + +extend-ignore = [ + "PLR0915", + "C901", + "PLR0913", + "PLW1510", + "I001" , + "PLR0912" , + "E501" +] diff --git a/setup.cfg b/setup.cfg index bd7136a5..1e6dfe1d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,36 +1,3 @@ -[flake8] -ignore = E251,E128,E501,W503 -max-line-length = 119 -exclude = - *.egg-info, - .eggs, - .git, - .settings, - .tox, - .venv, - build, - data, - dist, - docs, - *migrations*, - requirements, - tmp, - *node_modules*, - venv - -[isort] -line_length = 79 -skip = manage.py, migrations, .tox, .eggs, data, .venv, venv -include_trailing_comma = true -multi_line_output = 3 -lines_after_imports = 2 -combine_as_imports = true -sections = FUTURE, STDLIB, DJANGO, CMS, THIRDPARTY, FIRSTPARTY, LOCALFOLDER -known_first_party = djangocms_alias -known_cms = cms, menus -known_django = django -extra_standard_library = mock - [coverage:run] branch = True parallel = True diff --git a/setup.py b/setup.py index 71f33f77..a545cae7 100644 --- a/setup.py +++ b/setup.py @@ -4,50 +4,50 @@ CLASSIFIERS = [ - 'Environment :: Web Environment', - 'Framework :: Django', - 'Intended Audience :: Developers', - 'License :: OSI Approved :: BSD License', - 'Operating System :: OS Independent', - 'Programming Language :: Python', - 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', - 'Topic :: Software Development', - 'Topic :: Software Development :: Libraries :: Application Frameworks', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Framework :: Django', - 'Framework :: Django :: 3.2', - 'Framework :: Django :: 4.0', - 'Framework :: Django :: 4.1', - 'Framework :: Django :: 4.2', - 'Framework :: Django :: 5.0', - 'Framework :: Django CMS :: 4.1', + "Environment :: Web Environment", + "Framework :: Django", + "Intended Audience :: Developers", + "License :: OSI Approved :: BSD License", + "Operating System :: OS Independent", + "Programming Language :: Python", + "Topic :: Internet :: WWW/HTTP :: Dynamic Content", + "Topic :: Software Development", + "Topic :: Software Development :: Libraries :: Application Frameworks", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Framework :: Django", + "Framework :: Django :: 3.2", + "Framework :: Django :: 4.0", + "Framework :: Django :: 4.1", + "Framework :: Django :: 4.2", + "Framework :: Django :: 5.0", + "Framework :: Django CMS :: 4.1", ] INSTALL_REQUIREMENTS = [ - 'Django>=3.2', - 'django-parler>=1.4', - 'django-cms>=4.0rc3', + "Django>=3.2", + "django-parler>=1.4", + "django-cms>=4.0rc3", ] setup( - name='djangocms-alias', - author='Divio AG', - author_email='info@divio.ch', - maintainer='Django CMS Association and contributors', - maintainer_email='info@django-cms.org', - url='https://github.com/django-cms/djangocms-alias', - license='BSD', + name="djangocms-alias", + author="Divio AG", + author_email="info@divio.ch", + maintainer="Django CMS Association and contributors", + maintainer_email="info@django-cms.org", + url="https://github.com/django-cms/djangocms-alias", + license="BSD", version=djangocms_alias.__version__, description=djangocms_alias.__doc__, - long_description=open('README.rst').read(), - long_description_content_type='text/x-rst', - platforms=['OS Independent'], + long_description=open("README.rst").read(), + long_description_content_type="text/x-rst", + platforms=["OS Independent"], classifiers=CLASSIFIERS, install_requires=INSTALL_REQUIREMENTS, packages=find_packages(), include_package_data=True, - test_suite='test_settings.run', + test_suite="test_settings.run", ) diff --git a/test_settings.py b/test_settings.py index c4b486b9..a3facd1f 100644 --- a/test_settings.py +++ b/test_settings.py @@ -3,106 +3,103 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) -ENABLE_VERSIONING = strtobool(os.environ.get('ENABLE_VERSIONING', "1")) +ENABLE_VERSIONING = strtobool(os.environ.get("ENABLE_VERSIONING", "1")) EXTRA_INSTALLED_APPS = [] if ENABLE_VERSIONING: - EXTRA_INSTALLED_APPS.append('djangocms_versioning') + EXTRA_INSTALLED_APPS.append("djangocms_versioning") HELPER_SETTINGS = { - 'SECRET_KEY': 'test1234', - 'TIME_ZONE': 'Europe/Zurich', - 'TOP_INSTALLED_APPS': [ - 'djangocms_alias', + "SECRET_KEY": "test1234", + "TIME_ZONE": "Europe/Zurich", + "TOP_INSTALLED_APPS": [ + "djangocms_alias", ], - 'INSTALLED_APPS': [ - 'parler', - 'djangocms_alias.test_utils.text', - ] + EXTRA_INSTALLED_APPS, - 'VERSIONING_ALIAS_MODELS_ENABLED': ENABLE_VERSIONING, - 'MIGRATION_MODULES': { - 'sites': None, - 'contenttypes': None, - 'auth': None, - 'cms': None, - 'menus': None, - 'text': None, - 'djangocms_alias': None, - 'djangocms_versioning': None, + "INSTALLED_APPS": [ + "parler", + "djangocms_alias.test_utils.text", + ] + + EXTRA_INSTALLED_APPS, + "VERSIONING_ALIAS_MODELS_ENABLED": ENABLE_VERSIONING, + "MIGRATION_MODULES": { + "sites": None, + "contenttypes": None, + "auth": None, + "cms": None, + "menus": None, + "text": None, + "djangocms_alias": None, + "djangocms_versioning": None, }, - 'CMS_PERMISSION': True, + "CMS_PERMISSION": True, # At present, testing requires bootstrap to be disabled. # 'ALDRYN_BOILERPLATE_NAME': 'bootstrap3', - 'LANGUAGES': ( - ('en', 'English'), - ('de', 'German'), - ('fr', 'French'), - ('it', 'Italiano'), + "LANGUAGES": ( + ("en", "English"), + ("de", "German"), + ("fr", "French"), + ("it", "Italiano"), ), - 'CMS_LANGUAGES': { + "CMS_LANGUAGES": { 1: [ + {"code": "en", "name": "English", "fallbacks": ["de", "fr"]}, { - 'code': 'en', - 'name': 'English', - 'fallbacks': ['de', 'fr'] + "code": "de", + "name": "Deutsche", + "fallbacks": ["en"], # FOR TESTING DO NOT ADD 'fr' HERE }, { - 'code': 'de', - 'name': 'Deutsche', - 'fallbacks': ['en'] # FOR TESTING DO NOT ADD 'fr' HERE + "code": "fr", + "name": "Française", + "fallbacks": ["en"], # FOR TESTING DO NOT ADD 'de' HERE }, { - 'code': 'fr', - 'name': 'Française', - 'fallbacks': ['en'] # FOR TESTING DO NOT ADD 'de' HERE - }, - { - 'code': 'it', - 'name': 'Italiano', - 'fallbacks': ['fr'] # FOR TESTING, LEAVE AS ONLY 'fr' + "code": "it", + "name": "Italiano", + "fallbacks": ["fr"], # FOR TESTING, LEAVE AS ONLY 'fr' }, ], }, - 'TEMPLATE_DIRS': [ - os.path.join('tests', 'templates'), + "TEMPLATE_DIRS": [ + os.path.join("tests", "templates"), ], - 'CMS_TEMPLATES': ( + "CMS_TEMPLATES": ( ("fullwidth.html", "Fullwidth"), ("page.html", "Normal page"), - ('static_alias.html', 'Static Alias Template'), + ("static_alias.html", "Static Alias Template"), ), - 'PARLER_LANGUAGES': { + "PARLER_LANGUAGES": { 1: [ { - 'code': 'en', - 'fallbacks': ['de', 'fr'], - 'hide_untranslated': False, + "code": "en", + "fallbacks": ["de", "fr"], + "hide_untranslated": False, }, { - 'code': 'de', - 'fallbacks': ['en'], - 'hide_untranslated': False, + "code": "de", + "fallbacks": ["en"], + "hide_untranslated": False, }, { - 'code': 'fr', - 'fallbacks': ['en'], - 'hide_untranslated': False, + "code": "fr", + "fallbacks": ["en"], + "hide_untranslated": False, }, { - 'code': 'it', - 'fallbacks': ['fr'], # FOR TESTING, LEAVE AS ONLY 'fr' - 'hide_untranslated': False, + "code": "it", + "fallbacks": ["fr"], # FOR TESTING, LEAVE AS ONLY 'fr' + "hide_untranslated": False, }, ], - 'default': { - 'code': 'en', - 'fallbacks': ['en'], - 'hide_untranslated': False, - } + "default": { + "code": "en", + "fallbacks": ["en"], + "hide_untranslated": False, + }, }, - 'PARLER_ENABLE_CACHING': False, - 'LANGUAGE_CODE': 'en', - 'DJANGOCMS_ALIAS_TEMPLATES': [ - ('custom_alias_template', 'Custom Template Name'), + "PARLER_ENABLE_CACHING": False, + "LANGUAGE_CODE": "en", + "DJANGOCMS_ALIAS_TEMPLATES": [ + ("custom_alias_template", "Custom Template Name"), ], "DEFAULT_AUTO_FIELD": "django.db.models.AutoField", # Due to a recent temporary change in develop-4, we now need to confirm that we intend to use v4 @@ -112,7 +109,8 @@ def run(): from app_helper import runner - runner.cms('djangocms_alias', extra_args=[]) + + runner.cms("djangocms_alias", extra_args=[]) if __name__ == "__main__": diff --git a/tests/base.py b/tests/base.py index 498976bf..3bfe1aa3 100644 --- a/tests/base.py +++ b/tests/base.py @@ -26,7 +26,6 @@ class BaseAliasPluginTestCase(CMSTestCase): - def get_create_alias_endpoint(self): return admin_reverse(CREATE_ALIAS_URL_NAME) @@ -50,25 +49,36 @@ def get_list_alias_endpoint(self): def setUp(self): self.superuser = self.get_superuser() - self.language = 'en' - self.page = self._create_page('test') + self.language = "en" + self.page = self._create_page("test") self.placeholder = self.page.get_placeholders(self.language).get( - slot='content', + slot="content", ) self.plugin = add_plugin( self.placeholder, - 'TextPlugin', + "TextPlugin", language=self.language, - body='test', + body="test", ) - self.category = Category.objects.create(name='test category') + self.category = Category.objects.create(name="test category") def _get_draft_page_placeholder(self): - page_content = create_page_content(self.language, 'Draft Page', self.page, created_by=self.superuser) - return page_content.get_placeholders().get(slot='content') + page_content = create_page_content( + self.language, "Draft Page", self.page, created_by=self.superuser + ) + return page_content.get_placeholders().get(slot="content") - def _create_alias(self, plugins=None, name='test alias', category=None, position=0, - language=None, published=True, static_code=None, site=None): + def _create_alias( + self, + plugins=None, + name="test alias", + category=None, + position=0, + language=None, + published=True, + static_code=None, + site=None, + ): if language is None: language = self.language if category is None: @@ -89,7 +99,10 @@ def _create_alias(self, plugins=None, name='test alias', category=None, position if is_versioning_enabled(): from djangocms_versioning.models import Version - version = Version.objects.create(content=alias_content, created_by=self.superuser) + + version = Version.objects.create( + content=alias_content, created_by=self.superuser + ) if published: version.publish(self.superuser) @@ -101,18 +114,26 @@ def _get_version(self, grouper, version_state, language=None): language = language or self.language from djangocms_versioning.models import Version - versions = Version.objects.filter_by_grouper(grouper).filter(state=version_state) + + versions = Version.objects.filter_by_grouper(grouper).filter( + state=version_state + ) for version in versions: - if hasattr(version.content, 'language') and version.content.language == language: + if ( + hasattr(version.content, "language") + and version.content.language == language + ): return version def _publish(self, grouper, language=None): from djangocms_versioning.constants import DRAFT + version = self._get_version(grouper, DRAFT, language) version.publish(self.superuser) def _unpublish(self, grouper, language=None): from djangocms_versioning.constants import PUBLISHED + version = self._get_version(grouper, PUBLISHED, language) version.unpublish(self.superuser) @@ -120,27 +141,29 @@ def _create_page(self, title, language=None, site=None, published=True, **kwargs if language is None: language = self.language - if is_versioning_enabled() and not kwargs.get('created_by'): - kwargs['created_by'] = self.superuser + if is_versioning_enabled() and not kwargs.get("created_by"): + kwargs["created_by"] = self.superuser page = create_page( title=title, language=language, - template='page.html', - menu_title='', + template="page.html", + menu_title="", in_navigation=True, limit_visibility_in_menu=None, site=site, - **kwargs + **kwargs, ) if is_versioning_enabled() and published: self._publish(page, language) return page - def get_alias_request(self, alias, lang_code='en', *args, **kwargs): + def get_alias_request(self, alias, lang_code="en", *args, **kwargs): request = self._get_instance_request(alias, *args, **kwargs) request.current_page = None - request = self._process_request_by_toolbar_middleware(request, obj=alias.get_content(lang_code)) + request = self._process_request_by_toolbar_middleware( + request, obj=alias.get_content(lang_code) + ) return request def get_page_request(self, page, obj=None, *args, **kwargs): @@ -149,9 +172,17 @@ def get_page_request(self, page, obj=None, *args, **kwargs): request = self._process_request_by_toolbar_middleware(request, obj) return request - def _get_instance_request(self, instance, user, path=None, edit=False, - preview=False, structure=False, lang_code='en', - disable=False): + def _get_instance_request( + self, + instance, + user, + path=None, + edit=False, + preview=False, + structure=False, + lang_code="en", + disable=False, + ): if not path: if edit: path = get_object_edit_url(instance) @@ -166,20 +197,20 @@ def _get_instance_request(self, instance, user, path=None, edit=False, request.session = {} request.user = user request.LANGUAGE_CODE = lang_code - request.GET = QueryDict('', mutable=True) + request.GET = QueryDict("", mutable=True) if edit: - request.GET['edit'] = None + request.GET["edit"] = None else: - request.GET['edit_off'] = None + request.GET["edit_off"] = None if disable: - request.GET[get_cms_setting('CMS_TOOLBAR_URL__DISABLE')] = None + request.GET[get_cms_setting("CMS_TOOLBAR_URL__DISABLE")] = None return request def _process_request_by_toolbar_middleware(self, request, obj=None): middleware = ToolbarMiddleware(request) middleware.process_request(request) - if hasattr(request, 'toolbar'): + if hasattr(request, "toolbar"): if obj: request.toolbar.set_object(obj) request.toolbar.populate() @@ -188,31 +219,43 @@ def _process_request_by_toolbar_middleware(self, request, obj=None): def _add_default_permissions(self, user): # Text plugin permissions - user.user_permissions.add(Permission.objects.get(codename='add_text')) - user.user_permissions.add(Permission.objects.get(codename='delete_text')) - user.user_permissions.add(Permission.objects.get(codename='change_text')) - user.user_permissions.add(Permission.objects.get(codename='add_page')) - user.user_permissions.add(Permission.objects.get(codename='change_page')) - user.user_permissions.add(Permission.objects.get(codename='delete_page')) + user.user_permissions.add(Permission.objects.get(codename="add_text")) + user.user_permissions.add(Permission.objects.get(codename="delete_text")) + user.user_permissions.add(Permission.objects.get(codename="change_text")) + user.user_permissions.add(Permission.objects.get(codename="add_page")) + user.user_permissions.add(Permission.objects.get(codename="change_page")) + user.user_permissions.add(Permission.objects.get(codename="delete_page")) def add_alias_plugin_to_page(self, page, alias, language=None): if language is None: language = self.language add_plugin( - page.get_placeholders(language).get(slot='content'), - 'Alias', + page.get_placeholders(language).get(slot="content"), + "Alias", language=language, alias=alias, ) def get_staff_user_with_alias_permissions(self): staff_user = self._create_user("alias staff", is_staff=True, is_superuser=False) # noqa: E501 - self.add_permission(staff_user, get_permission_codename('add', AliasModel._meta)) # noqa: E501 - self.add_permission(staff_user, get_permission_codename('change', AliasModel._meta)) # noqa: E501 - self.add_permission(staff_user, get_permission_codename('delete', AliasModel._meta)) # noqa: E501 - self.add_permission(staff_user, get_permission_codename('add', AliasContent._meta)) # noqa: E501 - self.add_permission(staff_user, get_permission_codename('change', AliasContent._meta)) # noqa: E501 - self.add_permission(staff_user, get_permission_codename('delete', AliasContent._meta)) # noqa: E501 - self.add_permission(staff_user, get_permission_codename('add', Category._meta)) # noqa: E501 + self.add_permission( + staff_user, get_permission_codename("add", AliasModel._meta) + ) # noqa: E501 + self.add_permission( + staff_user, get_permission_codename("change", AliasModel._meta) + ) # noqa: E501 + self.add_permission( + staff_user, get_permission_codename("delete", AliasModel._meta) + ) # noqa: E501 + self.add_permission( + staff_user, get_permission_codename("add", AliasContent._meta) + ) # noqa: E501 + self.add_permission( + staff_user, get_permission_codename("change", AliasContent._meta) + ) # noqa: E501 + self.add_permission( + staff_user, get_permission_codename("delete", AliasContent._meta) + ) # noqa: E501 + self.add_permission(staff_user, get_permission_codename("add", Category._meta)) # noqa: E501 return staff_user diff --git a/tests/requirements/compile.py b/tests/requirements/compile.py index d19e98c1..e334076c 100755 --- a/tests/requirements/compile.py +++ b/tests/requirements/compile.py @@ -38,7 +38,7 @@ cms_dict = { "cms40": "https://github.com/django-cms/django-cms/tarball/release/4.0.1.x#egg=django-cms", "cms41": "django-cms>=4.1.0rc2,<4.2", - "cms4dev": "https://github.com/django-cms/django-cms/tarball/release/4.1.x#egg=django-cms" + "cms4dev": "https://github.com/django-cms/django-cms/tarball/release/4.1.x#egg=django-cms", } @@ -55,7 +55,7 @@ def get_args(key, value, common_args): cms_dict[cms_ver], *value, "-o", - key + key, ] @@ -81,7 +81,14 @@ def run(*args, **kwargs): print("Upgrading pip-tools") for py_ver in {key.split("-")[0] for key in COMPILE_SETTINGS.keys()}: - args = [f"python{py_ver[2]}.{py_ver[3:]}", "-m", "pip", "install", "--upgrade", "pip-tools"] + args = [ + f"python{py_ver[2]}.{py_ver[3:]}", + "-m", + "pip", + "install", + "--upgrade", + "pip-tools", + ] subprocess.run(args, capture_output=True) print("Creating requirement files") diff --git a/tests/templates/static_alias.html b/tests/templates/static_alias.html index c2f5140e..207c35c6 100644 --- a/tests/templates/static_alias.html +++ b/tests/templates/static_alias.html @@ -9,5 +9,3 @@

Static Alias tags

{% static_alias "template_example_global_alias_code" %} {% endblock content %} - - diff --git a/tests/test_admin.py b/tests/test_admin.py index 6b73d984..b2708289 100644 --- a/tests/test_admin.py +++ b/tests/test_admin.py @@ -26,13 +26,12 @@ class AliasContentManagerTestCase(BaseAliasPluginTestCase): - - @skipUnless(not is_versioning_enabled(), 'Test only relevant when no versioning') + @skipUnless(not is_versioning_enabled(), "Test only relevant when no versioning") def test_alias_content_manager_rendering_without_versioning_actions(self): """ When rendering aliascontent manager without versioning """ - category = Category.objects.create(name='Language Filter Category') + category = Category.objects.create(name="Language Filter Category") alias = AliasModel.objects.create( category=category, position=0, @@ -52,15 +51,12 @@ def test_alias_content_manager_rendering_without_versioning_actions(self): # Check Column Headings self.assertInHTML( - 'Category', + "Category", response_content_decoded, ) # Check Alias content row values - self.assertIn( - category.name, - response_content_decoded - ) + self.assertIn(category.name, response_content_decoded) self.assertIn( expected_en_content.name, response_content_decoded, @@ -70,12 +66,15 @@ def test_alias_content_manager_rendering_without_versioning_actions(self): response_content_decoded, ) - usage_url = admin_reverse(USAGE_ALIAS_URL_NAME, args=[expected_en_content.alias.pk]) + usage_url = admin_reverse( + USAGE_ALIAS_URL_NAME, args=[expected_en_content.alias.pk] + ) change_category_and_site_url = admin_reverse( - '{}_{}_change'.format( + "{}_{}_change".format( expected_en_content._meta.app_label, - expected_en_content.alias._meta.model_name - ), args=(expected_en_content.alias.pk,) + expected_en_content.alias._meta.model_name, + ), + args=(expected_en_content.alias.pk,), ) self.assertNotIn( @@ -88,9 +87,9 @@ def test_alias_content_manager_rendering_without_versioning_actions(self): ) # check for add content admin link add_alias_link = admin_reverse( - '{}_{}_add'.format( + "{}_{}_add".format( expected_en_content._meta.app_label, - expected_en_content._meta.model_name + expected_en_content._meta.model_name, ) ) self.assertNotIn( @@ -101,15 +100,15 @@ def test_alias_content_manager_rendering_without_versioning_actions(self): ) self.assertNotIn( '', # noqa: E501 - response_content_decoded + response_content_decoded, ) - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_alias_changelist_rendering_with_versioning_actions(self): """ When rendering aliascontent manager with versioning actions """ - category = Category.objects.create(name='Language Filter Category') + category = Category.objects.create(name="Language Filter Category") alias = AliasModel.objects.create( category=category, position=0, @@ -125,7 +124,6 @@ def test_alias_changelist_rendering_with_versioning_actions(self): Version.objects.create(content=expected_en_content, created_by=self.superuser) with self.login_user_context(self.superuser): - base_url = self.get_admin_url(Alias, "changelist") # en is the default language configured for the site response = self.client.get(base_url) @@ -134,31 +132,28 @@ def test_alias_changelist_rendering_with_versioning_actions(self): # Check Column Headings self.assertInHTML( - 'Category', + "Category", response_content_decoded, ) self.assertInHTML( - 'Author', + "Author", response_content_decoded, ) self.assertInHTML( - 'Modified', + "Modified", response_content_decoded, ) self.assertInHTML( - 'State', + "State", response_content_decoded, ) self.assertInHTML( - 'Actions', + "Actions", response_content_decoded, ) # Check Alias content row values - self.assertIn( - category.name, - response_content_decoded - ) + self.assertIn(category.name, response_content_decoded) self.assertIn( expected_en_content.name, response_content_decoded, @@ -179,12 +174,15 @@ def test_alias_changelist_rendering_with_versioning_actions(self): response_content_decoded, ) - usage_url = admin_reverse(USAGE_ALIAS_URL_NAME, args=[expected_en_content.alias.pk]) + usage_url = admin_reverse( + USAGE_ALIAS_URL_NAME, args=[expected_en_content.alias.pk] + ) settings_url = admin_reverse( - '{}_{}_change'.format( + "{}_{}_change".format( expected_en_content._meta.app_label, - expected_en_content.alias._meta.model_name - ), args=(expected_en_content.alias.pk,) + expected_en_content.alias._meta.model_name, + ), + args=(expected_en_content.alias.pk,), ) self.assertIn( @@ -196,12 +194,12 @@ def test_alias_changelist_rendering_with_versioning_actions(self): response_content_decoded, ) - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_alias_content_manager_rendering_preview_add_url(self): """ When rendering aliascontent manager with versioning actions and preview """ - category = Category.objects.create(name='Language Filter Category') + category = Category.objects.create(name="Language Filter Category") alias = AliasModel.objects.create( category=category, position=0, @@ -228,13 +226,13 @@ def test_alias_content_manager_rendering_preview_add_url(self): ) self.assertNotIn( '', # noqa: E501 - response_content_decoded + response_content_decoded, ) # check for add content admin link add_aliascontent_url = admin_reverse( - '{}_{}_add'.format( + "{}_{}_add".format( expected_en_content._meta.app_label, - expected_en_content._meta.model_name + expected_en_content._meta.model_name, ) ) self.assertNotIn( @@ -248,39 +246,54 @@ def _create_alias_and_categories(self, category_name, alias_content_name=None): category = Category.objects.create(name=category_name) alias = AliasModel.objects.create(category=category, position=0) alias_content = AliasContent.objects.create( - alias=alias, - name=alias_content_name, - language="en" + alias=alias, name=alias_content_name, language="en" ) return category, alias, alias_content - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_category_field_ordering_versioned(self): """ Related category can be ordered by name, both in ascending and descending order, with versioning """ # Create a number of categories, aliases, and alias content to order - first_category, first_alias, first_alias_content = self._create_alias_and_categories("First Order Test Case") + ( + first_category, + first_alias, + first_alias_content, + ) = self._create_alias_and_categories("First Order Test Case") # Previously lowercase and upper case would be sorted separately, test they are ordered together - first_category_lower, first_alias_lower, first_alias_content_lower = self._create_alias_and_categories( - "first order test case lower" - ) - middle_category, middle_alias, middle_alias_content = self._create_alias_and_categories( - "Middle Order Test Case" - ) + ( + first_category_lower, + first_alias_lower, + first_alias_content_lower, + ) = self._create_alias_and_categories("first order test case lower") + ( + middle_category, + middle_alias, + middle_alias_content, + ) = self._create_alias_and_categories("Middle Order Test Case") # Previously lowercase and upper case would be sorted separately, test they are ordered together - last_category_lower, last_alias_lower, last_alias_content_lower = self._create_alias_and_categories( - "z order test case lower" - ) - last_category, last_alias, last_alias_content = self._create_alias_and_categories( - "Z Order Test Case Upper" - ) + ( + last_category_lower, + last_alias_lower, + last_alias_content_lower, + ) = self._create_alias_and_categories("z order test case lower") + ( + last_category, + last_alias, + last_alias_content, + ) = self._create_alias_and_categories("Z Order Test Case Upper") # Create the versions for each alias content from djangocms_versioning.models import Version + Version.objects.create(content=first_alias_content, created_by=self.superuser) - Version.objects.create(content=first_alias_content_lower, created_by=self.superuser) + Version.objects.create( + content=first_alias_content_lower, created_by=self.superuser + ) Version.objects.create(content=middle_alias_content, created_by=self.superuser) - Version.objects.create(content=last_alias_content_lower, created_by=self.superuser) + Version.objects.create( + content=last_alias_content_lower, created_by=self.superuser + ) Version.objects.create(content=last_alias_content, created_by=self.superuser) with self.login_user_context(self.superuser): @@ -314,27 +327,39 @@ def test_category_field_ordering_versioned(self): self.assertEqual(results[1].text, last_alias_content_lower.name) self.assertEqual(results[0].text, last_alias_content.name) - @skipUnless(not is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(not is_versioning_enabled(), "Test only relevant for versioning") def test_category_field_ordering_unversioned(self): """ Related category can be ordered by name, both in ascending and descending order, without versioning """ # Create a number of categories, aliases, and alias content to order - first_category, first_alias, first_alias_content = self._create_alias_and_categories("First Order Test Case") + ( + first_category, + first_alias, + first_alias_content, + ) = self._create_alias_and_categories("First Order Test Case") # Previously lowercase and upper case would be sorted separately, test they are ordered together - first_category_lower, first_alias_lower, first_alias_content_lower = self._create_alias_and_categories( - "first order test case lower" - ) - middle_category, middle_alias, middle_alias_content = self._create_alias_and_categories( - "Middle Order Test Case" - ) + ( + first_category_lower, + first_alias_lower, + first_alias_content_lower, + ) = self._create_alias_and_categories("first order test case lower") + ( + middle_category, + middle_alias, + middle_alias_content, + ) = self._create_alias_and_categories("Middle Order Test Case") # Previously lowercase and upper case would be sorted separately, test they are ordered together - last_category_lower, last_alias_lower, last_alias_content_lower = self._create_alias_and_categories( - "z order test case lower" - ) - last_category, last_alias, last_alias_content = self._create_alias_and_categories( - "Z Order Test Case Upper" - ) + ( + last_category_lower, + last_alias_lower, + last_alias_content_lower, + ) = self._create_alias_and_categories("z order test case lower") + ( + last_category, + last_alias, + last_alias_content, + ) = self._create_alias_and_categories("Z Order Test Case Upper") with self.login_user_context(self.superuser): base_url = self.get_admin_url(AliasContent, "changelist") @@ -374,32 +399,32 @@ def test_aliascontent_list_view(self): about the objects """ category1 = Category.objects.create( - name='Category 1', + name="Category 1", ) category2 = Category.objects.create( - name='Category 2', + name="Category 2", ) plugin = add_plugin( self.placeholder, - 'TextPlugin', + "TextPlugin", language=self.language, - body='This is basic content', + body="This is basic content", ) alias1 = self._create_alias( [plugin], - name='Alias 1', + name="Alias 1", category=category1, ) alias2 = self._create_alias( [plugin], - name='Alias 2', + name="Alias 2", category=category2, ) alias3 = self._create_alias( [plugin], - name='Alias 3', + name="Alias 3", category=category1, published=False, ) @@ -412,9 +437,9 @@ def test_aliascontent_list_view(self): self.assertEqual(response.status_code, 200) self.assertContains(response, category1.name) self.assertContains(response, category2.name) - self.assertContains(response, 'Alias 1') - self.assertContains(response, 'Alias 2') - self.assertContains(response, 'Alias 3') + self.assertContains(response, "Alias 1") + self.assertContains(response, "Alias 2") + self.assertContains(response, "Alias 3") if is_versioning_enabled(): # we have both published and draft aliases so both should @@ -451,50 +476,49 @@ def test_aliascontent_list_view(self): class CategoryAdminViewsTestCase(BaseAliasPluginTestCase): - def test_changelist(self): Category.objects.all().delete() category1 = Category.objects.create() category2 = Category.objects.create() - category1.translations.create(language_code='en', name='Category 1') - category2.translations.create(language_code='en', name='Category 2') - category1.translations.create(language_code='de', name='Kategorie 1') - category2.translations.create(language_code='fr', name='Catégorie 2') - category1.translations.create(language_code='it', name='Categoria 1') + category1.translations.create(language_code="en", name="Category 1") + category2.translations.create(language_code="en", name="Category 2") + category1.translations.create(language_code="de", name="Kategorie 1") + category2.translations.create(language_code="fr", name="Catégorie 2") + category1.translations.create(language_code="it", name="Categoria 1") with self.login_user_context(self.superuser): - with force_language('en'): + with force_language("en"): en_response = self.client.get(self.get_category_list_endpoint()) - with force_language('de'): + with force_language("de"): de_response = self.client.get(self.get_category_list_endpoint()) - with force_language('fr'): + with force_language("fr"): fr_response = self.client.get(self.get_category_list_endpoint()) - with force_language('it'): + with force_language("it"): it_response = self.client.get(self.get_category_list_endpoint()) - self.assertContains(en_response, 'Category 1') - self.assertContains(en_response, 'Category 2') - self.assertNotContains(en_response, 'Kategorie 1') - self.assertNotContains(en_response, 'Catégorie 2') - self.assertNotContains(en_response, 'Categoria 1') - - self.assertContains(de_response, 'Kategorie 1') - self.assertContains(de_response, 'Category 2') # fallback - self.assertNotContains(de_response, 'Category 1') - self.assertNotContains(de_response, 'Catégorie 2') - self.assertNotContains(de_response, 'Categoria 1') - - self.assertContains(fr_response, 'Category 1') # fallback - self.assertContains(fr_response, 'Catégorie 2') - self.assertNotContains(fr_response, 'Category 2') - self.assertNotContains(fr_response, 'Kategorie 1') - self.assertNotContains(fr_response, 'Categoria 2') - - self.assertContains(it_response, 'Catégorie 2') # fallback - self.assertNotContains(it_response, 'Category 1') - self.assertNotContains(it_response, 'Category 2') - self.assertNotContains(it_response, 'Kategorie 1') - self.assertNotContains(it_response, 'Categoria 2') + self.assertContains(en_response, "Category 1") + self.assertContains(en_response, "Category 2") + self.assertNotContains(en_response, "Kategorie 1") + self.assertNotContains(en_response, "Catégorie 2") + self.assertNotContains(en_response, "Categoria 1") + + self.assertContains(de_response, "Kategorie 1") + self.assertContains(de_response, "Category 2") # fallback + self.assertNotContains(de_response, "Category 1") + self.assertNotContains(de_response, "Catégorie 2") + self.assertNotContains(de_response, "Categoria 1") + + self.assertContains(fr_response, "Category 1") # fallback + self.assertContains(fr_response, "Catégorie 2") + self.assertNotContains(fr_response, "Category 2") + self.assertNotContains(fr_response, "Kategorie 1") + self.assertNotContains(fr_response, "Categoria 2") + + self.assertContains(it_response, "Catégorie 2") # fallback + self.assertNotContains(it_response, "Category 1") + self.assertNotContains(it_response, "Category 2") + self.assertNotContains(it_response, "Kategorie 1") + self.assertNotContains(it_response, "Categoria 2") def test_changelist_standard_user(self): """ @@ -512,9 +536,11 @@ def test_changelist_staff_user_without_permission(self): def test_changelist_staff_user_with_permission(self): user = self.get_staff_user_with_std_permissions() - user.user_permissions.add(Permission.objects.get( - content_type__app_label='djangocms_alias', - codename='change_category')) + user.user_permissions.add( + Permission.objects.get( + content_type__app_label="djangocms_alias", codename="change_category" + ) + ) with self.login_user_context(user): response = self.client.get(self.get_category_list_endpoint()) self.assertEqual(response.status_code, 200) @@ -524,8 +550,7 @@ def test_changelist_edit_button(self): response = self.client.get(self.get_category_list_endpoint()) self.assertContains( - response, - 'Aliases') + self.assertNotContains(response, "Aliases") def test_add_aliases_submenu_to_admin_menu(self): user = self.get_staff_user_with_std_permissions() - user.user_permissions.add(Permission.objects.get( - content_type__app_label='djangocms_alias', - codename='change_category')) + user.user_permissions.add( + Permission.objects.get( + content_type__app_label="djangocms_alias", codename="change_category" + ) + ) try: page_url = get_object_edit_url(self.page.get_title_obj(self.language)) except AttributeError: page_url = get_object_edit_url(self.page.get_content_obj(self.language)) with self.login_user_context(user): response = self.client.get(page_url, follow=True) - self.assertContains(response, 'Aliases') + self.assertContains(response, "Aliases") def test_aliases_link_placement(self): request = self.get_page_request(self.page, user=self.superuser) admin_menu = request.toolbar.get_or_create_menu(ADMIN_MENU_IDENTIFIER) break_item = admin_menu.find_first(Break, identifier=ADMINISTRATION_BREAK) # noqa: E501 item_positioned_before_admin_break = admin_menu.items[break_item.index - 1] # noqa: E501 - self.assertEqual(item_positioned_before_admin_break.name, 'Aliases...') + self.assertEqual(item_positioned_before_admin_break.name, "Aliases...") def test_add_alias_menu_showing_only_on_alias_plugin_views(self): alias = self._create_alias([self.plugin]) @@ -75,20 +70,24 @@ def test_add_alias_menu_showing_only_on_alias_plugin_views(self): self.get_list_alias_endpoint(), self.page.get_absolute_url(language=self.language), ]: - request = self.get_page_request(page=None, path=endpoint, user=self.superuser) + request = self.get_page_request( + page=None, path=endpoint, user=self.superuser + ) alias_menu = request.toolbar.get_menu(ALIAS_MENU_IDENTIFIER) self.assertEqual(alias_menu, None) def _test_alias_endpoint(**kwargs): - kwargs.update({ - 'alias': alias, - 'path': endpoint, - 'user': self.superuser, - }) + kwargs.update( + { + "alias": alias, + "path": endpoint, + "user": self.superuser, + } + ) # py34 compat request = self.get_alias_request(**ChainMap(kwargs)) alias_menu = request.toolbar.get_menu(ALIAS_MENU_IDENTIFIER) - self.assertEqual(alias_menu.name, 'Alias') + self.assertEqual(alias_menu.name, "Alias") _test_alias_endpoint() _test_alias_endpoint(edit=True) @@ -130,18 +129,18 @@ def test_alias_toolbar_language_menu(self): menu.name: [menu_item.name for menu_item in menu.items] for key, menu in language_menu.menus.items() } - self.assertIn('Add Translation', language_menu_dict.keys()) - self.assertIn('Delete Translation', language_menu_dict.keys()) + self.assertIn("Add Translation", language_menu_dict.keys()) + self.assertIn("Delete Translation", language_menu_dict.keys()) self.assertEqual( - {'Deutsche...', 'Française...', 'Italiano...'}, - set(language_menu_dict['Add Translation']), + {"Deutsche...", "Française...", "Italiano..."}, + set(language_menu_dict["Add Translation"]), ) self.assertEqual( - {'English...'}, - set(language_menu_dict['Delete Translation']), + {"English..."}, + set(language_menu_dict["Delete Translation"]), ) - alias_content = alias.contents.create(name='test alias 2', language='fr') + alias_content = alias.contents.create(name="test alias 2", language="fr") alias_content.populate(replaced_placeholder=self.placeholder) alias_content.alias.clear_cache() @@ -150,7 +149,8 @@ def test_alias_toolbar_language_menu(self): from djangocms_versioning.models import Version Version.objects.create( - content=alias_content, created_by=self.superuser, state=PUBLISHED) + content=alias_content, created_by=self.superuser, state=PUBLISHED + ) request = self.get_alias_request( alias=alias, @@ -165,59 +165,64 @@ def test_alias_toolbar_language_menu(self): for key, menu in language_menu.menus.items() } self.assertEqual( - {'Deutsche...', 'Italiano...'}, - set(language_menu_dict['Add Translation']), + {"Deutsche...", "Italiano..."}, + set(language_menu_dict["Add Translation"]), ) self.assertEqual( - {'Française...', 'English...'}, - set(language_menu_dict['Delete Translation']), + {"Française...", "English..."}, + set(language_menu_dict["Delete Translation"]), ) self.assertEqual( - {'from Française'}, - set(language_menu_dict['Copy all plugins']), + {"from Française"}, + set(language_menu_dict["Copy all plugins"]), ) language_menu_first_items = { - menu.name: next(filter( - lambda item: item.name in ['Française...', 'Deutsche...', 'from Française'], - menu.items, - )) + menu.name: next( + filter( + lambda item: item.name + in ["Française...", "Deutsche...", "from Française"], + menu.items, + ) + ) for key, menu in language_menu.menus.items() } # First item is Deutsche... for Add Translation self.assertIn( - '/en/admin/djangocms_alias/aliascontent/add/', - language_menu_first_items['Add Translation'].url, + "/en/admin/djangocms_alias/aliascontent/add/", + language_menu_first_items["Add Translation"].url, ) self.assertIn( - 'language=de', - language_menu_first_items['Add Translation'].url, + "language=de", + language_menu_first_items["Add Translation"].url, ) self.assertIn( - f'alias={alias.pk}', - language_menu_first_items['Add Translation'].url, + f"alias={alias.pk}", + language_menu_first_items["Add Translation"].url, ) self.assertEqual( # First item is Française... for Delete Translation - '/en/admin/djangocms_alias/aliascontent/{}/delete/?language=fr'.format( - alias.get_content('fr').pk, + "/en/admin/djangocms_alias/aliascontent/{}/delete/?language=fr".format( + alias.get_content("fr").pk, ), - language_menu_first_items['Delete Translation'].url, + language_menu_first_items["Delete Translation"].url, ) self.assertRegex( - language_menu_first_items['Copy all plugins'].action, - r'en\/admin\/([\w\/]+)\/copy-plugins\/', + language_menu_first_items["Copy all plugins"].action, + r"en\/admin\/([\w\/]+)\/copy-plugins\/", ) def test_language_switcher_when_toolbar_object_is_alias_content(self): alias = self._create_alias([self.plugin]) - alias_content = alias.contents.create(name='test alias 2', language='fr') - expected_result = ['English', 'Française'] + alias_content = alias.contents.create(name="test alias 2", language="fr") + expected_result = ["English", "Française"] if is_versioning_enabled(): from djangocms_versioning.constants import DRAFT from djangocms_versioning.models import Version + Version.objects.create( - content=alias_content, created_by=self.superuser, state=DRAFT) + content=alias_content, created_by=self.superuser, state=DRAFT + ) alias_content.populate(replaced_placeholder=self.placeholder) alias_content.alias.clear_cache() @@ -237,22 +242,20 @@ def test_language_switcher_when_toolbar_object_isnt_alias_content(self): preview=True, ) language_menu = request.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER) - expected_result = ['English', 'Deutsche', 'Française', 'Italiano'] + expected_result = ["English", "Deutsche", "Française", "Italiano"] # Versioning changes the toolbar language selector and only shows # languages that have translations if is_versioning_enabled(): - expected_result = ['English'] + expected_result = ["English"] # Don't change default language switcher that is used for Pages - self.assertEqual( - [item.name for item in language_menu.items], expected_result - ) + self.assertEqual([item.name for item in language_menu.items], expected_result) def test_page_toolbar_no_language_menu(self): from django.utils.translation import gettext as _ alias = self._create_alias([self.plugin]) - alias_content = alias.contents.create(name='test alias 2', language='fr') + alias_content = alias.contents.create(name="test alias 2", language="fr") # Get request request = self.get_alias_request( alias=alias, @@ -271,14 +274,16 @@ def test_page_toolbar_no_language_menu(self): break else: self.fail("No AliasToolbar in alias request") - language_menu = request.toolbar.get_menu(LANGUAGE_MENU_IDENTIFIER, _("Language")) + language_menu = request.toolbar.get_menu( + LANGUAGE_MENU_IDENTIFIER, _("Language") + ) self.assertIsNone(language_menu) def test_change_alias_settings_button_is_visible_on_alias_edit_view(self): - button_label = 'Change alias settings...' - alias_change_viewname = 'djangocms_alias_alias_change' + button_label = "Change alias settings..." + alias_change_viewname = "djangocms_alias_alias_change" alias = self._create_alias() - with force_language('en'): + with force_language("en"): request = self.get_alias_request( alias=alias, user=self.superuser, @@ -288,7 +293,7 @@ def test_change_alias_settings_button_is_visible_on_alias_edit_view(self): search_result = alias_menu.find_first(item_type=ModalItem, name=button_label) self.assertIsNotNone(search_result) button = search_result.item - self.assertEqual(button.on_close, 'REFRESH_PAGE') + self.assertEqual(button.on_close, "REFRESH_PAGE") self.assertEqual( button.url, admin_reverse( @@ -304,7 +309,7 @@ def test_alias_usage_button(self): user=self.superuser, edit=True, ) - button_label = 'View usage...' + button_label = "View usage..." alias_menu = request.toolbar.get_menu(ALIAS_MENU_IDENTIFIER) search_result = alias_menu.find_first(item_type=ModalItem, name=button_label) self.assertIsNotNone(search_result) @@ -318,7 +323,7 @@ def test_alias_usage_button(self): ) self.assertEqual( button.on_close, - 'REFRESH_PAGE', + "REFRESH_PAGE", ) def test_create_wizard_button_enabled(self): @@ -330,7 +335,7 @@ def test_create_wizard_button_enabled(self): create_button = self._get_wizard_create_button(request) self.assertEqual(create_button.disabled, False) - @skipUnless(not is_versioning_enabled(), 'Test only relevant when no versioning') + @skipUnless(not is_versioning_enabled(), "Test only relevant when no versioning") def test_delete_button_show_on_edit_alias_view_no_versioning(self): """ When versioning is not installed deletion should be possible. The delete button @@ -342,7 +347,7 @@ def test_delete_button_show_on_edit_alias_view_no_versioning(self): user=self.superuser, edit=True, ) - button_label = 'Delete alias...' + button_label = "Delete alias..." alias_menu = request.toolbar.get_menu(ALIAS_MENU_IDENTIFIER) search_result = alias_menu.find_first(item_type=ModalItem, name=button_label) @@ -358,7 +363,7 @@ def test_delete_button_show_on_edit_alias_view_no_versioning(self): self.get_list_alias_endpoint(), ) - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_delete_button_not_shown_on_edit_alias_view_with_versioning(self): """ When versioning is installed no deletion should be possible. The delete button @@ -370,7 +375,7 @@ def test_delete_button_not_shown_on_edit_alias_view_with_versioning(self): user=self.superuser, edit=True, ) - button_label = 'Delete alias...' + button_label = "Delete alias..." alias_menu = request.toolbar.get_menu(ALIAS_MENU_IDENTIFIER) search_result = alias_menu.find_first(item_type=ModalItem, name=button_label) @@ -388,7 +393,7 @@ def test_do_not_disable_buttons_when_in_preview_mode(self): search_results = alias_menu.find_items(item_type=ModalItem) self.assertNotEqual(bool(search_results), False) for result in search_results: - if result.item.name == 'View usage...': + if result.item.name == "View usage...": self.assertEqual(result.item.disabled, False) else: self.assertEqual(result.item.disabled, False) @@ -405,7 +410,7 @@ def test_disable_buttons_when_not_have_perms(self): search_results = alias_menu.find_items(item_type=ModalItem) self.assertNotEqual(bool(search_results), False) for result in search_results: - if result.item.name == 'View usage...': + if result.item.name == "View usage...": self.assertEqual(result.item.disabled, False) else: self.assertEqual(result.item.disabled, True) @@ -433,7 +438,7 @@ def test_site_dropdown_url_renders_admin_changelist(self): site_aliases_url, ) - content = response.content.decode('utf-8') + content = response.content.decode("utf-8") self.assertEqual(response.status_code, 200) # Rendered content should contain admin changelist header @@ -443,9 +448,10 @@ def test_site_dropdown_url_renders_admin_changelist_url(self): request = self.get_page_request(self.page, user=self.superuser) admin_menu = request.toolbar.get_or_create_menu(ADMIN_MENU_IDENTIFIER) site_aliases_url = admin_menu.items[3].url - admin_changelist_aliases_url = reverse("admin:{}_alias_changelist".format( - AliasContent._meta.app_label) - ) + "?language=en" + admin_changelist_aliases_url = ( + reverse(f"admin:{AliasContent._meta.app_label}_alias_changelist") + + "?language=en" + ) with self.login_user_context(self.superuser): response = self.client.get( diff --git a/tests/test_views.py b/tests/test_views.py index 82786922..955c7174 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -27,7 +27,6 @@ class AliasViewsTestCase(BaseAliasPluginTestCase): - def test_create_alias_view_get_no_data(self): with self.login_user_context(self.superuser): response = self.client.get(self.get_create_alias_endpoint()) @@ -39,25 +38,31 @@ def test_create_alias_view_non_staff_denied_access(self): def test_create_alias_view_get_show_form_plugin(self): with self.login_user_context(self.superuser): - response = self.client.get(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'language': self.language, - }) + response = self.client.get( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) self.assertEqual( - response.context['form'].initial['plugin'].pk, + response.context["form"].initial["plugin"].pk, self.plugin.pk, ) def test_create_alias_view_get_show_form_placeholder(self): with self.login_user_context(self.superuser): - response = self.client.get(self.get_create_alias_endpoint(), data={ - 'placeholder': self.placeholder.pk, - 'language': self.language, - }) + response = self.client.get( + self.get_create_alias_endpoint(), + data={ + "placeholder": self.placeholder.pk, + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) self.assertEqual( - response.context['form'].initial['placeholder'], + response.context["form"].initial["placeholder"], self.placeholder, ) @@ -68,27 +73,33 @@ def test_create_alias_view_show_form_replace_hidden(self): content_type=ContentType.objects.get_for_model( Alias, ), - codename='add_alias', + codename="add_alias", ) ) with self.login_user_context(user): - response = self.client.get(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'language': self.language, - }) + response = self.client.get( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) self.assertTrue( - response.context['form'].fields['replace'].widget.is_hidden, + response.context["form"].fields["replace"].widget.is_hidden, ) def test_create_alias_view_post_plugin(self): with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'language': self.language, - 'name': 'test alias', - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "language": self.language, + "name": "test alias", + }, + ) self.assertEqual(response.status_code, 200) alias = Alias.objects.last() @@ -117,19 +128,22 @@ def test_create_alias_view_post_plugin_replace(self): plugin = add_plugin( placeholder, - 'TextPlugin', - language='en', - body='test 222', + "TextPlugin", + language="en", + body="test 222", ) with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': plugin.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - 'replace': True, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": plugin.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + "replace": True, + }, + ) self.assertEqual(response.status_code, 200) @@ -147,66 +161,81 @@ def test_create_alias_view_post_plugin_replace(self): def test_create_alias_view_name(self): with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) alias = Alias.objects.last() if is_versioning_enabled(): self._publish(alias) - self.assertEqual(alias.name, 'test alias') + self.assertEqual(alias.name, "test alias") def test_create_alias_view_post_no_plugin_or_placeholder(self): with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) - self.assertFalse(response.context['form'].is_valid()) + self.assertFalse(response.context["form"].is_valid()) def test_create_alias_view_post_both_plugin_and_placeholder(self): with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'placeholder': self.placeholder.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "placeholder": self.placeholder.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) - self.assertFalse(response.context['form'].is_valid()) + self.assertFalse(response.context["form"].is_valid()) def test_create_alias_view_post_empty_placeholder(self): - placeholder = Placeholder(slot='empty') + placeholder = Placeholder(slot="empty") placeholder.save() with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'placeholder': placeholder.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "placeholder": placeholder.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 400) self.assertEqual( response.content.decode(), - 'Plugins are required to create an alias', + "Plugins are required to create an alias", ) def test_create_alias_view_post_placeholder(self): with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'placeholder': self.placeholder.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "placeholder": self.placeholder.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) # Source plugins are kept in original placeholder @@ -239,19 +268,22 @@ def test_create_alias_view_post_placeholder_replace(self): placeholder.get_plugins().delete() text_plugin = add_plugin( placeholder, - 'TextPlugin', - language='en', - body='test 2', + "TextPlugin", + language="en", + body="test 2", ) with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'placeholder': placeholder.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - 'replace': True, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "placeholder": placeholder.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + "replace": True, + }, + ) self.assertEqual(response.status_code, 200) alias = Alias.objects.last() @@ -276,12 +308,15 @@ def test_create_alias_view_post_placeholder_replace(self): def test_create_alias_view_post_no_create_permission(self): with self.login_user_context(self.get_staff_user_with_no_permissions()): # noqa: E501 - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 403) def test_create_alias_view_post_no_replace_permission(self): @@ -291,17 +326,20 @@ def test_create_alias_view_post_no_replace_permission(self): content_type=ContentType.objects.get_for_model( Alias, ), - codename='add_alias', + codename="add_alias", ) ) with self.login_user_context(user): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - 'replace': True, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + "replace": True, + }, + ) self.assertEqual(response.status_code, 403) def test_detach_view_no_permission_to_add_plugins_from_alias(self): @@ -314,8 +352,8 @@ def test_detach_view_get(self): alias = self._create_alias([self.plugin]) plugin = add_plugin( self.placeholder, - 'Alias', - language='en', + "Alias", + language="en", alias=alias, ) with self.login_user_context(self.superuser): @@ -328,8 +366,8 @@ def test_detach_view_non_staff_denied_access(self): alias = self._create_alias([self.plugin]) plugin = add_plugin( self.placeholder, - 'Alias', - language='en', + "Alias", + language="en", alias=alias, ) user = self.get_staff_user_with_no_permissions() @@ -356,27 +394,27 @@ def test_detach_view(self): alias = self._create_alias() add_plugin( placeholder, - 'TextPlugin', + "TextPlugin", language=self.language, - body='test', + body="test", ) plugin = add_plugin( placeholder, - 'Alias', - language='en', + "Alias", + language="en", alias=alias, ) add_plugin( alias.get_placeholder(self.language), - 'TextPlugin', + "TextPlugin", language=self.language, - body='test 2', + body="test 2", ) add_plugin( alias.get_placeholder(self.language), - 'TextPlugin', + "TextPlugin", language=self.language, - body='test 88', + body="test 88", ) plugins = placeholder.get_plugins() self.assertEqual(plugins.count(), 2) @@ -389,9 +427,9 @@ def test_detach_view(self): plugins = placeholder.get_plugins() self.assertEqual(plugins.count(), 3) - self.assertEqual(plugins[0].get_bound_plugin().body, 'test') - self.assertEqual(plugins[1].get_bound_plugin().body, 'test 2') - self.assertEqual(plugins[2].get_bound_plugin().body, 'test 88') + self.assertEqual(plugins[0].get_bound_plugin().body, "test") + self.assertEqual(plugins[1].get_bound_plugin().body, "test 2") + self.assertEqual(plugins[2].get_bound_plugin().body, "test 88") def test_alias_content_preview_view(self): alias = self._create_alias([self.plugin]) @@ -403,27 +441,37 @@ def test_alias_content_preview_view(self): self.assertContains(response, self.plugin.body) def test_view_aliases_using_site_filter(self): - site1 = Site.objects.create(domain='site1.com', name='1') - site2 = Site.objects.create(domain='site2.com', name='2') + site1 = Site.objects.create(domain="site1.com", name="1") + site2 = Site.objects.create(domain="site2.com", name="2") site1_plugin = add_plugin( self.placeholder, - 'TextPlugin', - language='en', - body='This is text in English', + "TextPlugin", + language="en", + body="This is text in English", ) site2_plugin = add_plugin( self.placeholder, - 'TextPlugin', - language='en', - body='Das ist Text auf Deutsch', + "TextPlugin", + language="en", + body="Das ist Text auf Deutsch", + ) + site1_alias = self._create_alias( + plugins=[site1_plugin], + site=site1, + name="site1_alias", + category=self.category, + ) + site2_alias = self._create_alias( + plugins=[site2_plugin], + site=site2, + name="site2_alias", + category=self.category, ) - site1_alias = self._create_alias(plugins=[site1_plugin], site=site1, name='site1_alias', category=self.category) - site2_alias = self._create_alias(plugins=[site2_plugin], site=site2, name='site2_alias', category=self.category) alias_list_url = admin_reverse(LIST_ALIAS_URL_NAME) # when no filter used both objects are displayed with self.login_user_context(self.superuser): - with force_language('en'): + with force_language("en"): list_response = self.client.get(alias_list_url) self.assertContains(list_response, site1_alias.name) @@ -431,8 +479,10 @@ def test_view_aliases_using_site_filter(self): # when no filtering by site 1 only first object displayed with self.login_user_context(self.superuser): - with force_language('en'): - site1_aliases_filter_url = f"{alias_list_url}?site={site1_alias.site.id}" + with force_language("en"): + site1_aliases_filter_url = ( + f"{alias_list_url}?site={site1_alias.site.id}" + ) list_response = self.client.get(site1_aliases_filter_url) self.assertContains(list_response, site1_alias.name) @@ -440,35 +490,40 @@ def test_view_aliases_using_site_filter(self): # when no filtering by site 2 only first object displayed with self.login_user_context(self.superuser): - with force_language('en'): - site2_aliases_filter_url = f"{alias_list_url}?site={site2_alias.site.id}" + with force_language("en"): + site2_aliases_filter_url = ( + f"{alias_list_url}?site={site2_alias.site.id}" + ) list_response = self.client.get(site2_aliases_filter_url) self.assertNotContains(list_response, site1_alias.name) self.assertContains(list_response, site2_alias.name) - @skipIf(is_versioning_enabled(), 'Test only relevant without versioning enabled') + @skipIf(is_versioning_enabled(), "Test only relevant without versioning enabled") def test_create_alias_name_unique_per_category_and_language(self): self._create_alias( - name='test alias', + name="test alias", category=self.category, ) with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) self.assertContains( response, - 'Alias with this Name and Category already exists.', + "Alias with this Name and Category already exists.", ) self.assertEqual( AliasContent.objects.filter( - name='test alias', + name="test alias", language=self.language, alias__category=self.category, ).count(), @@ -484,21 +539,22 @@ def test_select2_view_no_permission(self): self.assertEqual(response.status_code, 403) def test_select2_view(self): - alias1 = self._create_alias(name='test 2') - alias2 = self._create_alias(name='foo', position=1) - alias3 = self._create_alias(name='foo4', position=1, published=False) + alias1 = self._create_alias(name="test 2") + alias2 = self._create_alias(name="foo", position=1) + alias3 = self._create_alias(name="foo4", position=1, published=False) if is_versioning_enabled(): from djangocms_versioning.constants import DRAFT from djangocms_versioning.models import Version # This will show because it's a new draft version of the same alias - draft_content = alias2.contents.create(name='foo', language=self.language) + draft_content = alias2.contents.create(name="foo", language=self.language) Version.objects.create( - content=draft_content, created_by=self.superuser, state=DRAFT) + content=draft_content, created_by=self.superuser, state=DRAFT + ) # This shouldn't show because it hasn't content in current language - self._create_alias(name='foo2', language='fr', position=1) + self._create_alias(name="foo2", language="fr", position=1) with self.login_user_context(self.superuser): response = self.client.get( admin_reverse( @@ -507,29 +563,29 @@ def test_select2_view(self): ) result = [alias1.pk, alias2.pk, alias3.pk] - text_result = ['test 2'] + text_result = ["test 2"] if is_versioning_enabled(): # The following versions have draft content - text_result.append('foo (Not published)') - text_result.append('foo4 (Not published)') + text_result.append("foo (Not published)") + text_result.append("foo4 (Not published)") else: - text_result.append('foo') - text_result.append('foo4') + text_result.append("foo") + text_result.append("foo4") self.assertEqual(response.status_code, 200) - self.assertEqual([a['id'] for a in response.json()['results']], result) + self.assertEqual([a["id"] for a in response.json()["results"]], result) self.assertEqual( - [a['text'] for a in response.json()['results']], + [a["text"] for a in response.json()["results"]], text_result, ) def test_select2_view_order_by_category_and_position(self): - category2 = Category.objects.create(name='foo') - alias1 = self._create_alias(name='test 2') - alias2 = self._create_alias(name='foo', position=1) - alias3 = self._create_alias(name='bar', category=category2) - alias4 = self._create_alias(name='baz', category=category2, position=1) + category2 = Category.objects.create(name="foo") + alias1 = self._create_alias(name="test 2") + alias2 = self._create_alias(name="foo", position=1) + alias3 = self._create_alias(name="bar", category=category2) + alias4 = self._create_alias(name="baz", category=category2, position=1) with self.login_user_context(self.superuser): response = self.client.get( admin_reverse( @@ -539,30 +595,30 @@ def test_select2_view_order_by_category_and_position(self): self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [alias3.pk, alias4.pk, alias1.pk, alias2.pk], ) def test_select2_view_set_limit(self): - self._create_alias(name='test 2') - self._create_alias(name='foo', position=1) - self._create_alias(name='three', position=2) + self._create_alias(name="test 2") + self._create_alias(name="foo", position=1) + self._create_alias(name="three", position=2) with self.login_user_context(self.superuser): response = self.client.get( admin_reverse( SELECT2_ALIAS_URL_NAME, ), - data={'limit': 2}, + data={"limit": 2}, ) content = response.json() self.assertEqual(response.status_code, 200) - self.assertTrue(content['more']) - self.assertEqual(len(content['results']), 2) + self.assertTrue(content["more"]) + self.assertEqual(len(content["results"]), 2) def test_select2_view_text_repr(self): - alias1 = self._create_alias(name='test 2') + alias1 = self._create_alias(name="test 2") with self.login_user_context(self.superuser): response = self.client.get( admin_reverse( @@ -572,64 +628,64 @@ def test_select2_view_text_repr(self): self.assertEqual(response.status_code, 200) self.assertEqual( - response.json()['results'][0]['text'], + response.json()["results"][0]["text"], alias1.name, ) def test_select2_view_term(self): - alias1 = self._create_alias(name='test 2') - self._create_alias(name='foo', position=1) - alias3 = self._create_alias(name='three', position=2) + alias1 = self._create_alias(name="test 2") + self._create_alias(name="foo", position=1) + alias3 = self._create_alias(name="three", position=2) with self.login_user_context(self.superuser): response = self.client.get( admin_reverse( SELECT2_ALIAS_URL_NAME, ), - data={'term': 't'}, + data={"term": "t"}, ) self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [alias1.pk, alias3.pk], ) def test_select2_view_category(self): - category2 = Category.objects.create(name='test 2') - alias1 = self._create_alias(name='test 2', category=category2) - alias2 = self._create_alias(name='foo', category=category2, position=1) + category2 = Category.objects.create(name="test 2") + alias1 = self._create_alias(name="test 2", category=category2) + alias2 = self._create_alias(name="foo", category=category2, position=1) # This shouldnt show because it's in different Category - self._create_alias(name='three') + self._create_alias(name="three") with self.login_user_context(self.superuser): response = self.client.get( admin_reverse( SELECT2_ALIAS_URL_NAME, ), - data={'category': category2.pk}, + data={"category": category2.pk}, ) self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [alias1.pk, alias2.pk], ) def test_select2_view_category_and_term(self): - category2 = Category.objects.create(name='test 2') - alias1 = self._create_alias(name='test 2', category=category2) - self._create_alias(name='foo', category=category2, position=1) - self._create_alias(name='three') + category2 = Category.objects.create(name="test 2") + alias1 = self._create_alias(name="test 2", category=category2) + self._create_alias(name="foo", category=category2, position=1) + self._create_alias(name="three") with self.login_user_context(self.superuser): response = self.client.get( admin_reverse( SELECT2_ALIAS_URL_NAME, ), - data={'category': category2.pk, 'term': 't'}, + data={"category": category2.pk, "term": "t"}, ) self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [alias1.pk], ) @@ -648,12 +704,12 @@ def test_select2_view_site(self): admin_reverse( SELECT2_ALIAS_URL_NAME, ), - data={'site': site.pk}, + data={"site": site.pk}, ) self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [alias1.pk, alias2.pk, alias3.pk], ) @@ -662,7 +718,7 @@ def test_select2_view_site_and_category(self): The list is filtered based on only matching alias with a specific site and category if it is provided """ - category = Category.objects.create(name='category') + category = Category.objects.create(name="category") site = get_current_site() self._create_alias(site=site) alias2 = self._create_alias(site=site, category=category, position=1) @@ -675,32 +731,32 @@ def test_select2_view_site_and_category(self): SELECT2_ALIAS_URL_NAME, ), data={ - 'site': site.pk, - 'category': category.pk, + "site": site.pk, + "category": category.pk, }, ) self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [alias2.pk], ) def test_select2_view_pk(self): - alias1 = self._create_alias(name='test 2') - self._create_alias(name='foo', position=1) - self._create_alias(name='three') + alias1 = self._create_alias(name="test 2") + self._create_alias(name="foo", position=1) + self._create_alias(name="three") with self.login_user_context(self.superuser): response = self.client.get( admin_reverse( SELECT2_ALIAS_URL_NAME, ), - data={'pk': alias1.pk}, + data={"pk": alias1.pk}, ) self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [alias1.pk], ) @@ -712,21 +768,21 @@ def test_aliascontent_add_view(self): alias = Alias.objects.create(category=self.category) with self.login_user_context(self.superuser): response = self.client.post( - admin_reverse('djangocms_alias_aliascontent_add'), + admin_reverse("djangocms_alias_aliascontent_add"), data={ - 'language': 'de', - 'name': 'alias test de 1', - 'alias': alias.pk, + "language": "de", + "name": "alias test de 1", + "alias": alias.pk, }, ) self.assertEqual(response.status_code, 302) if is_versioning_enabled(): - self._publish(alias, 'de') + self._publish(alias, "de") self.assertEqual(alias.contents.count(), 1) alias_content = alias.contents.first() - self.assertEqual(alias_content.language, 'de') - self.assertEqual(alias_content.name, 'alias test de 1') + self.assertEqual(alias_content.language, "de") + self.assertEqual(alias_content.name, "alias test de 1") @skip( "It is not currently possible to add an alias from the django admin changelist issue " @@ -738,9 +794,9 @@ def test_aliascontent_add_view_get(self): response = self.client.get( add_url_parameters( admin_reverse( - 'djangocms_alias_aliascontent_add', + "djangocms_alias_aliascontent_add", ), - language='fr', + language="fr", alias=alias.pk, ) ) @@ -755,25 +811,25 @@ def test_aliascontent_add_view_get(self): def test_aliascontent_add_view_invalid_data(self): alias = Alias.objects.create(category=self.category) self._create_alias( - name='test alias', + name="test alias", category=self.category, language=self.language, published=True, ) with self.login_user_context(self.superuser): response = self.client.post( - admin_reverse('djangocms_alias_aliascontent_add'), + admin_reverse("djangocms_alias_aliascontent_add"), data={ - 'language': self.language, - 'name': 'test alias', - 'alias': alias.pk, + "language": self.language, + "name": "test alias", + "alias": alias.pk, }, ) self.assertEqual(response.status_code, 200) self.assertContains( response, - 'Alias with this Name and Category already exists', + "Alias with this Name and Category already exists", ) @skip( @@ -784,18 +840,18 @@ def test_aliascontent_add_view_valid_data(self): alias = Alias.objects.create(category=self.category) if is_versioning_enabled(): self._create_alias( - name='test alias', + name="test alias", category=self.category, language=self.language, published=False, ) with self.login_user_context(self.superuser): response = self.client.post( - admin_reverse('djangocms_alias_aliascontent_add'), + admin_reverse("djangocms_alias_aliascontent_add"), data={ - 'language': self.language, - 'name': 'test alias', - 'alias': alias.pk, + "language": self.language, + "name": "test alias", + "alias": alias.pk, }, ) @@ -803,7 +859,7 @@ def test_aliascontent_add_view_valid_data(self): if is_versioning_enabled(): self._publish(alias) alias_content = alias.contents.first() - self.assertEqual(alias_content.name, 'test alias') + self.assertEqual(alias_content.name, "test alias") def test_alias_usage_view(self): alias = self._create_alias() @@ -817,12 +873,12 @@ def test_alias_usage_view(self): ), ) - self.assertContains(response, 'Page') - self.assertNotContains(response, 'Alias') + self.assertContains(response, "Page") + self.assertNotContains(response, "Alias") add_plugin( root_alias.get_placeholder(self.language), - 'Alias', + "Alias", language=self.language, alias=alias, ) @@ -835,8 +891,8 @@ def test_alias_usage_view(self): ), ) - self.assertContains(response, 'Page') - self.assertContains(response, 'Alias') + self.assertContains(response, "Page") + self.assertContains(response, "Alias") self.assertRegex( str(response.content), r'href="{}"[\w+]?>{}<\/a>'.format( @@ -863,7 +919,7 @@ def test_alias_usage_view(self): back=1, ) ), - 'View usage', + "View usage", ), ) @@ -871,7 +927,7 @@ def test_delete_alias_view_get(self): alias = self._create_alias([self.plugin]) add_plugin( self.placeholder, - 'Alias', + "Alias", language=self.language, alias=alias, ) @@ -891,7 +947,7 @@ def test_delete_alias_view_get_using_objects(self): alias = self._create_alias([self.plugin]) add_plugin( self.placeholder, - 'Alias', + "Alias", language=self.language, alias=alias, ) @@ -902,8 +958,10 @@ def test_delete_alias_view_get_using_objects(self): args=[alias.pk], ), ) - self.assertContains(response, 'This alias is used by following objects:') - test = r'
  • [\s\\n]*Page:[\s\\n]*test<\/a>[\s\\n]*<\/li>' + self.assertContains(response, "This alias is used by following objects:") + test = ( + r"
  • [\s\\n]*Page:[\s\\n]*test<\/a>[\s\\n]*<\/li>" + ) self.assertRegex(str(response.content), test) def test_delete_alias_view_get_alias_not_used_on_any_page(self): @@ -915,7 +973,7 @@ def test_delete_alias_view_get_alias_not_used_on_any_page(self): args=[alias.pk], ), ) - self.assertContains(response, 'This alias wasn\'t used by any object.') + self.assertContains(response, "This alias wasn't used by any object.") def test_delete_alias_view_post(self): """Tests the admin delete view (as opposed to the djangocms_alias.views.delete_view)""" @@ -927,9 +985,11 @@ def test_delete_alias_view_post(self): DELETE_ALIAS_URL_NAME, args=[alias.pk], ), - data={'post': 'yes'}, + data={"post": "yes"}, ) - self.assertEqual(response.status_code, 302) # Successful delete returns a redirect + self.assertEqual( + response.status_code, 302 + ) # Successful delete returns a redirect self.assertFalse(Alias.objects.filter(pk=alias.pk).exists()) # Ensure it's gone def test_delete_alias_view_user_with_no_perms(self): @@ -950,7 +1010,7 @@ def test_delete_alias_view_user_with_no_perms(self): DELETE_ALIAS_URL_NAME, args=[alias.pk], ), - data={'post': 'yes'}, + data={"post": "yes"}, ) self.assertEqual(response.status_code, 403) @@ -964,7 +1024,7 @@ def test_delete_alias_view_alias_not_being_used(self): args=[alias.pk], ), ) - self.assertContains(response, 'Are you sure you want to delete') + self.assertContains(response, "Are you sure you want to delete") self.assertContains(response, 'type="submit"') with self.login_user_context(staff_user): # noqa: E501 response = self.client.post( # noqa @@ -972,7 +1032,7 @@ def test_delete_alias_view_alias_not_being_used(self): DELETE_ALIAS_URL_NAME, args=[alias.pk], ), - data={'post': 'yes'}, + data={"post": "yes"}, ) self.assertEqual(response.status_code, 302) self.assertFalse(Alias.objects.filter(pk=alias.pk).exists()) @@ -981,13 +1041,13 @@ def test_delete_alias_view_alias_being_used_on_pages(self): alias = self._create_alias([self.plugin]) add_plugin( self.placeholder, - 'Alias', + "Alias", language=self.language, alias=alias, ) # this user only can delete alias when alias not being used anywhere staff_user = self.get_staff_user_with_no_permissions() - self.add_permission(staff_user, 'delete_alias') + self.add_permission(staff_user, "delete_alias") with self.login_user_context(staff_user): # noqa: E501 response = self.client.get( @@ -1004,7 +1064,7 @@ def test_delete_alias_view_alias_being_used_on_pages(self): DELETE_ALIAS_URL_NAME, args=[alias.pk], ), - data={'post': 'yes'}, + data={"post": "yes"}, ) self.assertEqual(response.status_code, 403) @@ -1012,41 +1072,41 @@ def test_custom_template_alias_view(self): alias = self._create_alias() add_plugin( alias.get_placeholder(self.language), - 'TextPlugin', + "TextPlugin", language=self.language, - body='custom alias content', + body="custom alias content", ) add_plugin( self.placeholder, - 'Alias', + "Alias", language=self.language, alias=alias, - template='custom_alias_template', + template="custom_alias_template", ) response = self.client.get(self.page.get_absolute_url()) - self.assertContains(response, 'custom alias content') + self.assertContains(response, "custom alias content") @override_settings(CMS_PLACEHOLDER_CACHE=False) def test_alias_multisite_support(self): - site1 = Site.objects.create(domain='site1.com', name='1') - site2 = Site.objects.create(domain='site2.com', name='2') + site1 = Site.objects.create(domain="site1.com", name="1") + site2 = Site.objects.create(domain="site2.com", name="2") alias = self._create_alias() alias_placeholder = alias.get_placeholder(self.language) add_plugin( alias_placeholder, - 'TextPlugin', + "TextPlugin", language=self.language, - body='test alias multisite', + body="test alias multisite", ) site1_page = self._create_page( - title='Site1', + title="Site1", language=self.language, site=site1, ) site2_page = self._create_page( - title='Site2', + title="Site2", language=self.language, site=site2, ) @@ -1055,32 +1115,31 @@ def test_alias_multisite_support(self): with override_settings(SITE_ID=site1.pk): response = self.client.get(site1_page.get_absolute_url()) - self.assertContains(response, 'test alias multisite') + self.assertContains(response, "test alias multisite") with override_settings(SITE_ID=site2.pk): response = self.client.get(site2_page.get_absolute_url()) - self.assertContains(response, 'test alias multisite') + self.assertContains(response, "test alias multisite") add_plugin( alias_placeholder, - 'TextPlugin', + "TextPlugin", language=self.language, - body='Another alias plugin', + body="Another alias plugin", ) with override_settings(SITE_ID=site1.pk): response = self.client.get(site1_page.get_absolute_url()) - self.assertContains(response, 'test alias multisite') - self.assertContains(response, 'Another alias plugin') + self.assertContains(response, "test alias multisite") + self.assertContains(response, "Another alias plugin") with override_settings(SITE_ID=site2.pk): response = self.client.get(site2_page.get_absolute_url()) - self.assertContains(response, 'test alias multisite') - self.assertContains(response, 'Another alias plugin') + self.assertContains(response, "test alias multisite") + self.assertContains(response, "Another alias plugin") class AliasCategorySelect2ViewTestCase(BaseAliasPluginTestCase): - def test_select2_view_no_permission(self): """ The category list view is private @@ -1098,9 +1157,9 @@ def test_select2_view_alias_not_set(self): When categories exist but are not attached to an alias they are ignored """ - Category.objects.create(name='Category 1') - category_2 = Category.objects.create(name='Category 2') - Category.objects.create(name='Category 3') + Category.objects.create(name="Category 1") + category_2 = Category.objects.create(name="Category 2") + Category.objects.create(name="Category 3") self._create_alias(category=category_2) with self.login_user_context(self.superuser): @@ -1113,7 +1172,7 @@ def test_select2_view_alias_not_set(self): expected_result = [category_2.pk] self.assertEqual(response.status_code, 200) - self.assertEqual([a['id'] for a in response.json()['results']], expected_result) + self.assertEqual([a["id"] for a in response.json()["results"]], expected_result) def test_select2_view_alias_site_set(self): """ @@ -1122,9 +1181,9 @@ def test_select2_view_alias_site_set(self): """ site = get_current_site() second_site = Site.objects.create(domain="other-site.org", name="other site") - category_1 = Category.objects.create(name='Category 1') - category_2 = Category.objects.create(name='Category 2') - category_3 = Category.objects.create(name='Category 3') + category_1 = Category.objects.create(name="Category 1") + category_2 = Category.objects.create(name="Category 2") + category_3 = Category.objects.create(name="Category 3") self._create_alias(category=category_1, site=site) self._create_alias(category=category_2, site=second_site) self._create_alias(category=category_3) @@ -1134,21 +1193,21 @@ def test_select2_view_alias_site_set(self): admin_reverse( CATEGORY_SELECT2_URL_NAME, ), - data={'site': site.pk}, + data={"site": site.pk}, ) expected_result = [category_1.pk, category_3.pk] self.assertEqual(response.status_code, 200) - self.assertEqual([a['id'] for a in response.json()['results']], expected_result) + self.assertEqual([a["id"] for a in response.json()["results"]], expected_result) def test_select2_view_set_limit(self): """ Ensure that the page limit is respected """ - category_1 = Category.objects.create(name='Category 1') - category_2 = Category.objects.create(name='Category 2') - category_3 = Category.objects.create(name='Category 3') + category_1 = Category.objects.create(name="Category 1") + category_2 = Category.objects.create(name="Category 2") + category_3 = Category.objects.create(name="Category 3") self._create_alias(category=category_1) self._create_alias(category=category_2, position=1) self._create_alias(category=category_3, position=2) @@ -1158,22 +1217,22 @@ def test_select2_view_set_limit(self): admin_reverse( CATEGORY_SELECT2_URL_NAME, ), - data={'limit': 2}, + data={"limit": 2}, ) content = response.json() self.assertEqual(response.status_code, 200) - self.assertTrue(content['more']) - self.assertEqual(len(content['results']), 2) + self.assertTrue(content["more"]) + self.assertEqual(len(content["results"]), 2) def test_select2_view_text_repr(self): """ Ensure that the display / text representation of the object is output to the user. """ - category = Category.objects.create(name='Category 1') - self._create_alias(name='test 2', category=category) + category = Category.objects.create(name="Category 1") + self._create_alias(name="test 2", category=category) with self.login_user_context(self.superuser): response = self.client.get( @@ -1184,7 +1243,7 @@ def test_select2_view_text_repr(self): self.assertEqual(response.status_code, 200) self.assertEqual( - response.json()['results'][0]['text'], + response.json()["results"][0]["text"], category.name, ) @@ -1193,10 +1252,10 @@ def test_select2_view_term(self): Given a term, the response should return only categories that match the term. """ - category_1 = Category.objects.create(name='ategory 1') - category_2 = Category.objects.create(name='Category 2') - category_3 = Category.objects.create(name='tegory 3') - category_4 = Category.objects.create(name='tegory 4') + category_1 = Category.objects.create(name="ategory 1") + category_2 = Category.objects.create(name="Category 2") + category_3 = Category.objects.create(name="tegory 3") + category_4 = Category.objects.create(name="tegory 4") self._create_alias(category=category_1) self._create_alias(category=category_2) self._create_alias(category=category_3) @@ -1207,12 +1266,12 @@ def test_select2_view_term(self): admin_reverse( CATEGORY_SELECT2_URL_NAME, ), - data={'term': 'ate'}, + data={"term": "ate"}, ) self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [category_2.pk, category_1.pk], ) @@ -1220,9 +1279,9 @@ def test_select2_view_pk(self): """ When a pk is provided that record should be returned """ - category_1 = Category.objects.create(name='Category 1') - category_2 = Category.objects.create(name='Category 2') - category_3 = Category.objects.create(name='Category 3') + category_1 = Category.objects.create(name="Category 1") + category_2 = Category.objects.create(name="Category 2") + category_3 = Category.objects.create(name="Category 3") self._create_alias(category=category_1) self._create_alias(category=category_2) self._create_alias(category=category_3) @@ -1232,117 +1291,132 @@ def test_select2_view_pk(self): admin_reverse( CATEGORY_SELECT2_URL_NAME, ), - data={'pk': category_2.pk}, + data={"pk": category_2.pk}, ) self.assertEqual(response.status_code, 200) self.assertEqual( - [a['id'] for a in response.json()['results']], + [a["id"] for a in response.json()["results"]], [category_2.pk], ) class AliasViewsUsingVersioningTestCase(BaseAliasPluginTestCase): - - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_create_alias_view_name_draft_alias(self): with self.login_user_context(self.superuser): - name = 'test alias' - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'name': name, - 'language': self.language, - }) + name = "test alias" + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "name": name, + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) alias = Alias.objects.last() # AliasContent not published - self.assertEqual(alias.name, f'{name} (Not published)') + self.assertEqual(alias.name, f"{name} (Not published)") - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_create_alias_view_creating_version(self): with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) alias = Alias.objects.last() if is_versioning_enabled(): from djangocms_versioning.models import Version + self.assertEqual(Version.objects.filter_by_grouper(alias).count(), 1) - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_create_alias_name_without_uniqness(self): alias1 = self._create_alias( - name='test alias', + name="test alias", category=self.category, published=True, ) with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) self.assertContains( response, - 'Alias with this Name and Category already exists.', + "Alias with this Name and Category already exists.", ) self._unpublish(alias1) with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'plugin': self.plugin.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "plugin": self.plugin.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) self.assertNotContains( response, - 'Alias with this Name and Category already exists.', + "Alias with this Name and Category already exists.", ) alias = Alias.objects.last() self._publish(alias) qs = AliasContent.objects.filter( - name='test alias', + name="test alias", language=self.language, alias__category=self.category, ) self.assertEqual(qs.count(), 1) self.assertEqual(qs.first(), alias.get_content(self.language)) - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_create_alias_view_post_placeholder_from_draft_page(self): - page1 = self._create_page('test alias page') + page1 = self._create_page("test alias page") placeholder = page1.get_placeholders(self.language).get( - slot='content', + slot="content", ) plugin = add_plugin( placeholder, - 'TextPlugin', + "TextPlugin", language=self.language, - body='test alias', + body="test alias", ) self._unpublish(page1) with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'placeholder': placeholder.pk, - 'category': self.category.pk, - 'name': 'test alias', - 'language': self.language, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "placeholder": placeholder.pk, + "category": self.category.pk, + "name": "test alias", + "language": self.language, + }, + ) self.assertEqual(response.status_code, 200) # Source plugins are kept in original placeholder @@ -1365,27 +1439,30 @@ def test_create_alias_view_post_placeholder_from_draft_page(self): target.get_bound_plugin().body, ) - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_create_alias_with_replace_plugin_with_versioning_checks(self): # 403 if you try to edit placeholder of published page with self.login_user_context(self.superuser): - response = self.client.post(self.get_create_alias_endpoint(), data={ - 'placeholder': self.placeholder.pk, - 'category': self.category.pk, - 'name': 'test alias 5', - 'language': self.language, - 'replace': True, - }) + response = self.client.post( + self.get_create_alias_endpoint(), + data={ + "placeholder": self.placeholder.pk, + "category": self.category.pk, + "name": "test alias 5", + "language": self.language, + "replace": True, + }, + ) self.assertEqual(response.status_code, 403) - @skipUnless(is_versioning_enabled(), 'Test only relevant for versioning') + @skipUnless(is_versioning_enabled(), "Test only relevant for versioning") def test_detach_view_with_versioning_checks(self): # 403 when placeholder from non-draft page alias = self._create_alias() plugin = add_plugin( self.placeholder, - 'Alias', - language='en', + "Alias", + language="en", alias=alias, ) with self.login_user_context(self.superuser): @@ -1394,26 +1471,25 @@ def test_detach_view_with_versioning_checks(self): ) self.assertEqual(response.status_code, 403) - @skipUnless(is_versioning_enabled(), 'Only valid in versioning scenario') + @skipUnless(is_versioning_enabled(), "Only valid in versioning scenario") def test_alias_not_shown_when_draft_when_visiting_page(self): """ When visiting a published page with a draft alias the alias is not visible """ unpublished_alias = self._create_alias(published=False) - content = unpublished_alias.contents(manager="admin_manager").filter(language=self.language).first() + content = ( + unpublished_alias.contents(manager="admin_manager") + .filter(language=self.language) + .first() + ) alias_placeholder = content.placeholder - body = 'unpublished alias' - add_plugin( - alias_placeholder, - 'TextPlugin', - language=self.language, - body=body - ) + body = "unpublished alias" + add_plugin(alias_placeholder, "TextPlugin", language=self.language, body=body) page = self._create_page( - title='New page', + title="New page", language=self.language, ) @@ -1427,50 +1503,57 @@ def test_view_multilanguage(self): """ en_plugin = add_plugin( self.placeholder, - 'TextPlugin', - language='en', - body='This is text in English', + "TextPlugin", + language="en", + body="This is text in English", ) de_plugin = add_plugin( self.placeholder, - 'TextPlugin', - language='de', - body='Das ist Text auf Deutsch', + "TextPlugin", + language="de", + body="Das ist Text auf Deutsch", ) fr_plugin = add_plugin( self.placeholder, - 'TextPlugin', - language='fr', - body='C\'est le texte en français', + "TextPlugin", + language="fr", + body="C'est le texte en français", ) alias = self._create_alias([en_plugin], name="English AliasContent object") alias_content_de = AliasContent.objects.create( alias=alias, - name='German AliasContent object', - language='de', + name="German AliasContent object", + language="de", ) alias_content_de.populate(plugins=[de_plugin]) alias_content_fr = AliasContent.objects.create( alias=alias, - name='French AliasContent object', - language='fr', + name="French AliasContent object", + language="fr", ) alias_content_fr.populate(plugins=[fr_plugin]) # when versioning is enabled a Version must be created and published for each language if is_versioning_enabled(): from djangocms_versioning.models import Version - version_de = Version.objects.create(content=alias_content_de, created_by=self.superuser) + + version_de = Version.objects.create( + content=alias_content_de, created_by=self.superuser + ) version_de.publish(user=self.superuser) - version_fr = Version.objects.create(content=alias_content_fr, created_by=self.superuser) + version_fr = Version.objects.create( + content=alias_content_fr, created_by=self.superuser + ) version_fr.publish(user=self.superuser) with self.login_user_context(self.superuser): - with force_language('en'): + with force_language("en"): if is_versioning_enabled(): # we need to call get_absolute_url on the AliasContent object when versioning is enabled, # otherwise we are taken to the version list url - detail_response = self.client.get(alias.get_content(language="en").get_absolute_url()) + detail_response = self.client.get( + alias.get_content(language="en").get_absolute_url() + ) else: detail_response = self.client.get(alias.get_absolute_url()) list_response = self.client.get( @@ -1484,11 +1567,13 @@ def test_view_multilanguage(self): self.assertNotContains(list_response, alias_content_de.name) with self.login_user_context(self.superuser): - with force_language('de'): + with force_language("de"): if is_versioning_enabled(): # we need to call get_absolute_url on the AliasContent object when versioning is enabled, # otherwise we are taken to the version list url - detail_response = self.client.get(alias_content_de.get_absolute_url()) + detail_response = self.client.get( + alias_content_de.get_absolute_url() + ) else: detail_response = self.client.get(alias.get_absolute_url()) list_response = self.client.get( @@ -1502,11 +1587,13 @@ def test_view_multilanguage(self): self.assertNotContains(list_response, alias.name) with self.login_user_context(self.superuser): - with force_language('fr'): + with force_language("fr"): if is_versioning_enabled(): # we need to call get_absolute_url on the AliasContent object when versioning is enabled, # otherwise we are taken to the version list url - detail_response = self.client.get(alias_content_fr.get_absolute_url()) + detail_response = self.client.get( + alias_content_fr.get_absolute_url() + ) else: detail_response = self.client.get(alias.get_absolute_url()) list_response = self.client.get( diff --git a/tests/test_wizards.py b/tests/test_wizards.py index 5df58ac7..42803484 100644 --- a/tests/test_wizards.py +++ b/tests/test_wizards.py @@ -12,7 +12,6 @@ class WizardsTestCase(BaseAliasPluginTestCase): - def _get_wizard_instance(self, wizard_name): return [ wizard @@ -22,22 +21,24 @@ def _get_wizard_instance(self, wizard_name): def _get_form_kwargs(self, data, language=None): language = language or self.language - request = self.get_request('/', language=language) + request = self.get_request("/", language=language) request.user = self.superuser return { - 'data': data, - 'wizard_language': language, - 'wizard_site': Site.objects.get_current(), - 'wizard_request': request, + "data": data, + "wizard_language": language, + "wizard_site": Site.objects.get_current(), + "wizard_request": request, } def test_create_alias_wizard_instance(self): - wizard = self._get_wizard_instance('CreateAliasWizard') - self.assertEqual(wizard.title, 'New alias') + wizard = self._get_wizard_instance("CreateAliasWizard") + self.assertEqual(wizard.title, "New alias") self.assertTrue(wizard.user_has_add_permission(self.superuser)) self.assertTrue( - wizard.user_has_add_permission(self.get_staff_user_with_alias_permissions()), # noqa: E501 + wizard.user_has_add_permission( + self.get_staff_user_with_alias_permissions() + ), # noqa: E501 ) self.assertFalse( wizard.user_has_add_permission(self.get_staff_user_with_no_permissions()), # noqa: E501 @@ -47,11 +48,11 @@ def test_create_alias_wizard_instance(self): ) def test_create_alias_wizard_form(self): - wizard = self._get_wizard_instance('CreateAliasWizard') + wizard = self._get_wizard_instance("CreateAliasWizard") data = { - 'name': 'Content #1', - 'category': self.category.pk, - 'site': get_current_site().pk + "name": "Content #1", + "category": self.category.pk, + "site": get_current_site().pk, } form_class = step2_form_factory( mixin_cls=WizardStep2BaseForm, @@ -62,42 +63,43 @@ def test_create_alias_wizard_form(self): self.assertTrue(form.is_valid()) alias = form.save() - self.assertEqual(form.fields['site'].initial, get_current_site()) + self.assertEqual(form.fields["site"].initial, get_current_site()) with self.login_user_context(self.superuser): response = self.client.get(alias.get_absolute_url()) - self.assertContains(response, data['name']) + self.assertContains(response, data["name"]) if is_versioning_enabled(): from djangocms_versioning.models import Version + self.assertEqual(Version.objects.filter_by_grouper(alias).count(), 1) def test_create_alias_wizard_form_with_no_category_fallback_language(self): """When creating an Alias via the Wizard an error can occur if the category doesn't have a valid translation """ - translation.activate('en') + translation.activate("en") # A japanese translation that does not have any fallback settings! - Category.objects.language('ja').create(name='Japanese category') + Category.objects.language("ja").create(name="Japanese category") - wizard = self._get_wizard_instance('CreateAliasWizard') + wizard = self._get_wizard_instance("CreateAliasWizard") data = { - 'name': 'Content #1', - 'category': None, + "name": "Content #1", + "category": None, } form_class = step2_form_factory( mixin_cls=WizardStep2BaseForm, entry_form_class=wizard.form, ) form = form_class(**self._get_form_kwargs(data)) - category_form_queryset = form.declared_fields['category'].queryset + category_form_queryset = form.declared_fields["category"].queryset - self.assertEqual(form.fields['site'].initial, get_current_site()) + self.assertEqual(form.fields["site"].initial, get_current_site()) # Be sure that we have untranslated categories that enforces a fair test self.assertNotEqual( category_form_queryset.all().count(), - category_form_queryset.active_translations().count() + category_form_queryset.active_translations().count(), ) for category in category_form_queryset.all(): @@ -107,12 +109,14 @@ def test_create_alias_wizard_form_with_no_category_fallback_language(self): self.assertTrue(category_name) def test_create_alias_category_wizard_instance(self): - wizard = self._get_wizard_instance('CreateAliasCategoryWizard') - self.assertEqual(wizard.title, 'New alias category') + wizard = self._get_wizard_instance("CreateAliasCategoryWizard") + self.assertEqual(wizard.title, "New alias category") self.assertTrue(wizard.user_has_add_permission(self.superuser)) self.assertTrue( - wizard.user_has_add_permission(self.get_staff_user_with_alias_permissions()), # noqa: E501 + wizard.user_has_add_permission( + self.get_staff_user_with_alias_permissions() + ), # noqa: E501 ) self.assertFalse( wizard.user_has_add_permission(self.get_staff_user_with_no_permissions()), # noqa: E501 @@ -122,9 +126,9 @@ def test_create_alias_category_wizard_instance(self): ) def test_create_alias_category_wizard_form(self): - wizard = self._get_wizard_instance('CreateAliasCategoryWizard') + wizard = self._get_wizard_instance("CreateAliasCategoryWizard") data = { - 'name': 'Category 1', + "name": "Category 1", } form_class = step2_form_factory( @@ -138,4 +142,4 @@ def test_create_alias_category_wizard_form(self): with self.login_user_context(self.superuser): response = self.client.get(category.get_absolute_url()) - self.assertContains(response, data['name']) + self.assertContains(response, data["name"])