From 310c13d87b7ab56f0a22b4d1290889a1605b07e2 Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Thu, 14 Mar 2024 15:03:57 +0000 Subject: [PATCH 01/10] fix: fix check errors --- .github/workflows/lint.yml | 4 ++-- .github/workflows/test.yml | 3 +++ tests/requirements/dj42_cms40.txt | 4 ++-- tests/requirements/requirements_base.txt | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index fe6c95e4..5527c571 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -12,7 +12,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - name: Install flake8 run: pip install --upgrade flake8 - name: Run flake8 @@ -29,7 +29,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: 3.9 + python-version: '3.10' - run: python -m pip install isort - name: isort uses: liskin/gh-problem-matcher-wrap@v1 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 631cf808..fd4be451 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,6 +20,9 @@ jobs: os: [ ubuntu-20.04, ] + exclude: + - requirements-file: [dj32_cms40.txt, dj42_cms40.txt] + python-version: "3.12" #cms40 not support py3.12 yet steps: - uses: actions/checkout@v4 diff --git a/tests/requirements/dj42_cms40.txt b/tests/requirements/dj42_cms40.txt index a6826f4d..deb73e0f 100644 --- a/tests/requirements/dj42_cms40.txt +++ b/tests/requirements/dj42_cms40.txt @@ -6,6 +6,6 @@ django-admin-sortable2 django_polymorphic https://github.com/django-cms/django-cms/tarball/release/4.0.1.x#egg=django-cms -https://github.com/django-cms/djangocms-versioning/tarball/1.2.2#egg=djangocms-versioning -https://github.com/FidelityInternational/djangocms-version-locking/tarball/1.2.0#egg=djangocms-version-locking +https://github.com/django-cms/djangocms-versioning/tarball/support/django-cms-4.0.x#egg=djangocms-versioning +https://github.com/joshyu/djangocms-version-locking/tarball/feat/django-42-compatible#egg=djangocms-version-locking https://github.com/django-cms/djangocms-alias/tarball/support/django-cms-4.0.x#egg=djangocms-alias diff --git a/tests/requirements/requirements_base.txt b/tests/requirements/requirements_base.txt index 7f095b1f..3d7e24f8 100644 --- a/tests/requirements/requirements_base.txt +++ b/tests/requirements/requirements_base.txt @@ -1,6 +1,6 @@ cachetools coverage -django-classy-tags +django-classy-tags>=0.7.2 django-filer django-sekizai django-simple-captcha From 57ee74c0c70573588cecc9bb58d20216c757c60a Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Thu, 14 Mar 2024 15:09:30 +0000 Subject: [PATCH 02/10] fix: test.yml --- .github/workflows/test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fd4be451..a1104efb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,10 @@ jobs: ubuntu-20.04, ] exclude: - - requirements-file: [dj32_cms40.txt, dj42_cms40.txt] + - requirements-file: [ + dj32_cms40.txt, + dj42_cms40.txt + ] python-version: "3.12" #cms40 not support py3.12 yet steps: From a2d1fa2695c02c1ff462f3786be1aa8f2928b960 Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Thu, 14 Mar 2024 15:15:43 +0000 Subject: [PATCH 03/10] fix: test.yml 2 --- .github/workflows/test.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a1104efb..37217349 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,11 +21,10 @@ jobs: ubuntu-20.04, ] exclude: - - requirements-file: [ - dj32_cms40.txt, - dj42_cms40.txt - ] + - requirements-file: "dj42_cms40.txt" python-version: "3.12" #cms40 not support py3.12 yet + - requirements-file: "dj32_cms40.txt" + python-version: "3.12" steps: - uses: actions/checkout@v4 From 1c50da3c1629bbfd857077565488de4e7d2da287 Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Fri, 15 Mar 2024 01:22:42 +0000 Subject: [PATCH 04/10] fix: update pre-commit-config versions --- .pre-commit-config.yaml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bcd3de1a..accaa9e3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,38 +12,38 @@ repos: rev: v2.31.0 hooks: - id: pyupgrade - args: ["--py37-plus"] + args: ["--py310-plus"] - repo: https://github.com/adamchainz/django-upgrade rev: '1.4.0' hooks: - id: django-upgrade - args: [--target-version, "2.2"] + args: [--target-version, "4.2"] - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 7.0.0 hooks: - id: flake8 - repo: https://github.com/asottile/yesqa - rev: v1.3.0 + rev: v1.5.0 hooks: - id: yesqa - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.5.0 hooks: - id: check-merge-conflict - id: debug-statements - id: mixed-line-ending - id: trailing-whitespace - +# upgrade the isort version to fix compatiable issue withe peotry: https://stackoverflow.com/questions/75269700/pre-commit-fails-to-install-isort-5-11-4-with-error-runtimeerror-the-poetry-co - repo: https://github.com/pycqa/isort - rev: 5.10.1 + rev: 5.13.2 hooks: - id: isort - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.2.6 hooks: - id: codespell From ec35312eea0bee02ddc5ff10ace74e21715770d0 Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Fri, 15 Mar 2024 01:42:50 +0000 Subject: [PATCH 05/10] fix: update code styles using pre-commit run --- djangocms_moderation/admin.py | 2 +- djangocms_moderation/apps.py | 4 ++-- djangocms_moderation/backends.py | 2 +- djangocms_moderation/cms_toolbars.py | 4 ++-- djangocms_moderation/emails.py | 4 ++-- djangocms_moderation/handlers.py | 2 +- djangocms_moderation/helpers.py | 2 +- .../migrations/0001_initial.py | 6 +++--- .../migrations/0003_auto_20180903_1206.py | 2 +- .../migrations/0011_auto_20181008_1328.py | 2 +- djangocms_moderation/models.py | 10 +++++----- .../djangocms_moderation/css/actions.css | 10 +++++----- .../base_confirmation_build.html | 2 +- djangocms_moderation/utils.py | 2 +- docs/comment.rst | 2 +- docs/conf.py | 1 - docs/lock.rst | 6 +++--- docs/moderation_collection.rst | 12 +++++------ docs/overview.rst | 2 +- tests/test_admin_actions.py | 14 ++++++------- tests/test_app_registration.py | 2 +- tests/test_cms_toolbars.py | 6 +++--- tests/test_forms.py | 4 ++-- tests/test_helpers.py | 11 +++++----- tests/test_integration.py | 2 +- tests/test_models.py | 4 ++-- tests/test_moderation_flows.py | 2 +- tests/test_monkeypatch.py | 2 +- tests/test_views.py | 20 +++++++++---------- tests/utils/factories.py | 2 +- tests/utils/moderated_polls/models.py | 2 +- .../versioned_none_moderated_app/models.py | 2 +- 32 files changed, 74 insertions(+), 76 deletions(-) diff --git a/djangocms_moderation/admin.py b/djangocms_moderation/admin.py index a9f1ed5c..f9320fa2 100644 --- a/djangocms_moderation/admin.py +++ b/djangocms_moderation/admin.py @@ -93,7 +93,7 @@ def form_submission(self, obj): opts = ConfirmationFormSubmission._meta url = reverse( - "admin:{}_{}_change".format(opts.app_label, opts.model_name), + f"admin:{opts.app_label}_{opts.model_name}_change", args=[instance.pk], ) return format_html( diff --git a/djangocms_moderation/apps.py b/djangocms_moderation/apps.py index cbeed482..b2b7dbf1 100644 --- a/djangocms_moderation/apps.py +++ b/djangocms_moderation/apps.py @@ -7,6 +7,6 @@ class ModerationConfig(AppConfig): verbose_name = _("django CMS Moderation") def ready(self): - import djangocms_moderation.handlers # noqa: F401 - import djangocms_moderation.monkeypatch # noqa: F401 + import djangocms_moderation.handlers + import djangocms_moderation.monkeypatch import djangocms_moderation.signals # noqa: F401 diff --git a/djangocms_moderation/backends.py b/djangocms_moderation/backends.py index 416606c0..565e9390 100644 --- a/djangocms_moderation/backends.py +++ b/djangocms_moderation/backends.py @@ -20,4 +20,4 @@ def sequential_number_with_identifier_prefix_backend(**kwargs): semi-sequential numbers, prefixed with `workflow.identifier` field, if set """ moderation_request = kwargs["moderation_request"] - return "{}{}".format(moderation_request.workflow.identifier, moderation_request.pk) + return f"{moderation_request.workflow.identifier}{moderation_request.pk}" diff --git a/djangocms_moderation/cms_toolbars.py b/djangocms_moderation/cms_toolbars.py index 6181cfb7..7679807a 100644 --- a/djangocms_moderation/cms_toolbars.py +++ b/djangocms_moderation/cms_toolbars.py @@ -68,7 +68,7 @@ def _add_moderation_buttons(self): opts = ModerationRequest._meta codename = get_permission_codename("add", opts) if not self.request.user.has_perm( - "{app_label}.{codename}".format(app_label=opts.app_label, codename=codename) + f"{opts.app_label}.{codename}" ): return version = Version.objects.get_for_content(self.toolbar.obj) @@ -91,7 +91,7 @@ def _add_moderation_menu(self): opts = ModerationCollection._meta codename = get_permission_codename("change", opts) if not self.request.user.has_perm( - "{app_label}.{codename}".format(app_label=opts.app_label, codename=codename) + f"{opts.app_label}.{codename}" ): return admin_menu = self.toolbar.get_or_create_menu(ADMIN_MENU_IDENTIFIER) diff --git a/djangocms_moderation/emails.py b/djangocms_moderation/emails.py index 319a53e6..761c3b5b 100644 --- a/djangocms_moderation/emails.py +++ b/djangocms_moderation/emails.py @@ -35,7 +35,7 @@ def _send_email( "job_id": collection.job_id, "by_user": by_user, } - template = "djangocms_moderation/emails/moderation-request/{}".format(template) + template = f"djangocms_moderation/emails/moderation-request/{template}" # TODO What language should the email be sent in? e.g. `with force_language(lang):` subject = force_str(subject) @@ -61,7 +61,7 @@ def notify_collection_author(collection, moderation_requests, action, by_user): moderation_requests=moderation_requests, recipients=[collection.author.email], subject=email_subjects[action], - template="{}.txt".format(action), + template=f"{action}.txt", by_user=by_user, ) return status diff --git a/djangocms_moderation/handlers.py b/djangocms_moderation/handlers.py index 768ba335..50a9f9e4 100644 --- a/djangocms_moderation/handlers.py +++ b/djangocms_moderation/handlers.py @@ -11,7 +11,7 @@ def moderation_confirmation_form_submission( sender, page, language, user, form_data, **kwargs ): for field_data in form_data: - if not set(("label", "value")).issubset(field_data): + if not {"label", "value"}.issubset(field_data): raise ValueError("Each field dict should contain label and value keys.") # TODO Confirmation pages are not used/working in 1.0.x yet diff --git a/djangocms_moderation/helpers.py b/djangocms_moderation/helpers.py index b7fdcf03..d266f7cd 100644 --- a/djangocms_moderation/helpers.py +++ b/djangocms_moderation/helpers.py @@ -79,7 +79,7 @@ def get_active_moderation_request(content_object): If this returns None, it means there is no active_moderation request for this object, and it means it can be submitted for new moderation """ - from djangocms_moderation.models import ModerationRequest # noqa + from djangocms_moderation.models import ModerationRequest version = Version.objects.get_for_content(content_object) diff --git a/djangocms_moderation/migrations/0001_initial.py b/djangocms_moderation/migrations/0001_initial.py index b1464ba4..0efd9497 100644 --- a/djangocms_moderation/migrations/0001_initial.py +++ b/djangocms_moderation/migrations/0001_initial.py @@ -454,14 +454,14 @@ class Migration(migrations.Migration): ), ), migrations.AlterUniqueTogether( - name="workflowstep", unique_together=set([("role", "workflow")]) + name="workflowstep", unique_together={("role", "workflow")} ), migrations.AlterUniqueTogether( name="moderationrequest", - unique_together=set([("collection", "object_id", "content_type")]), + unique_together={("collection", "object_id", "content_type")}, ), migrations.AlterUniqueTogether( name="confirmationformsubmission", - unique_together=set([("request", "for_step")]), + unique_together={("request", "for_step")}, ), ] diff --git a/djangocms_moderation/migrations/0003_auto_20180903_1206.py b/djangocms_moderation/migrations/0003_auto_20180903_1206.py index 8bbc691c..46e11fa2 100644 --- a/djangocms_moderation/migrations/0003_auto_20180903_1206.py +++ b/djangocms_moderation/migrations/0003_auto_20180903_1206.py @@ -22,7 +22,7 @@ class Migration(migrations.Migration): preserve_default=False, ), migrations.AlterUniqueTogether( - name="moderationrequest", unique_together=set([("collection", "version")]) + name="moderationrequest", unique_together={("collection", "version")} ), migrations.RemoveField(model_name="moderationrequest", name="content_type"), migrations.RemoveField(model_name="moderationrequest", name="object_id"), diff --git a/djangocms_moderation/migrations/0011_auto_20181008_1328.py b/djangocms_moderation/migrations/0011_auto_20181008_1328.py index 23829d74..db52ec3a 100644 --- a/djangocms_moderation/migrations/0011_auto_20181008_1328.py +++ b/djangocms_moderation/migrations/0011_auto_20181008_1328.py @@ -13,7 +13,7 @@ class Migration(migrations.Migration): # AlterUniqueTogether needs to happen before removing field migrations.AlterUniqueTogether( name="confirmationformsubmission", - unique_together=set([("moderation_request", "for_step")]), + unique_together={("moderation_request", "for_step")}, ), migrations.RemoveField(model_name="confirmationformsubmission", name="request"), migrations.RemoveField(model_name="moderationrequestaction", name="request"), diff --git a/djangocms_moderation/models.py b/djangocms_moderation/models.py index 166daf58..1dbcc854 100644 --- a/djangocms_moderation/models.py +++ b/djangocms_moderation/models.py @@ -241,7 +241,7 @@ def __str__(self): @property def job_id(self): - return "{}".format(self.pk) + return f"{self.pk}" @property def author_name(self): @@ -445,7 +445,7 @@ class Meta: ordering = ["id"] def __str__(self): - return "{} {}".format(self.pk, self.version_id) + return f"{self.pk} {self.version_id}" @cached_property def workflow(self): @@ -652,7 +652,7 @@ class Meta: verbose_name_plural = _("Actions") def __str__(self): - return "{} - {}".format(self.moderation_request_id, self.get_action_display()) + return f"{self.moderation_request_id} - {self.get_action_display()}" def get_by_user_name(self): if not self.to_user: @@ -687,7 +687,7 @@ def save(self, **kwargs): if next_step: self.to_role_id = next_step.role_id - super(ModerationRequestAction, self).save(**kwargs) + super().save(**kwargs) class AbstractComment(models.Model): @@ -744,7 +744,7 @@ class ConfirmationFormSubmission(models.Model): ) def __str__(self): - return "{} - {}".format(self.request_id, self.for_step) + return f"{self.request_id} - {self.for_step}" class Meta: verbose_name = _("Confirmation Form Submission") diff --git a/djangocms_moderation/static/djangocms_moderation/css/actions.css b/djangocms_moderation/static/djangocms_moderation/css/actions.css index e86c02d9..d1c2c989 100644 --- a/djangocms_moderation/static/djangocms_moderation/css/actions.css +++ b/djangocms_moderation/static/djangocms_moderation/css/actions.css @@ -33,9 +33,9 @@ a.btn.cms-moderation-action-btn span { display: inline-block; } span.svg-juxtaposed-font { - text-rendering: auto; - display: inline-block; - line-height: 1rem; - vertical-align: 20%; - margin-top: -2px !important; + text-rendering: auto; + display: inline-block; + line-height: 1rem; + vertical-align: 20%; + margin-top: -2px !important; } \ No newline at end of file diff --git a/djangocms_moderation/templates/djangocms_moderation/base_confirmation_build.html b/djangocms_moderation/templates/djangocms_moderation/base_confirmation_build.html index 89b3eab2..cc55a8dd 100644 --- a/djangocms_moderation/templates/djangocms_moderation/base_confirmation_build.html +++ b/djangocms_moderation/templates/djangocms_moderation/base_confirmation_build.html @@ -16,7 +16,7 @@ {% block post_content %}{% endblock %} - + {% render_block "js" %} {% block extrajs %}{% endblock %} diff --git a/djangocms_moderation/utils.py b/djangocms_moderation/utils.py index 1f29c242..cc19722b 100644 --- a/djangocms_moderation/utils.py +++ b/djangocms_moderation/utils.py @@ -17,7 +17,7 @@ def get_absolute_url(location, site=None): scheme = "https" else: scheme = "http" - domain = "{}://{}".format(scheme, site.domain) + domain = f"{scheme}://{site.domain}" return urljoin(domain, location) diff --git a/docs/comment.rst b/docs/comment.rst index 8bdc8c25..d9959034 100644 --- a/docs/comment.rst +++ b/docs/comment.rst @@ -2,7 +2,7 @@ Comment ================================================ -Comments may be added to various moderation entities: +Comments may be added to various moderation entities: * :ref:`moderation_collection` * :ref:`moderation_request` * :ref:`moderation_request_action` \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index 1273cc40..6e6aa86e 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- # # Configuration file for the Sphinx documentation builder. # diff --git a/docs/lock.rst b/docs/lock.rst index 06e7a0b9..05553d0f 100644 --- a/docs/lock.rst +++ b/docs/lock.rst @@ -2,8 +2,8 @@ Moderation Review Lock ================================================ -As soon as a :ref:`moderation_collection` status becomes in review then its drafts are automatically locked, in the sense that their content can no longer be edited (not at all, not by anyone, not even the collection author). Also once a collection is in Review then content versions cannot be added to the collection. This means that once you’ve clicked “Submit for review”: +As soon as a :ref:`moderation_collection` status becomes in review then its drafts are automatically locked, in the sense that their content can no longer be edited (not at all, not by anyone, not even the collection author). Also once a collection is in Review then content versions cannot be added to the collection. This means that once you’ve clicked “Submit for review”: * Collection Lock: New drafts cannot be added to the :ref:`moderation_collection` * Version Lock: Drafts in the :ref:`moderation_collection` cannot be edited unless rejected - -Once a version is published the Moderation Version Lock is removed automatically. \ No newline at end of file + +Once a version is published the Moderation Version Lock is removed automatically. \ No newline at end of file diff --git a/docs/moderation_collection.rst b/docs/moderation_collection.rst index cdddf4fc..4a3cc12a 100644 --- a/docs/moderation_collection.rst +++ b/docs/moderation_collection.rst @@ -3,10 +3,10 @@ Moderation Collection ================================================ -A Moderation Collection is primarily intended as a way of being able to group draft content versions together for: -a) review and +A Moderation Collection is primarily intended as a way of being able to group draft content versions together for: +a) review and b) publishing - + The rules for adding items to a Collection, removing items from a Collection and the actions that can be taken on items the Collection may vary by :ref:`workflow`. Publishing is a `djangocms-versioning` feature, thus `djangocms-moderation` depends on and extends the functionality made available by the Versioning addon. @@ -16,7 +16,7 @@ Collections are stateful. The available states are: * In review * Archived * Cancelled - + Drafts can only be added to a Collection during the `Collecting` phase (see :ref:`lock`) Buttons @@ -76,7 +76,7 @@ A collection can also be flagged as cancelled. This is similar to Archived excep Bulk Actions ------------------------------------------------- -These will appear in the Collection’s action drop-down for each content-type registered with Moderation. +These will appear in the Collection’s action drop-down for each content-type registered with Moderation. Remove from collection ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -92,4 +92,4 @@ Flags a draft as being in need of further editing Submit for review ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -Useful for items that have been flagged for rework - resubmits them for review, sending out notifications again. +Useful for items that have been flagged for rework - resubmits them for review, sending out notifications again. diff --git a/docs/overview.rst b/docs/overview.rst index 57207d65..806bfec9 100644 --- a/docs/overview.rst +++ b/docs/overview.rst @@ -5,7 +5,7 @@ Overview Moderation provides an approval workflow mechanism for organisations who need to ensure that content is approved before it is published. It is designed to extend and compliment the Versioning addon and has that as a dependency. -The general idea is that a draft version can be submitted for moderation. This involves adding that draft to a :ref:`moderation_collection`, which can be thought of as a chapter, edition or batch of content that aims to all be published simultaneously. Various drafts can be added to the same :ref:`moderation_collection`. +The general idea is that a draft version can be submitted for moderation. This involves adding that draft to a :ref:`moderation_collection`, which can be thought of as a chapter, edition or batch of content that aims to all be published simultaneously. Various drafts can be added to the same :ref:`moderation_collection`. Drafts within the :ref:`moderation_collection` can then be approved rejected by various parties according to :ref:`role`s defined within the :ref:`workflow` assigned to the :ref:`moderation_collection`. diff --git a/tests/test_admin_actions.py b/tests/test_admin_actions.py index b0c3fbd8..c026b84d 100644 --- a/tests/test_admin_actions.py +++ b/tests/test_admin_actions.py @@ -1,5 +1,5 @@ -import mock import unittest +from unittest import mock from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME from django.contrib.auth.models import Group @@ -66,7 +66,7 @@ def setUp(self): # Set up the url data self.url = reverse("admin:djangocms_moderation_moderationrequesttreenode_changelist") - self.url += "?moderation_request__collection__id={}".format(self.collection.pk) + self.url += f"?moderation_request__collection__id={self.collection.pk}" # Asserts to check data set up is ok. Ideally wouldn't need them, but # the set up is so complex that it's safer to have them. @@ -409,7 +409,7 @@ def setUp(self): # Set up the url data self.url = reverse("admin:djangocms_moderation_moderationrequesttreenode_changelist") - self.url += "?moderation_request__collection__id={}".format(self.collection.pk) + self.url += f"?moderation_request__collection__id={self.collection.pk}" # Asserts to check data set up is ok. Ideally wouldn't need them, but # the set up is so complex that it's safer to have them. @@ -586,7 +586,7 @@ def setUp(self): # Set up the url data self.url = reverse("admin:djangocms_moderation_moderationrequesttreenode_changelist") - self.url += "?moderation_request__collection__id={}".format(self.collection.pk) + self.url += f"?moderation_request__collection__id={self.collection.pk}" # Asserts to check data set up is ok. Ideally wouldn't need them, but # the set up is so complex that it's safer to have them. @@ -813,7 +813,7 @@ def setUp(self): self.client.force_login(self.user) self.url = reverse("admin:djangocms_moderation_moderationrequesttreenode_changelist") - self.url += "?moderation_request__collection__id={}".format(self.collection.pk) + self.url += f"?moderation_request__collection__id={self.collection.pk}" # Asserts to check data set up is ok. Ideally wouldn't need them, but # the set up is so complex that it's safer to have them. @@ -963,7 +963,7 @@ def setUp(self): id=6, moderation_request=self.moderation_request2) self.url = reverse("admin:djangocms_moderation_moderationrequesttreenode_changelist") - self.url += "?moderation_request__collection__id={}".format(self.collection.pk) + self.url += f"?moderation_request__collection__id={self.collection.pk}" @mock.patch.object(ModerationRequestTreeAdmin, "has_delete_permission", mock.Mock(return_value=True)) def test_delete_selected_action_cannot_be_accessed_if_not_collection_author(self): @@ -1112,7 +1112,7 @@ def setUp(self): # Generate url and POST data self.url = reverse("admin:djangocms_moderation_moderationrequesttreenode_changelist") - self.url += "?moderation_request__collection__id={}".format(self.collection.pk) + self.url += f"?moderation_request__collection__id={self.collection.pk}" self.data = get_url_data(self, "delete_selected") def tearDown(self): diff --git a/tests/test_app_registration.py b/tests/test_app_registration.py index 1b2423dc..eb28f94a 100644 --- a/tests/test_app_registration.py +++ b/tests/test_app_registration.py @@ -1,7 +1,7 @@ try: from unittest.mock import Mock except ImportError: - from mock import Mock + from unittest.mock import Mock from unittest import TestCase, skip from unittest.mock import patch diff --git a/tests/test_cms_toolbars.py b/tests/test_cms_toolbars.py index 18b8bcbf..7b539ae8 100644 --- a/tests/test_cms_toolbars.py +++ b/tests/test_cms_toolbars.py @@ -1,4 +1,4 @@ -import mock +from unittest import mock from django.contrib.auth.models import Permission, User from django.test.client import RequestFactory @@ -141,7 +141,7 @@ def test_page_in_collection_collection(self): self.assertTrue( self._button_exists( - 'In collection "{} ({})"'.format(collection.name, collection.id), + f'In collection "{collection.name} ({collection.id})"', toolbar.toolbar, ) ) @@ -159,7 +159,7 @@ def test_page_in_collection_moderating(self): self.assertTrue( self._button_exists( - 'In moderation "{} ({})"'.format(collection.name, collection.id), + f'In moderation "{collection.name} ({collection.id})"', toolbar.toolbar, ) ) diff --git a/tests/test_forms.py b/tests/test_forms.py index 571e591f..4439508a 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -1,4 +1,4 @@ -import mock +from unittest import mock from django.contrib.auth.models import User from django.forms import HiddenInput @@ -248,7 +248,7 @@ def test_collection_choice_should_be_limited_to_current_user_and_collecting_stat form = CollectionItemsForm(data=data, user=user) self.assertEqual( - form.is_valid(), fixture[1], "{} failed".format(fixture[0]) + form.is_valid(), fixture[1], f"{fixture[0]} failed" ) if not form.is_valid(): self.assertIn("collection", form.errors) diff --git a/tests/test_helpers.py b/tests/test_helpers.py index ebdacf10..40cc4777 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -1,6 +1,5 @@ import json -import mock -from unittest import skip +from unittest import mock, skip from django.template.defaultfilters import truncatechars from django.urls import reverse @@ -115,7 +114,7 @@ def setUp(self): def test_get_moderation_button_title_and_url_when_collection(self): title, url = get_moderation_button_title_and_url(self.mr) - self.assertEqual(title, 'In collection "C1 ({})"'.format(self.collection.id)) + self.assertEqual(title, f'In collection "C1 ({self.collection.id})"') self.assertEqual(url, self.expected_url) def test_get_moderation_button_title_and_url_when_in_review(self): @@ -123,7 +122,7 @@ def test_get_moderation_button_title_and_url_when_in_review(self): self.collection.save() title, url = get_moderation_button_title_and_url(self.mr) - self.assertEqual(title, 'In moderation "C1 ({})"'.format(self.collection.id)) + self.assertEqual(title, f'In moderation "C1 ({self.collection.id})"') self.assertEqual(url, self.expected_url) def test_get_moderation_button_truncated_title_and_url(self): @@ -135,7 +134,7 @@ def test_get_moderation_button_truncated_title_and_url(self): self.assertEqual( title, # By default, truncate will shorten the name - 'In collection "{} ({})"'.format(expected_title, self.collection.id), + f'In collection "{expected_title} ({self.collection.id})"', ) with mock.patch("djangocms_moderation.helpers.COLLECTION_NAME_LENGTH_LIMIT", 3): title, url = get_moderation_button_title_and_url(self.mr) @@ -143,7 +142,7 @@ def test_get_moderation_button_truncated_title_and_url(self): self.assertEqual( title, # As the limit is only 3, the truncate will produce `...` - 'In collection "{} ({})"'.format(expected_title, self.collection.id), + f'In collection "{expected_title} ({self.collection.id})"', ) with mock.patch( diff --git a/tests/test_integration.py b/tests/test_integration.py index c0d1b01f..9110714e 100644 --- a/tests/test_integration.py +++ b/tests/test_integration.py @@ -1,4 +1,4 @@ -import mock +from unittest import mock from djangocms_versioning.test_utils.factories import PageVersionFactory diff --git a/tests/test_models.py b/tests/test_models.py index b00b6bfa..53d48d5d 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -1,5 +1,5 @@ import json -from mock import patch +from unittest.mock import patch from django.contrib.auth.models import Permission, User from django.core.exceptions import ValidationError @@ -390,7 +390,7 @@ def test_compliance_number_sequential_number_with_identifier_prefix_backend(self request.refresh_from_db() self.assertIsNone(request.compliance_number) - expected = "SSO{}".format(request.pk) + expected = f"SSO{request.pk}" request.set_compliance_number() request.refresh_from_db() self.assertEqual(request.compliance_number, expected) diff --git a/tests/test_moderation_flows.py b/tests/test_moderation_flows.py index 0531e02e..41fe54d1 100644 --- a/tests/test_moderation_flows.py +++ b/tests/test_moderation_flows.py @@ -53,7 +53,7 @@ def _process_moderation_request(self, user, action, message="Test message"): self.client.force_login(user) response = self.client.post( get_admin_url( - name="cms_moderation_{}_request".format(action), + name=f"cms_moderation_{action}_request", language="en", args=(self.page.pk, "en"), ), diff --git a/tests/test_monkeypatch.py b/tests/test_monkeypatch.py index c6c512ed..3817b0b6 100644 --- a/tests/test_monkeypatch.py +++ b/tests/test_monkeypatch.py @@ -1,4 +1,4 @@ -import mock +from unittest import mock from django.contrib import admin from django.urls import reverse diff --git a/tests/test_views.py b/tests/test_views.py index b7ecee19..bfbd24f5 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -1,4 +1,4 @@ -import mock +from unittest import mock from django.contrib.admin.widgets import RelatedFieldWidgetWrapper from django.contrib.messages import get_messages @@ -629,7 +629,7 @@ def test_initial_form_values_when_collection_id_passed(self): pg_version = PageVersionFactory() poll_version = PollVersionFactory() self.url += "?collection_id=" + str(collection.pk) - self.url += "&version_ids={},{}".format(pg_version.pk, poll_version.pk) + self.url += f"&version_ids={pg_version.pk},{poll_version.pk}" response = self.client.get(self.url) @@ -648,7 +648,7 @@ def test_initial_form_values_when_collection_id_passed(self): def test_initial_form_values_when_collection_id_not_passed(self): pg_version = PageVersionFactory() poll_version = PollVersionFactory() - self.url += "?version_ids={},{}".format(pg_version.pk, poll_version.pk) + self.url += f"?version_ids={pg_version.pk},{poll_version.pk}" response = self.client.get(self.url) @@ -774,7 +774,7 @@ def test_tree_nodes_are_created(self): class SubmitCollectionForModerationViewTest(BaseViewTestCase): def setUp(self): - super(SubmitCollectionForModerationViewTest, self).setUp() + super().setUp() self.url = reverse( "admin:cms_moderation_submit_collection_for_moderation", args=(self.collection2.pk,), @@ -820,7 +820,7 @@ def test_submit_collection_for_moderation(self, cancel_mock): class ModerationRequestChangeListView(BaseViewTestCase): def setUp(self): - super(ModerationRequestChangeListView, self).setUp() + super().setUp() self.collection_submit_url = reverse( "admin:cms_moderation_submit_collection_for_moderation", args=(self.collection2.pk,), @@ -1038,7 +1038,7 @@ def test_moderation_workflow_node_deletion_1(self): # Load the changelist and check that the page loads without an error changelist_url = reverse('admin:djangocms_moderation_moderationrequesttreenode_changelist') - changelist_url += "?moderation_request__collection__id={}".format(self.collection.pk) + changelist_url += f"?moderation_request__collection__id={self.collection.pk}" response = self.client.get(changelist_url) self.assertEqual(response.status_code, 200) @@ -1093,7 +1093,7 @@ def test_moderation_workflow_node_deletion_2(self): # Load the changelist and check that the page loads without an error changelist_url = reverse('admin:djangocms_moderation_moderationrequesttreenode_changelist') - changelist_url += "?moderation_request__collection__id={}".format(self.collection.pk) + changelist_url += f"?moderation_request__collection__id={self.collection.pk}" response = self.client.get(changelist_url) self.assertEqual(response.status_code, 200) @@ -1149,7 +1149,7 @@ def test_moderation_workflow_node_deletion_3(self): # Load the changelist and check that the page loads without an error changelist_url = reverse('admin:djangocms_moderation_moderationrequesttreenode_changelist') - changelist_url += "?moderation_request__collection__id={}".format(self.collection.pk) + changelist_url += f"?moderation_request__collection__id={self.collection.pk}" response = self.client.get(changelist_url) self.assertEqual(response.status_code, 200) @@ -1209,7 +1209,7 @@ def test_moderation_workflow_node_deletion_4(self): # Load the changelist and check that the page loads without an error changelist_url = reverse('admin:djangocms_moderation_moderationrequesttreenode_changelist') - changelist_url += "?moderation_request__collection__id={}".format(self.collection.pk) + changelist_url += f"?moderation_request__collection__id={self.collection.pk}" response = self.client.get(changelist_url) self.assertEqual(response.status_code, 200) @@ -1268,7 +1268,7 @@ def test_moderation_workflow_node_deletion_5(self): # Load the changelist and check that the page loads without an error changelist_url = reverse('admin:djangocms_moderation_moderationrequesttreenode_changelist') - changelist_url += "?moderation_request__collection__id={}".format(self.collection.pk) + changelist_url += f"?moderation_request__collection__id={self.collection.pk}" response = self.client.get(changelist_url) self.assertEqual(response.status_code, 200) diff --git a/tests/utils/factories.py b/tests/utils/factories.py index 811f0955..2c9c442b 100644 --- a/tests/utils/factories.py +++ b/tests/utils/factories.py @@ -134,7 +134,7 @@ class UserFactory(DjangoModelFactory): first_name = factory.Faker("first_name") last_name = factory.Faker("last_name") email = factory.LazyAttribute( - lambda u: "%s.%s@example.com" % (u.first_name.lower(), u.last_name.lower()) + lambda u: f"{u.first_name.lower()}.{u.last_name.lower()}@example.com" ) class Meta: diff --git a/tests/utils/moderated_polls/models.py b/tests/utils/moderated_polls/models.py index 81147b54..eb0785ba 100644 --- a/tests/utils/moderated_polls/models.py +++ b/tests/utils/moderated_polls/models.py @@ -10,7 +10,7 @@ class Poll(models.Model): name = models.TextField() def __str__(self): - return "{} ({})".format(self.name, self.pk) + return f"{self.name} ({self.pk})" class PollContent(models.Model): diff --git a/tests/utils/versioned_none_moderated_app/models.py b/tests/utils/versioned_none_moderated_app/models.py index 674ff192..dafffb62 100644 --- a/tests/utils/versioned_none_moderated_app/models.py +++ b/tests/utils/versioned_none_moderated_app/models.py @@ -9,7 +9,7 @@ class NoneModeratedPoll(models.Model): name = models.TextField() def __str__(self): - return "{} ({})".format(self.name, self.pk) + return f"{self.name} ({self.pk})" class NoneModeratedPollContent(models.Model): From 3a3dd395405911954ce494a63b2145d90fb43789 Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Fri, 15 Mar 2024 06:24:11 +0000 Subject: [PATCH 06/10] fix: test_views.py --- tests/test_views.py | 414 ++++++++++++++++++++++++++++---------------- 1 file changed, 262 insertions(+), 152 deletions(-) diff --git a/tests/test_views.py b/tests/test_views.py index bfbd24f5..984d9f08 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -5,6 +5,7 @@ from django.test import TransactionTestCase from django.urls import reverse +from cms import __version__ as cms_version from cms.test_utils.testcases import CMSTestCase from cms.utils.urlutils import add_url_parameters, admin_reverse @@ -237,7 +238,11 @@ def test_add_pages_moderated_children_to_collection(self): self.assertEqual(302, response.status_code) self.assertEqual(admin_endpoint, response.url) - self.assertEqual(stored_collection.count(), 3) + if cms_version < "4.1.0": + #version-locking override `_add_nested_children` add locked state checking + self.assertEqual(stored_collection.count(), 1) + else: + self.assertEqual(stored_collection.count(), 3) mr = ModerationRequest.objects.filter( collection=collection, version=page_version ) @@ -248,17 +253,24 @@ def test_add_pages_moderated_children_to_collection(self): mr1 = ModerationRequest.objects.filter( collection=collection, version=poll1_version ) - self.assertEqual(mr1.count(), 1) - self.assertEqual( - ModerationRequestTreeNode.objects.filter(moderation_request=mr1.first()).count(), 1 - ) mr2 = ModerationRequest.objects.filter( collection=collection, version=poll2_version ) - self.assertEqual(mr2.count(), 1) - self.assertEqual( - ModerationRequestTreeNode.objects.filter(moderation_request=mr2.first()).count(), 1 - ) + + if cms_version < "4.1.0": + #version-locking override `_add_nested_children` add locked state checking + #poll1_version is locked, so will not be added to collection + self.assertEqual(mr1.count(), 0) + self.assertEqual(mr2.count(), 0) + else: + self.assertEqual(mr1.count(), 1) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request=mr1.first()).count(), 1 + ) + self.assertEqual(mr2.count(), 1) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request=mr2.first()).count(), 1 + ) def test_add_pages_moderated_duplicated_children_to_collection(self): """ @@ -303,13 +315,19 @@ def test_add_pages_moderated_duplicated_children_to_collection(self): ).count(), 1, ) - self.assertEqual(stored_collection.filter(version=poll_version).count(), 1) - self.assertEqual( - ModerationRequestTreeNode.objects.filter( - moderation_request=stored_collection.get(version=poll_version) - ).count(), - 1, - ) + mr = stored_collection.filter(version=poll_version) + if cms_version < "4.1.0": + #version-locking override `_add_nested_children` add locked state checking + #poll1_version is locked, so will not be added to collection + self.assertEqual(mr.count(), 0) + else: + self.assertEqual(mr.count(), 1) + self.assertEqual( + ModerationRequestTreeNode.objects.filter( + moderation_request=stored_collection.get(version=poll_version) + ).count(), + 1, + ) def test_add_pages_moderated_duplicated_children_to_collection_for_author_only( self @@ -349,7 +367,12 @@ def test_add_pages_moderated_duplicated_children_to_collection_for_author_only( self.assertEqual(302, response.status_code) self.assertEqual(admin_endpoint, response.url) - self.assertEqual(stored_collection.count(), 2) + if cms_version < "4.1.0": + #version-locking override `_add_nested_children` add locked state checking + self.assertEqual(stored_collection.count(), 1) + else: + self.assertEqual(stored_collection.count(), 2) + self.assertEqual(stored_collection.filter(version=page_version).count(), 1) self.assertEqual( ModerationRequestTreeNode.objects.filter( @@ -357,13 +380,20 @@ def test_add_pages_moderated_duplicated_children_to_collection_for_author_only( ).count(), 1, ) - self.assertEqual(stored_collection.filter(version=poll1_version).count(), 1) - self.assertEqual( - ModerationRequestTreeNode.objects.filter( - moderation_request=stored_collection.get(version=poll1_version) - ).count(), - 1, - ) + mr1 = stored_collection.filter(version=poll1_version) + if cms_version < "4.1.0": + #version-locking override `_add_nested_children` add locked state checking + #poll1_version is locked, so will not be added to collection + self.assertEqual(mr1.count(), 0) + else: + self.assertEqual(mr1.count(), 1) + self.assertEqual( + ModerationRequestTreeNode.objects.filter( + moderation_request=stored_collection.get(version=poll1_version) + ).count(), + 1, + ) + self.assertEqual(stored_collection.filter(version=poll2_version).count(), 0) self.assertEqual( ModerationRequestTreeNode.objects.filter( @@ -423,7 +453,12 @@ def test_add_pages_moderated_traversed_children_to_collection(self): self.assertEqual(302, response.status_code) self.assertEqual(admin_endpoint, response.url) - self.assertEqual(stored_collection.count(), 4) + if cms_version < "4.1.0": + #version-locking override `_add_nested_children` add locked state checking + self.assertEqual(stored_collection.count(), 1) + else: + self.assertEqual(stored_collection.count(), 4) + self.assertEqual(stored_collection.filter(version=page_version).count(), 1) self.assertEqual( ModerationRequestTreeNode.objects.filter( @@ -431,31 +466,44 @@ def test_add_pages_moderated_traversed_children_to_collection(self): ).count(), 1, ) - self.assertEqual(stored_collection.filter(version=poll_version).count(), 1) - self.assertEqual( - ModerationRequestTreeNode.objects.filter( - moderation_request=stored_collection.get(version=poll_version) - ).count(), - 1, - ) - self.assertEqual( - stored_collection.filter(version=poll_child_1_version).count(), 1 - ) - self.assertEqual( - ModerationRequestTreeNode.objects.filter( - moderation_request=stored_collection.get(version=poll_child_1_version) - ).count(), - 1, - ) - self.assertEqual( - stored_collection.filter(version=poll_child_2_version).count(), 1 - ) - self.assertEqual( - ModerationRequestTreeNode.objects.filter( - moderation_request=stored_collection.get(version=poll_child_2_version) - ).count(), - 1, - ) + + mr = stored_collection.filter(version=poll_version) + if cms_version < "4.1.0": + #version-locking override `_add_nested_children` add locked state checking + #poll1_version is locked, so will not be added to collection + self.assertEqual(mr.count(), 0) + self.assertEqual( + stored_collection.filter(version=poll_child_1_version).count(), 0 + ) + self.assertEqual( + stored_collection.filter(version=poll_child_2_version).count(), 0 + ) + else: + self.assertEqual(mr.count(), 1) + self.assertEqual( + ModerationRequestTreeNode.objects.filter( + moderation_request=stored_collection.get(version=poll_version) + ).count(), + 1, + ) + self.assertEqual( + stored_collection.filter(version=poll_child_1_version).count(), 1 + ) + self.assertEqual( + ModerationRequestTreeNode.objects.filter( + moderation_request=stored_collection.get(version=poll_child_1_version) + ).count(), + 1, + ) + self.assertEqual( + stored_collection.filter(version=poll_child_2_version).count(), 1 + ) + self.assertEqual( + ModerationRequestTreeNode.objects.filter( + moderation_request=stored_collection.get(version=poll_child_2_version) + ).count(), + 1, + ) def test_adding_non_page_item_doesnt_trigger_nested_collection_mechanism(self): user = self.get_superuser() @@ -748,28 +796,34 @@ def test_tree_nodes_are_created(self): ) # The correct amount of nodes exist - self.assertEqual(nodes.count(), 6) + if cms_version < "4.1.0": + self.assertEqual(nodes.count(), 1) + else: + self.assertEqual(nodes.count(), 6) # Now assert the tree structure... # Check root refers to correct version & has correct number of children root = ModerationRequestTreeNode.get_root_nodes().get() self.assertEqual(root.moderation_request.version, page_version) - self.assertEqual(root.get_children().count(), 2) - # Check first child of root has correct tree - poll_node = root.get_children().get(moderation_request__version=poll_version) - self.assertEqual(poll_node.get_children().count(), 1) - poll_child_node = poll_node.get_children().get() - self.assertEqual(poll_child_node.moderation_request.version, poll_child_version) - self.assertEqual(poll_child_node.get_children().count(), 1) - poll_grandchild_node = poll_child_node.get_children().get() - self.assertEqual(poll_grandchild_node.moderation_request.version, poll_grandchild_version) - # Check second child of root has correct tree - poll_child_node2 = root.get_children().get(moderation_request__version=poll_child_version) - self.assertNotEqual(poll_child_node, poll_child_node2) - self.assertEqual(poll_child_node2.moderation_request.version, poll_child_version) - self.assertEqual(poll_child_node2.get_children().count(), 1) - poll_grandchild_node2 = poll_child_node2.get_children().get() - self.assertNotEqual(poll_grandchild_node, poll_grandchild_node2) - self.assertEqual(poll_grandchild_node2.moderation_request.version, poll_grandchild_version) + if cms_version < "4.1.0": + self.assertEqual(root.get_children().count(), 0) + else: + self.assertEqual(root.get_children().count(), 2) + # Check first child of root has correct tree + poll_node = root.get_children().get(moderation_request__version=poll_version) + self.assertEqual(poll_node.get_children().count(), 1) + poll_child_node = poll_node.get_children().get() + self.assertEqual(poll_child_node.moderation_request.version, poll_child_version) + self.assertEqual(poll_child_node.get_children().count(), 1) + poll_grandchild_node = poll_child_node.get_children().get() + self.assertEqual(poll_grandchild_node.moderation_request.version, poll_grandchild_version) + # Check second child of root has correct tree + poll_child_node2 = root.get_children().get(moderation_request__version=poll_child_version) + self.assertNotEqual(poll_child_node, poll_child_node2) + self.assertEqual(poll_child_node2.moderation_request.version, poll_child_version) + self.assertEqual(poll_child_node2.get_children().count(), 1) + poll_grandchild_node2 = poll_child_node2.get_children().get() + self.assertNotEqual(poll_grandchild_node, poll_grandchild_node2) + self.assertEqual(poll_grandchild_node2.moderation_request.version, poll_grandchild_version) class SubmitCollectionForModerationViewTest(BaseViewTestCase): @@ -976,33 +1030,42 @@ def _add_pages_to_collection(self): self.assertEqual(302, response.status_code) self.assertEqual(admin_endpoint, response.url) # The correct amount of moderation requests has been created - self.assertEqual( - ModerationRequest.objects.filter(collection=self.collection).count(), - 4 - ) - # The correct amount of tree nodes has been created - # Poll is repeated twice and will therefore have an additional node - self.assertEqual( - ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), - 5 - ) + mr = ModerationRequest.objects.filter(collection=self.collection) # The tree structure for page_1_version is correct - root_1 = ModerationRequestTreeNode.get_root_nodes().get( - moderation_request__version=self.page_1_version) - self.assertEqual(root_1.get_children().count(), 1) - child_1 = root_1.get_children().get() - self.assertEqual(child_1.moderation_request.version, self.poll_version) - self.assertEqual(child_1.get_children().count(), 1) - grandchild = child_1.get_children().get() - self.assertEqual( - grandchild.moderation_request.version, self.poll_child_version) - # The tree structure for page_2_version is correct - root_2 = ModerationRequestTreeNode.get_root_nodes().get( - moderation_request__version=self.page_2_version) - self.assertEqual(root_2.get_children().count(), 1) - child_2 = root_2.get_children().get() - self.assertEqual(child_2.moderation_request.version, self.poll_child_version) - self.assertEqual(grandchild.moderation_request, child_2.moderation_request) + root_1 = ModerationRequestTreeNode.get_root_nodes().get(moderation_request__version=self.page_1_version) + if cms_version < "4.1.0": + #version-locking override `_add_nested_children` add locked state checking + self.assertEqual(mr.count(), 2) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), + 2 + ) + self.assertEqual(root_1.get_children().count(), 0) + + else: + self.assertEqual(mr.count(), 4) + # The correct amount of tree nodes has been created + # Poll is repeated twice and will therefore have an additional node + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), + 5 + ) + self.assertEqual(root_1.get_children().count(), 1) + + child_1 = root_1.get_children().get() + self.assertEqual(child_1.moderation_request.version, self.poll_version) + self.assertEqual(child_1.get_children().count(), 1) + grandchild = child_1.get_children().get() + self.assertEqual( + grandchild.moderation_request.version, self.poll_child_version) + + # The tree structure for page_2_version is correct + root_2 = ModerationRequestTreeNode.get_root_nodes().get( + moderation_request__version=self.page_2_version) + self.assertEqual(root_2.get_children().count(), 1) + child_2 = root_2.get_children().get() + self.assertEqual(child_2.moderation_request.version, self.poll_child_version) + self.assertEqual(grandchild.moderation_request, child_2.moderation_request) def test_moderation_workflow_node_deletion_1(self): """ @@ -1046,19 +1109,33 @@ def test_moderation_workflow_node_deletion_1(self): # The whole of the page_2_version tree should have been removed. # Additionally, poll_child_version should have been removed from # the page_1_version tree. - self.assertEqual( - ModerationRequest.objects.filter(collection=self.collection).count(), - 2 - ) - self.assertEqual( - ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), - 2 - ) - self.assertEqual(ModerationRequestTreeNode.get_root_nodes().count(), 1) - root = ModerationRequestTreeNode.get_root_nodes().get() - self.assertEqual(root.moderation_request.version, self.page_1_version) - self.assertEqual(root.get_children().count(), 1) - self.assertEqual(root.get_children().get().moderation_request.version, self.poll_version) + if cms_version < "4.1.0": + self.assertEqual( + ModerationRequest.objects.filter(collection=self.collection).count(), + 1 + ) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), + 1 + ) + self.assertEqual(ModerationRequestTreeNode.get_root_nodes().count(), 1) + root = ModerationRequestTreeNode.get_root_nodes().get() + self.assertEqual(root.moderation_request.version, self.page_1_version) + self.assertEqual(root.get_children().count(), 0) + else: + self.assertEqual( + ModerationRequest.objects.filter(collection=self.collection).count(), + 2 + ) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), + 2 + ) + self.assertEqual(ModerationRequestTreeNode.get_root_nodes().count(), 1) + root = ModerationRequestTreeNode.get_root_nodes().get() + self.assertEqual(root.moderation_request.version, self.page_1_version) + self.assertEqual(root.get_children().count(), 1) + self.assertEqual(root.get_children().get().moderation_request.version, self.poll_version) def test_moderation_workflow_node_deletion_2(self): """ @@ -1138,14 +1215,16 @@ def test_moderation_workflow_node_deletion_3(self): # Now remove poll_version from the collection page_1_root = ModerationRequestTreeNode.get_root_nodes().get( moderation_request__version=self.page_1_version) - poll_1_node = page_1_root.get_children().get() - delete_url = "{}?ids={}&collection_id={}".format( - reverse('admin:djangocms_moderation_moderationrequesttreenode_delete'), - ",".join([str(poll_1_node.pk)]), - self.collection.pk, - ) - response = self.client.post(delete_url, follow=True) - self.assertEqual(response.status_code, 200) + page_1_root_children = page_1_root.get_children() + if page_1_root_children.count() > 0: + poll_1_node = page_1_root_children.get() + delete_url = "{}?ids={}&collection_id={}".format( + reverse('admin:djangocms_moderation_moderationrequesttreenode_delete'), + ",".join([str(poll_1_node.pk)]), + self.collection.pk, + ) + response = self.client.post(delete_url, follow=True) + self.assertEqual(response.status_code, 200) # Load the changelist and check that the page loads without an error changelist_url = reverse('admin:djangocms_moderation_moderationrequesttreenode_changelist') @@ -1198,14 +1277,16 @@ def test_moderation_workflow_node_deletion_4(self): # Now remove poll_version from the collection page_1_root = ModerationRequestTreeNode.get_root_nodes().get( moderation_request__version=self.page_1_version) - poll_grandchild_node = page_1_root.get_children().get().get_children().get() - delete_url = "{}?ids={}&collection_id={}".format( - reverse('admin:djangocms_moderation_moderationrequesttreenode_delete'), - ",".join([str(poll_grandchild_node.pk)]), - self.collection.pk, - ) - response = self.client.post(delete_url, follow=True) - self.assertEqual(response.status_code, 200) + page_1_root_children = page_1_root.get_children() + if page_1_root_children.count() > 0: + poll_grandchild_node = page_1_root_children.get().get_children().get() + delete_url = "{}?ids={}&collection_id={}".format( + reverse('admin:djangocms_moderation_moderationrequesttreenode_delete'), + ",".join([str(poll_grandchild_node.pk)]), + self.collection.pk, + ) + response = self.client.post(delete_url, follow=True) + self.assertEqual(response.status_code, 200) # Load the changelist and check that the page loads without an error changelist_url = reverse('admin:djangocms_moderation_moderationrequesttreenode_changelist') @@ -1215,22 +1296,34 @@ def test_moderation_workflow_node_deletion_4(self): # Check the data # Only the roots (page_1_version and page_2_version) should remain - self.assertEqual( - ModerationRequest.objects.filter(collection=self.collection).count(), - 3 - ) - self.assertEqual( - ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), - 3 - ) + if cms_version < "4.1.0": + self.assertEqual( + ModerationRequest.objects.filter(collection=self.collection).count(), + 2 + ) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), + 2 + ) + else: + self.assertEqual( + ModerationRequest.objects.filter(collection=self.collection).count(), + 3 + ) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), + 3 + ) self.assertEqual(ModerationRequestTreeNode.get_root_nodes().count(), 2) root_1 = ModerationRequestTreeNode.get_root_nodes().filter( moderation_request__version=self.page_1_version).get() root_2 = ModerationRequestTreeNode.get_root_nodes().filter( moderation_request__version=self.page_2_version).get() - self.assertEqual(root_1.get_children().count(), 1) + if cms_version < "4.1.0": + self.assertEqual(root_1.get_children().count(), 0) + else: + self.assertEqual(root_1.get_children().count(), 1) self.assertEqual(root_2.get_children().count(), 0) - self.assertEqual(root_1.get_children().get().moderation_request.version, self.poll_version) def test_moderation_workflow_node_deletion_5(self): """ @@ -1257,14 +1350,16 @@ def test_moderation_workflow_node_deletion_5(self): # Now remove poll_version from the collection page_2_root = ModerationRequestTreeNode.get_root_nodes().get( moderation_request__version=self.page_2_version) - poll_child_node = page_2_root.get_children().get() - delete_url = "{}?ids={}&collection_id={}".format( - reverse('admin:djangocms_moderation_moderationrequesttreenode_delete'), - ",".join([str(poll_child_node.pk)]), - self.collection.pk, - ) - response = self.client.post(delete_url, follow=True) - self.assertEqual(response.status_code, 200) + page_2_root_children = page_2_root.get_children() + if page_2_root_children.count() > 0: + poll_child_node = page_2_root_children.get() + delete_url = "{}?ids={}&collection_id={}".format( + reverse('admin:djangocms_moderation_moderationrequesttreenode_delete'), + ",".join([str(poll_child_node.pk)]), + self.collection.pk, + ) + response = self.client.post(delete_url, follow=True) + self.assertEqual(response.status_code, 200) # Load the changelist and check that the page loads without an error changelist_url = reverse('admin:djangocms_moderation_moderationrequesttreenode_changelist') @@ -1274,19 +1369,34 @@ def test_moderation_workflow_node_deletion_5(self): # Check the data # Only the roots (page_1_version and page_2_version) should remain - self.assertEqual( - ModerationRequest.objects.filter(collection=self.collection).count(), - 3 - ) - self.assertEqual( - ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), - 3 - ) + if cms_version < "4.1.0": + self.assertEqual( + ModerationRequest.objects.filter(collection=self.collection).count(), + 2 + ) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), + 2 + ) + else: + self.assertEqual( + ModerationRequest.objects.filter(collection=self.collection).count(), + 3 + ) + self.assertEqual( + ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), + 3 + ) self.assertEqual(ModerationRequestTreeNode.get_root_nodes().count(), 2) root_1 = ModerationRequestTreeNode.get_root_nodes().filter( moderation_request__version=self.page_1_version).get() root_2 = ModerationRequestTreeNode.get_root_nodes().filter( moderation_request__version=self.page_2_version).get() - self.assertEqual(root_1.get_children().count(), 1) - self.assertEqual(root_2.get_children().count(), 0) - self.assertEqual(root_1.get_children().get().moderation_request.version, self.poll_version) + + if cms_version < "4.1.0": + self.assertEqual(root_1.get_children().count(), 0) + self.assertEqual(root_2.get_children().count(), 0) + else: + self.assertEqual(root_1.get_children().count(), 1) + self.assertEqual(root_1.get_children().get().moderation_request.version, self.poll_version) + self.assertEqual(root_2.get_children().count(), 0) From 185b43a41f0bbee3a9fbc22277106f41bb0cd2de Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Fri, 15 Mar 2024 06:27:41 +0000 Subject: [PATCH 07/10] fix: flake8 issue --- tests/test_views.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tests/test_views.py b/tests/test_views.py index 984d9f08..7c05c417 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -239,7 +239,7 @@ def test_add_pages_moderated_children_to_collection(self): self.assertEqual(302, response.status_code) self.assertEqual(admin_endpoint, response.url) if cms_version < "4.1.0": - #version-locking override `_add_nested_children` add locked state checking + # version-locking override `_add_nested_children` add locked state checking self.assertEqual(stored_collection.count(), 1) else: self.assertEqual(stored_collection.count(), 3) @@ -258,8 +258,8 @@ def test_add_pages_moderated_children_to_collection(self): ) if cms_version < "4.1.0": - #version-locking override `_add_nested_children` add locked state checking - #poll1_version is locked, so will not be added to collection + # version-locking override `_add_nested_children` add locked state checking + # poll1_version is locked, so will not be added to collection self.assertEqual(mr1.count(), 0) self.assertEqual(mr2.count(), 0) else: @@ -317,8 +317,8 @@ def test_add_pages_moderated_duplicated_children_to_collection(self): ) mr = stored_collection.filter(version=poll_version) if cms_version < "4.1.0": - #version-locking override `_add_nested_children` add locked state checking - #poll1_version is locked, so will not be added to collection + # version-locking override `_add_nested_children` add locked state checking + # poll1_version is locked, so will not be added to collection self.assertEqual(mr.count(), 0) else: self.assertEqual(mr.count(), 1) @@ -368,11 +368,11 @@ def test_add_pages_moderated_duplicated_children_to_collection_for_author_only( self.assertEqual(302, response.status_code) self.assertEqual(admin_endpoint, response.url) if cms_version < "4.1.0": - #version-locking override `_add_nested_children` add locked state checking + # version-locking override `_add_nested_children` add locked state checking self.assertEqual(stored_collection.count(), 1) else: self.assertEqual(stored_collection.count(), 2) - + self.assertEqual(stored_collection.filter(version=page_version).count(), 1) self.assertEqual( ModerationRequestTreeNode.objects.filter( @@ -382,8 +382,8 @@ def test_add_pages_moderated_duplicated_children_to_collection_for_author_only( ) mr1 = stored_collection.filter(version=poll1_version) if cms_version < "4.1.0": - #version-locking override `_add_nested_children` add locked state checking - #poll1_version is locked, so will not be added to collection + # version-locking override `_add_nested_children` add locked state checking + # poll1_version is locked, so will not be added to collection self.assertEqual(mr1.count(), 0) else: self.assertEqual(mr1.count(), 1) @@ -454,7 +454,7 @@ def test_add_pages_moderated_traversed_children_to_collection(self): self.assertEqual(302, response.status_code) self.assertEqual(admin_endpoint, response.url) if cms_version < "4.1.0": - #version-locking override `_add_nested_children` add locked state checking + # version-locking override `_add_nested_children` add locked state checking self.assertEqual(stored_collection.count(), 1) else: self.assertEqual(stored_collection.count(), 4) @@ -469,8 +469,8 @@ def test_add_pages_moderated_traversed_children_to_collection(self): mr = stored_collection.filter(version=poll_version) if cms_version < "4.1.0": - #version-locking override `_add_nested_children` add locked state checking - #poll1_version is locked, so will not be added to collection + # version-locking override `_add_nested_children` add locked state checking + # poll1_version is locked, so will not be added to collection self.assertEqual(mr.count(), 0) self.assertEqual( stored_collection.filter(version=poll_child_1_version).count(), 0 @@ -1034,7 +1034,7 @@ def _add_pages_to_collection(self): # The tree structure for page_1_version is correct root_1 = ModerationRequestTreeNode.get_root_nodes().get(moderation_request__version=self.page_1_version) if cms_version < "4.1.0": - #version-locking override `_add_nested_children` add locked state checking + # version-locking override `_add_nested_children` add locked state checking self.assertEqual(mr.count(), 2) self.assertEqual( ModerationRequestTreeNode.objects.filter(moderation_request__collection=self.collection).count(), @@ -1392,7 +1392,7 @@ def test_moderation_workflow_node_deletion_5(self): moderation_request__version=self.page_1_version).get() root_2 = ModerationRequestTreeNode.get_root_nodes().filter( moderation_request__version=self.page_2_version).get() - + if cms_version < "4.1.0": self.assertEqual(root_1.get_children().count(), 0) self.assertEqual(root_2.get_children().count(), 0) From 2e4c97e9e5da07d4cba1eb4168e83d0785190463 Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Fri, 15 Mar 2024 06:52:08 +0000 Subject: [PATCH 08/10] fix: pre-commit-config related errors --- .pre-commit-config.yaml | 2 +- tests/test_views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index accaa9e3..54562a19 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -44,6 +44,6 @@ repos: - id: isort - repo: https://github.com/codespell-project/codespell - rev: v2.2.6 + rev: v2.1.0 hooks: - id: codespell diff --git a/tests/test_views.py b/tests/test_views.py index 7c05c417..d4cd9464 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -602,7 +602,7 @@ def test_collection_with_redirect_url_query_redirect_sanitisation(self): """ Reflected XSS Protection by ensuring that harmful characters are encoded - When a collection is succesful a redirect occurs back to the grouper in versioning, + When a collection is successful a redirect occurs back to the grouper in versioning, this functionality should continue to function even when sanitised! """ user = self.get_superuser() From 877085dacb9b805bbf801a151073d9dfd9507714 Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Fri, 15 Mar 2024 06:52:36 +0000 Subject: [PATCH 09/10] fix: pre-commit-config related errors --- .pre-commit-config.yaml | 6 +++++- djangocms_moderation/conf.py | 2 +- djangocms_moderation/migrations/0001_initial.py | 4 ++-- djangocms_moderation/migrations/0011_auto_20181008_1328.py | 2 -- djangocms_moderation/migrations/0014_auto_20190315_1723.py | 7 ++++++- .../migrations/0016_moderationrequesttreenode.py | 6 +++++- .../static/djangocms_moderation/js/libs/diffview.js | 2 +- 7 files changed, 20 insertions(+), 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 54562a19..c0963489 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,7 +18,7 @@ repos: rev: '1.4.0' hooks: - id: django-upgrade - args: [--target-version, "4.2"] + args: [--target-version, "4.0"] - repo: https://github.com/PyCQA/flake8 rev: 7.0.0 @@ -47,3 +47,7 @@ repos: rev: v2.1.0 hooks: - id: codespell + exclude: > + (?x)^( + .*\.(js|po) + )$ diff --git a/djangocms_moderation/conf.py b/djangocms_moderation/conf.py index e7008be7..26a3e5c5 100644 --- a/djangocms_moderation/conf.py +++ b/djangocms_moderation/conf.py @@ -9,7 +9,7 @@ ) CORE_COMPLIANCE_NUMBER_BACKENDS = ( - (UUID_BACKEND, _("Unique alpha-numeric string")), + (UUID_BACKEND, _("Unique alpha-npreumeric string")), (SEQUENTIAL_NUMBER_BACKEND, _("Sequential number")), ( SEQUENTIAL_NUMBER_WITH_IDENTIFIER_PREFIX_BACKEND, diff --git a/djangocms_moderation/migrations/0001_initial.py b/djangocms_moderation/migrations/0001_initial.py index 0efd9497..c714385e 100644 --- a/djangocms_moderation/migrations/0001_initial.py +++ b/djangocms_moderation/migrations/0001_initial.py @@ -311,7 +311,7 @@ class Migration(migrations.Migration): models.CharField( blank=True, default="", - help_text="Identifier is a 'free' field you could use for internal purposes. For example, it could be used as a workflow specific prefix of a compliance number", + help_text="Identifier is a 'free' field you could use for internal purposes. For example, it could be used as a workflow specific prefix of a compliance number", # noqa: E501 max_length=128, verbose_name="identifier", ), @@ -320,7 +320,7 @@ class Migration(migrations.Migration): "requires_compliance_number", models.BooleanField( default=False, - help_text="Does the Compliance number need to be generated before the moderation request is approved? Please select the compliance number backend below", + help_text="Does the Compliance number need to be generated before the moderation request is approved? Please select the compliance number backend below", # noqa: E501 verbose_name="requires compliance number?", ), ), diff --git a/djangocms_moderation/migrations/0011_auto_20181008_1328.py b/djangocms_moderation/migrations/0011_auto_20181008_1328.py index db52ec3a..cca7ac2b 100644 --- a/djangocms_moderation/migrations/0011_auto_20181008_1328.py +++ b/djangocms_moderation/migrations/0011_auto_20181008_1328.py @@ -1,6 +1,4 @@ # Generated by Django 1.11.13 on 2018-10-08 12:28 -from django.conf import settings -from django.db import migrations from django.db import migrations, models import django.db.models.deletion diff --git a/djangocms_moderation/migrations/0014_auto_20190315_1723.py b/djangocms_moderation/migrations/0014_auto_20190315_1723.py index d420dc9c..6cc014da 100644 --- a/djangocms_moderation/migrations/0014_auto_20190315_1723.py +++ b/djangocms_moderation/migrations/0014_auto_20190315_1723.py @@ -11,6 +11,11 @@ class Migration(migrations.Migration): operations = [ migrations.AlterModelOptions( name='moderationcollection', - options={'permissions': (('can_change_author', 'Can change collection author'), ('cancel_moderationcollection', 'Can cancel collection')), 'verbose_name': 'collection'}, + options={'permissions': ( + ('can_change_author', 'Can change collection author'), + ('cancel_moderationcollection', 'Can cancel collection') + ), + 'verbose_name': 'collection' + }, ), ] diff --git a/djangocms_moderation/migrations/0016_moderationrequesttreenode.py b/djangocms_moderation/migrations/0016_moderationrequesttreenode.py index 592c7f89..6f37e42c 100644 --- a/djangocms_moderation/migrations/0016_moderationrequesttreenode.py +++ b/djangocms_moderation/migrations/0016_moderationrequesttreenode.py @@ -17,7 +17,11 @@ class Migration(migrations.Migration): ('path', models.CharField(max_length=255, unique=True)), ('depth', models.PositiveIntegerField()), ('numchild', models.PositiveIntegerField(default=0)), - ('moderation_request', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='djangocms_moderation.ModerationRequest', verbose_name='moderation_request')), + ('moderation_request', models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + to='djangocms_moderation.ModerationRequest', + verbose_name='moderation_request') + ), # noqa: E124 ], options={ 'ordering': ('id',), diff --git a/djangocms_moderation/static/djangocms_moderation/js/libs/diffview.js b/djangocms_moderation/static/djangocms_moderation/js/libs/diffview.js index 65e2e411..999f8f6f 100644 --- a/djangocms_moderation/static/djangocms_moderation/js/libs/diffview.js +++ b/djangocms_moderation/static/djangocms_moderation/js/libs/diffview.js @@ -177,7 +177,7 @@ var diffview = { var botrows = []; for (var i = 0; i < rowcnt; i++) { - // jump ahead if we've alredy provided leading context or if this is the first range + // jump ahead if we've already provided leading context or if this is the first range if ( contextSize && opcodes.length > 1 && From 66dc28a2d9aeab3fc4f499756c367a00b7010c1e Mon Sep 17 00:00:00 2001 From: Josh Peng Yu Date: Fri, 15 Mar 2024 07:12:28 +0000 Subject: [PATCH 10/10] fix: typo --- djangocms_moderation/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/djangocms_moderation/conf.py b/djangocms_moderation/conf.py index 26a3e5c5..e051e5ef 100644 --- a/djangocms_moderation/conf.py +++ b/djangocms_moderation/conf.py @@ -9,7 +9,7 @@ ) CORE_COMPLIANCE_NUMBER_BACKENDS = ( - (UUID_BACKEND, _("Unique alpha-npreumeric string")), + (UUID_BACKEND, _("Unique alphanumeric string")), (SEQUENTIAL_NUMBER_BACKEND, _("Sequential number")), ( SEQUENTIAL_NUMBER_WITH_IDENTIFIER_PREFIX_BACKEND,