Skip to content

Commit

Permalink
Add tests for cloning regions
Browse files Browse the repository at this point in the history
- Add test case which fails in the current state to reproduce #1259
- Order translation models by language to keep deterministic order to compare querysets
  • Loading branch information
timobrembeck committed Mar 5, 2022
1 parent b48e39e commit b7cb791
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Generated by Django 3.2.12 on 2022-03-04 21:19

from django.db import migrations


class Migration(migrations.Migration):
"""
Migration file to change the ordering of translation models
(additionally order translation objects by language)
"""

dependencies = [
("cms", "0008_alter_pushnotification_channel"),
]

operations = [
migrations.AlterModelOptions(
name="eventtranslation",
options={
"default_permissions": (),
"default_related_name": "event_translations",
"ordering": ["event__pk", "language__pk", "-version"],
"verbose_name": "event translation",
"verbose_name_plural": "event translations",
},
),
migrations.AlterModelOptions(
name="imprintpagetranslation",
options={
"default_permissions": (),
"default_related_name": "imprint_translations",
"ordering": ["page__pk", "language__pk", "-version"],
"verbose_name": "imprint translation",
"verbose_name_plural": "imprint translations",
},
),
migrations.AlterModelOptions(
name="pagetranslation",
options={
"default_permissions": (),
"default_related_name": "page_translations",
"ordering": ["page__pk", "language__pk", "-version"],
"verbose_name": "page translation",
"verbose_name_plural": "page translations",
},
),
migrations.AlterModelOptions(
name="poitranslation",
options={
"default_permissions": (),
"default_related_name": "poi_translations",
"ordering": ["poi__pk", "language__pk", "-version"],
"verbose_name": "location translation",
"verbose_name_plural": "location translations",
},
),
migrations.AlterModelOptions(
name="pushnotificationtranslation",
options={
"default_permissions": (),
"ordering": ["push_notification__pk", "language__pk", "language"],
"verbose_name": "push notification translation",
"verbose_name_plural": "push notification translations",
},
),
]
2 changes: 1 addition & 1 deletion integreat_cms/cms/models/events/event_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,4 @@ class Meta:
#: The default permissions for this model
default_permissions = ()
#: The fields which are used to sort the returned objects of a QuerySet
ordering = ["event__pk", "-version"]
ordering = ["event__pk", "language__pk", "-version"]
2 changes: 1 addition & 1 deletion integreat_cms/cms/models/pages/imprint_page_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,4 @@ class Meta:
#: The default permissions for this model
default_permissions = ()
#: The fields which are used to sort the returned objects of a QuerySet
ordering = ["page", "-version"]
ordering = ["page__pk", "language__pk", "-version"]
2 changes: 1 addition & 1 deletion integreat_cms/cms/models/pages/page_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,4 +253,4 @@ class Meta:
#: The default permissions for this model
default_permissions = ()
#: The fields which are used to sort the returned objects of a QuerySet
ordering = ["page__pk", "-version"]
ordering = ["page__pk", "language__pk", "-version"]
2 changes: 1 addition & 1 deletion integreat_cms/cms/models/pois/poi_translation.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ class Meta:
#: The default permissions for this model
default_permissions = ()
#: The fields which are used to sort the returned objects of a QuerySet
ordering = ["poi__pk", "-version"]
ordering = ["poi__pk", "language__pk", "-version"]
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class Meta:
#: The plural verbose name of the model
verbose_name_plural = _("push notification translations")
#: The fields which are used to sort the returned objects of a QuerySet
ordering = ["push_notification", "language"]
ordering = ["push_notification__pk", "language__pk", "language"]
#: The default permissions for this model
default_permissions = ()
#: Sets of field names that, taken together, must be unique
Expand Down
91 changes: 91 additions & 0 deletions tests/cms/region_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import pytest

from django.forms.models import model_to_dict
from django.urls import reverse

from integreat_cms.cms.models import Region, LanguageTreeNode, Page

# pylint: disable=unused-argument,too-many-locals
@pytest.mark.django_db
def test_duplicate_regions(load_test_data, admin_client):
"""
Test whether duplicating regions works as expected
:param load_test_data: The fixture providing the test data (see :meth:`~tests.conftest.load_test_data`)
:type load_test_data: tuple
:param admin_client: The fixture providing the logged in admin
:type admin_client: :fixture:`admin_client`
"""
url = reverse("new_region")
response = admin_client.post(
url,
data={
"administrative_division": "CITY",
"name": "cloned",
"admin_mail": "cloned@example.com",
"postal_code": "11111",
"status": "ACTIVE",
"longitude": 1,
"latitude": 1,
"duplicated_region": 1,
},
)
print(response.headers)
assert response.status_code == 302

source_region = Region.objects.get(id=1)
target_region = Region.objects.get(slug="cloned")

# Check if all cloned pages exist and are identical
source_pages = source_region.pages.all()
target_pages = target_region.pages.all()
assert len(source_pages) == len(target_pages)
for source_page, target_page in zip(source_pages, target_pages):
source_page_dict = model_to_dict(
source_page, exclude=["id", "tree_id", "region", "parent"]
)
target_page_dict = model_to_dict(
target_page, exclude=["id", "tree_id", "region", "parent"]
)
assert source_page_dict == target_page_dict

# Check if all cloned page translations exist and are identical
source_page_translations = source_page.translations.all()
target_pages_translations = target_page.translations.all()
assert len(source_page_translations) == len(target_pages_translations)
for source_page_translation, target_page_translation in zip(
source_page_translations, target_pages_translations
):
source_page_translation_dict = model_to_dict(
source_page_translation, exclude=["id", "page"]
)
target_page_translation_dict = model_to_dict(
target_page_translation, exclude=["id", "page"]
)
assert source_page_translation_dict == target_page_translation_dict

# Check if all cloned language tree nodes exist and are identical
source_language_tree = source_region.language_tree_nodes.all()
target_language_tree = target_region.language_tree_nodes.all()
assert len(source_language_tree) == len(target_language_tree)
for source_node, target_node in zip(source_language_tree, target_language_tree):
source_node_dict = model_to_dict(
source_node, exclude=["id", "tree_id", "region", "parent"]
)
target_node_dict = model_to_dict(
target_node, exclude=["id", "tree_id", "region", "parent"]
)
assert source_node_dict == target_node_dict

# Check for duplicated tree ids
for model in [LanguageTreeNode, Page]:
# Make sure each combination of tree_id and lft resp. rgt only exists once
for tree_field in ["lft", "rgt"]:
combinations = model.objects.values_list("tree_id", tree_field)
# Make sure there are no duplicates in this list
assert len(combinations) == len(set(combinations))
# Make sure each tree_id only exists in one region
combinations = model.objects.values_list("tree_id", "region")
tree_ids = [tree_id for tree_id, region in set(combinations)]
assert len(tree_ids) == len(set(tree_ids))

0 comments on commit b7cb791

Please sign in to comment.