django-localized-fields/tests/test_slug_fields.py

260 lines
7.5 KiB
Python

import copy
from django import forms
from django.db import models
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.fields import (
LocalizedField,
LocalizedUniqueSlugField
)
from .fake_model import get_fake_model
class LocalizedSlugFieldTestCase(TestCase):
"""Tests the localized slug classes."""
AutoSlugModel = None
Model = None
@classmethod
def setUpClass(cls):
"""Creates the test models in the database."""
super(LocalizedSlugFieldTestCase, cls).setUpClass()
cls.Model = get_fake_model(
{
'title': LocalizedField(),
'name': models.CharField(max_length=255),
'slug': LocalizedUniqueSlugField(populate_from='title')
}
)
@staticmethod
def test_unique_slug_with_time():
"""Tests whether the primary key is included in
the slug when the 'use_pk' option is enabled."""
title = 'myuniquetitle'
PkModel = get_fake_model(
{
'title': LocalizedField(),
'slug': LocalizedUniqueSlugField(populate_from='title', include_time=True)
}
)
obj = PkModel()
obj.title.en = title
obj.save()
assert obj.slug.en.startswith('%s-' % title)
@classmethod
def test_uniue_slug_no_change(cls):
"""Tests whether slugs are not re-generated if not needed."""
NoChangeSlugModel = get_fake_model(
{
'title': LocalizedField(),
'slug': LocalizedUniqueSlugField(populate_from='title', include_time=True)
}
)
title = 'myuniquetitle'
obj = NoChangeSlugModel()
obj.title.en = title
obj.title.nl = title
obj.save()
old_slug_en = copy.deepcopy(obj.slug.en)
old_slug_nl = copy.deepcopy(obj.slug.nl)
obj.title.nl += 'beer'
obj.save()
assert old_slug_en == obj.slug.en
assert old_slug_nl != obj.slug.nl
@classmethod
def test_unique_slug_update(cls):
obj = cls.Model.objects.create(title={settings.LANGUAGE_CODE: 'mytitle'})
assert obj.slug.get() == 'mytitle'
obj.title.set(settings.LANGUAGE_CODE, 'othertitle')
obj.save()
assert obj.slug.get() == 'othertitle'
@classmethod
def test_unique_slug_unique_max_retries(cls):
"""Tests whether the unique slug implementation doesn't
try to find a slug forever and gives up after a while."""
title = 'myuniquetitle'
obj = cls.Model()
obj.title.en = title
obj.save()
with cls.assertRaises(cls, IntegrityError):
for _ in range(0, settings.LOCALIZED_FIELDS_MAX_RETRIES + 1):
another_obj = cls.Model()
another_obj.title.en = title
another_obj.save()
@classmethod
def test_populate(cls):
"""Tests whether the populating feature works correctly."""
obj = cls.Model()
obj.title.en = 'this is my title'
obj.save()
assert obj.slug.get('en') == slugify(obj.title)
@classmethod
def test_populate_callable(cls):
"""Tests whether the populating feature works correctly
when you specify a callable."""
def generate_slug(instance):
return instance.title
model = get_fake_model({
'title': LocalizedField(),
'slug': LocalizedUniqueSlugField(populate_from=generate_slug)
})
obj = cls.Model()
for lang_code, lang_name in settings.LANGUAGES:
obj.title.set(lang_code, 'title %s' % lang_name)
obj.save()
for lang_code, lang_name in settings.LANGUAGES:
assert obj.slug.get(lang_code) == 'title-%s' % lang_name.lower()
@staticmethod
def test_populate_multiple_from_fields():
"""Tests whether populating the slug from multiple
fields works correctly."""
model = get_fake_model(
{
'title': LocalizedField(),
'name': models.CharField(max_length=255),
'slug': LocalizedUniqueSlugField(populate_from=('title', 'name'))
}
)
obj = model()
for lang_code, lang_name in settings.LANGUAGES:
obj.name = 'swen'
obj.title.set(lang_code, 'title %s' % lang_name)
obj.save()
for lang_code, lang_name in settings.LANGUAGES:
assert obj.slug.get(lang_code) == 'title-%s-swen' % lang_name.lower()
@staticmethod
def test_populate_multiple_from_fields_fk():
"""Tests whether populating the slug from multiple
fields works correctly."""
model_fk = get_fake_model(
{
'name': LocalizedField(),
}
)
model = get_fake_model(
{
'title': LocalizedField(),
'other': models.ForeignKey(model_fk),
'slug': LocalizedUniqueSlugField(populate_from=('title', 'other.name'))
}
)
other = model_fk.objects.create(name={settings.LANGUAGE_CODE: 'swen'})
obj = model()
for lang_code, lang_name in settings.LANGUAGES:
obj.other_id = other.id
obj.title.set(lang_code, 'title %s' % lang_name)
obj.save()
for lang_code, lang_name in settings.LANGUAGES:
assert obj.slug.get(lang_code) == 'title-%s-swen' % lang_name.lower()
@classmethod
def test_populate_multiple_languages(cls):
"""Tests whether the populating feature correctly
works for all languages."""
obj = cls.Model()
for lang_code, lang_name in settings.LANGUAGES:
obj.title.set(lang_code, 'title %s' % lang_name)
obj.save()
for lang_code, lang_name in settings.LANGUAGES:
assert obj.slug.get(lang_code) == 'title-%s' % lang_name.lower()
@classmethod
def test_unique_slug(cls):
"""Tests whether unique slugs are properly generated."""
title = 'myuniquetitle'
obj = cls.Model()
obj.title.en = title
obj.save()
for i in range(1, settings.LOCALIZED_FIELDS_MAX_RETRIES - 1):
another_obj = cls.Model()
another_obj.title.en = title
another_obj.save()
assert another_obj.slug.en == '%s-%d' % (title, i)
@classmethod
def test_unique_slug_utf(cls):
"""Tests whether generating a slug works
when the value consists completely out
of non-ASCII characters."""
obj = cls.Model()
obj.title.en = 'مكاتب للايجار بشارع بورسعيد'
obj.save()
assert obj.slug.en == 'مكاتب-للايجار-بشارع-بورسعيد'
@staticmethod
def test_deconstruct():
"""Tests whether the :see:deconstruct
function properly retains options
specified in the constructor."""
field = LocalizedUniqueSlugField(populate_from='title')
_, _, _, kwargs = field.deconstruct()
assert 'populate_from' in kwargs
assert kwargs['populate_from'] == field.populate_from
@staticmethod
def test_formfield():
"""Tests whether the :see:formfield method
returns a valid form field that is hidden."""
form_field = LocalizedUniqueSlugField(populate_from='title').formfield()
assert isinstance(form_field, forms.CharField)
assert isinstance(form_field.widget, forms.HiddenInput)