Skip to content

Commit

Permalink
Prevent translation object duplicates via TranslationCreator (#756)
Browse files Browse the repository at this point in the history
  • Loading branch information
ACK1D authored and zerolab committed Dec 27, 2023
1 parent 92c18ab commit 8b32d63
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 2 deletions.
8 changes: 6 additions & 2 deletions wagtail_localize/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ def create_translations(self, instance, include_related_objects=True):
)

# Support disabling the out of the box translation mode.
# The value set on the model takes precendence over the global setting.
# The value set on the model takes precedence over the global setting.
if hasattr(instance, "localize_default_translation_mode"):
translation_mode = instance.localize_default_translation_mode
else:
Expand All @@ -61,9 +61,13 @@ def create_translations(self, instance, include_related_objects=True):

# Set up translation records
for target_locale in self.target_locales:
# Skip if target_locale is the same as source locale
if target_locale == source.locale:
continue

# Create translation if it doesn't exist yet, re-enable if translation was disabled
# Note that the form won't show this locale as an option if the translation existed
# in this langauge, so this shouldn't overwrite any unmanaged translations.
# in this language, so this shouldn't overwrite any unmanaged translations.
translation, created = Translation.objects.update_or_create(
source=source,
target_locale=target_locale,
Expand Down
84 changes: 84 additions & 0 deletions wagtail_localize/tests/test_operations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from django.contrib.auth import get_user_model
from django.test import TestCase
from wagtail.models import Locale, Page

from wagtail_localize.models import Translation, TranslationSource
from wagtail_localize.operations import TranslationCreator
from wagtail_localize.segments import RelatedObjectSegmentValue
from wagtail_localize.test.models import TestPage


def create_test_page(**kwargs):
parent = kwargs.pop("parent", None) or Page.objects.get(id=1)
page = parent.add_child(instance=TestPage(**kwargs))
page_revision = page.save_revision()
page_revision.publish()
page.refresh_from_db()

source, created = TranslationSource.get_or_create_from_instance(page)
prepare_source(source)

return page


def prepare_source(source):
# Recurse into any related objects
for segment in source.relatedobjectsegment_set.all():
if isinstance(segment, RelatedObjectSegmentValue):
related_source, created = TranslationSource.get_or_create_from_instance(
segment.get_instance(source.locale)
)
prepare_source(related_source)


class TranslationOperationsTest(TestCase):
def setUp(self):
# Create a Belarusian locale for testing
self.be_locale = Locale.objects.create(language_code="be")

# Create a test page
self.page = create_test_page(
title="Test page",
slug="test-page",
test_charfield="This is some test content",
)

# Create a user
self.user = get_user_model().objects.create(username="testuser")

# Instantiate TranslationCreator with the default and Belarusian locales for target_locales
self.target_locales = [self.page.locale, self.be_locale]
self.translation_creator = TranslationCreator(
user=self.user, target_locales=self.target_locales
)

def test_create_translations_skips_duplicate(self):
# Call create_translations() to check that only one translation has been created
self.translation_creator.create_translations(self.page)

# Assert statements for better readability
self.assertEqual(
TranslationSource.objects.filter(
object_id=self.page.translation_key
).count(),
1,
"Only one TranslationSource should be created for the source page",
)

self.assertEqual(
Translation.objects.filter(
source__object_id=self.page.translation_key,
target_locale=self.be_locale,
).count(),
1,
"Only one Translation object should be created for the Belarusian locale",
)

self.assertEqual(
Translation.objects.filter(
source__object_id=self.page.translation_key,
target_locale=self.page.locale,
).count(),
0,
"No Translation object should be created for the default locale",
)

0 comments on commit 8b32d63

Please sign in to comment.