Added max retries option + tests

This commit is contained in:
Swen Kooij 2017-02-02 15:01:40 +02:00
parent 1ef02616ec
commit 9a976d5ec8
4 changed files with 39 additions and 8 deletions

View File

@ -1,5 +1,6 @@
from django.db import models, transaction
from django.db.utils import IntegrityError
from django.conf import settings
from .fields import LocalizedField
from .localized_value import LocalizedValue
@ -37,6 +38,12 @@ class LocalizedModel(models.Model):
def save(self, *args, **kwargs):
"""Saves this model instance to the database."""
max_retries = getattr(
settings,
'LOCALIZED_FIELDS_MAX_RETRIES',
100
)
if not hasattr(self, 'retries'):
self.retries = 0
@ -49,8 +56,8 @@ class LocalizedModel(models.Model):
# field class... we can also not only catch exceptions
# that apply to slug fields... so yea.. this is as
# retarded as it gets... i am sorry :(
if 'slug' not in str(ex):
if self.retries >= 100:
if 'slug' in str(ex):
if self.retries >= max_retries:
raise ex
self.retries += 1

View File

@ -23,3 +23,7 @@ LANGUAGES = (
INSTALLED_APPS = (
'tests',
)
# set to a lower number than the default, since
# we want the tests to be fast, default is 100
LOCALIZED_FIELDS_MAX_RETRIES = 3

View File

@ -1,6 +1,7 @@
from unittest import mock
from django.db import connection
from django.apps import apps
from django.conf import settings
from django.test import TestCase
from django.db.backends.base.schema import BaseDatabaseSchemaEditor
@ -8,7 +9,6 @@ from django.db.backends.base.schema import BaseDatabaseSchemaEditor
from localized_fields import LocalizedField, get_language_codes
from .fake_model import define_fake_model
from django.apps import apps
class DBBackendTestCase(TestCase):

View File

@ -1,9 +1,11 @@
from django import forms
from django.conf import settings
from django.test import TestCase
from django.db.utils import IntegrityError
from django.utils.text import slugify
from localized_fields import (LocalizedField, LocalizedAutoSlugField,
LocalizedMagicSlugField)
from django.utils.text import slugify
from .fake_model import get_fake_model
@ -60,6 +62,22 @@ class LocalizedSlugFieldTestCase(TestCase):
def test_unique_slug_magic(cls):
cls._test_unique_slug(cls.MagicSlugModel)
def test_unique_slug_magic_max_retries(self):
"""Tests whether the magic slug implementation doesn't
try to find a slug forever and gives up after a while."""
title = 'mymagictitle'
obj = self.MagicSlugModel()
obj.title.en = title
obj.save()
with self.assertRaises(IntegrityError):
for _ in range(0, settings.LOCALIZED_FIELDS_MAX_RETRIES + 1):
another_obj = self.MagicSlugModel()
another_obj.title.en = title
another_obj.save()
@classmethod
def test_unique_slug_utf_auto(cls):
cls._test_unique_slug_utf(cls.AutoSlugModel)
@ -112,16 +130,18 @@ class LocalizedSlugFieldTestCase(TestCase):
def _test_unique_slug(model):
"""Tests whether unique slugs are properly generated."""
title = 'mymagictitle'
obj = model()
obj.title.en = 'title'
obj.title.en = title
obj.save()
for i in range(1, 90):
for i in range(1, settings.LOCALIZED_FIELDS_MAX_RETRIES - 1):
another_obj = model()
another_obj.title.en = 'title'
another_obj.title.en = title
another_obj.save()
assert another_obj.slug.en == 'title-%d' % i
assert another_obj.slug.en == '%s-%d' % (title, i)
@staticmethod
def _test_unique_slug_utf(model):