123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- # coding=utf-8
- """
- AutoSlugField taken from django-extensions at
- 15d3eb305957cee4768dd86e44df1bdad341a10e
- Uses Oscar's slugify function instead of Django's
-
- Copyright (c) 2007 Michael Trier
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- """
- from unittest import skipIf
-
- from django import VERSION as DJANGO_VERSION
- from django.db import models
- from django.test import TestCase
- from django.test.utils import override_settings
-
- from oscar.core.loading import get_model
-
- SluggedTestModel = get_model('model_tests_app', 'sluggedtestmodel')
- ChildSluggedTestModel = get_model('model_tests_app', 'childsluggedtestmodel')
- CustomSluggedTestModel = get_model('model_tests_app', 'CustomSluggedTestModel')
-
-
- class AutoSlugFieldTest(TestCase):
- def tearDown(self):
- super(AutoSlugFieldTest, self).tearDown()
-
- SluggedTestModel.objects.all().delete()
-
- def test_auto_create_slug(self):
- m = SluggedTestModel(title='foo')
- m.save()
- self.assertEqual(m.slug, 'foo')
-
- def test_auto_create_next_slug(self):
- m = SluggedTestModel(title='foo')
- m.save()
-
- m = SluggedTestModel(title='foo')
- m.save()
- self.assertEqual(m.slug, 'foo-2')
-
- def test_auto_create_slug_with_number(self):
- m = SluggedTestModel(title='foo 2012')
- m.save()
- self.assertEqual(m.slug, 'foo-2012')
-
- def test_auto_update_slug_with_number(self):
- m = SluggedTestModel(title='foo 2012')
- m.save()
- m.save()
- self.assertEqual(m.slug, 'foo-2012')
-
- @skipIf(DJANGO_VERSION < (1, 9),
- "unicode slugs not supported by Django<1.9")
- def test_auto_create_unicode_slug(self):
- with override_settings(OSCAR_SLUG_ALLOW_UNICODE=True):
- m = SluggedTestModel(title=u'Château Margaux 1960')
- m.save()
- self.assertEqual(m.slug, u'château-margaux-1960')
-
- @skipIf(DJANGO_VERSION < (1, 9),
- "unicode slugs not supported by Django<1.9")
- def test_auto_create_next_unicode_slug(self):
- with override_settings(OSCAR_SLUG_ALLOW_UNICODE=True):
- m1 = SluggedTestModel(title=u'Château Margaux 1960')
- m1.save()
-
- m2 = SluggedTestModel(title=u'Château Margaux 1960')
- m2.save()
-
- self.assertEqual(m2.slug, u'château-margaux-1960-2')
-
- @skipIf(DJANGO_VERSION < (1, 9),
- "unicode slugs not supported by Django<1.9")
- def test_switch_to_unicode_slug(self):
- m = SluggedTestModel(title=u'Château Margaux 1960')
- m.save()
- self.assertEqual(m.slug, 'chateau-margaux-1960')
- with override_settings(OSCAR_SLUG_ALLOW_UNICODE=True):
- m = SluggedTestModel(title=u'Château Margaux 1960')
- m.save()
- self.assertEqual(m.slug, u'château-margaux-1960')
-
- @skipIf(DJANGO_VERSION < (1, 9),
- "unicode slugs not supported by Django<1.9")
- def test_autoslugfield_allow_unicode_kwargs_precedence(self):
- from oscar.models.fields import AutoSlugField
- with override_settings(OSCAR_SLUG_ALLOW_UNICODE=True):
- autoslug_field = AutoSlugField(populate_from='title', allow_unicode=False)
- self.assertFalse(autoslug_field.allow_unicode)
- autoslug_field = AutoSlugField(populate_from='title')
- self.assertTrue(autoslug_field.allow_unicode)
-
- def test_update_slug(self):
- m = SluggedTestModel(title='foo')
- m.save()
- self.assertEqual(m.slug, 'foo')
-
- # update m instance without using `save'
- SluggedTestModel.objects.filter(pk=m.pk).update(slug='foo-2012')
- # update m instance with new data from the db
- m = SluggedTestModel.objects.get(pk=m.pk)
- self.assertEqual(m.slug, 'foo-2012')
-
- m.save()
- self.assertEqual(m.title, 'foo')
- self.assertEqual(m.slug, 'foo-2012')
-
- # Check slug is not overwrite
- m.title = 'bar'
- m.save()
- self.assertEqual(m.title, 'bar')
- self.assertEqual(m.slug, 'foo-2012')
-
- def test_simple_slug_source(self):
- m = SluggedTestModel(title='-foo')
- m.save()
- self.assertEqual(m.slug, 'foo')
-
- n = SluggedTestModel(title='-foo')
- n.save()
- self.assertEqual(n.slug, 'foo-2')
-
- n.save()
- self.assertEqual(n.slug, 'foo-2')
-
- def test_empty_slug_source(self):
- # regression test
-
- m = SluggedTestModel(title='')
- m.save()
- self.assertEqual(m.slug, '-2')
-
- n = SluggedTestModel(title='')
- n.save()
- self.assertEqual(n.slug, '-3')
-
- n.save()
- self.assertEqual(n.slug, '-3')
-
- def test_inheritance_creates_next_slug(self):
- m = SluggedTestModel(title='foo')
- m.save()
-
- n = ChildSluggedTestModel(title='foo')
- n.save()
- self.assertEqual(n.slug, 'foo-2')
-
- o = SluggedTestModel(title='foo')
- o.save()
- self.assertEqual(o.slug, 'foo-3')
-
- def test_separator_and_uppercase_options(self):
- m = CustomSluggedTestModel(title="Password reset")
- m.save()
- self.assertEqual(m.slug, 'PASSWORD_RESET')
-
- m = CustomSluggedTestModel(title="Password reset")
- m.save()
- self.assertEqual(m.slug, 'PASSWORD_RESET_2')
-
- def test_migration(self):
- """
- Tests making migrations with Django 1.7+'s migration framework
- """
-
- import oscar
- from django.db import migrations
- from django.db.migrations.writer import MigrationWriter
- from django.utils import six
- from oscar.models.fields import AutoSlugField
- fields = {
- 'autoslugfield': AutoSlugField(populate_from='otherfield'),
- }
-
- migration = type(str("Migration"), (migrations.Migration,), {
- "operations": [
- migrations.CreateModel("MyModel", tuple(fields.items()),
- {'populate_from': 'otherfield'},
- (models.Model,)),
- ],
- })
- writer = MigrationWriter(migration)
- output = writer.as_string()
- # It should NOT be unicode.
- self.assertIsInstance(output, six.binary_type,
- "Migration as_string returned unicode")
- # We don't test the output formatting - that's too fragile.
- # Just make sure it runs for now, and that things look alright.
- context = {
- 'migrations': migrations,
- 'oscar': oscar,
- }
- result = self.safe_exec(output, context=context)
- self.assertIn("Migration", result)
-
- def safe_exec(self, string, value=None, context=None):
- l = {}
- g = globals()
- g.update(context)
- try:
- exec(string, g, l)
- except Exception as e:
- if value:
- self.fail("Could not exec %r (from value %r): %s" % (
- string.strip(), value, e))
- else:
- self.fail("Could not exec %r: %s" % (string.strip(), e))
- return l
|