django/tests/postgres_tests/test_citext.py
Mads Jensen 3545e84488 [1.11.x] Fixed #28702 -- Made query lookups for CIText fields use citext.
Backport of f0a68c25118786d47041d0a435b2afa953be3c86 from master
2017-11-29 11:12:07 -05:00

61 lines
2.5 KiB
Python

"""
The citext PostgreSQL extension supports indexing of case-insensitive text
strings and thus eliminates the need for operations such as iexact and other
modifiers to enforce use of an index.
"""
from django.db import IntegrityError
from django.test.utils import modify_settings
from . import PostgreSQLTestCase
from .models import CITestModel
@modify_settings(INSTALLED_APPS={'append': 'django.contrib.postgres'})
class CITextTestCase(PostgreSQLTestCase):
case_sensitive_lookups = ('contains', 'startswith', 'endswith', 'regex')
@classmethod
def setUpTestData(cls):
cls.john = CITestModel.objects.create(
name='JoHn',
email='joHn@johN.com',
description='Average Joe named JoHn',
array_field=['JoE', 'jOhn'],
)
def test_equal_lowercase(self):
"""
citext removes the need for iexact as the index is case-insensitive.
"""
self.assertEqual(CITestModel.objects.filter(name=self.john.name.lower()).count(), 1)
self.assertEqual(CITestModel.objects.filter(email=self.john.email.lower()).count(), 1)
self.assertEqual(CITestModel.objects.filter(description=self.john.description.lower()).count(), 1)
def test_fail_citext_primary_key(self):
"""
Creating an entry for a citext field used as a primary key which
clashes with an existing value isn't allowed.
"""
with self.assertRaises(IntegrityError):
CITestModel.objects.create(name='John')
def test_array_field(self):
instance = CITestModel.objects.get()
self.assertEqual(instance.array_field, self.john.array_field)
self.assertTrue(CITestModel.objects.filter(array_field__contains=['joe']).exists())
def test_lookups_name_char(self):
for lookup in self.case_sensitive_lookups:
query = {'name__{}'.format(lookup): 'john'}
self.assertSequenceEqual(CITestModel.objects.filter(**query), [self.john])
def test_lookups_description_text(self):
for lookup, string in zip(self.case_sensitive_lookups, ('average', 'average joe', 'john', 'Joe.named')):
query = {'description__{}'.format(lookup): string}
self.assertSequenceEqual(CITestModel.objects.filter(**query), [self.john])
def test_lookups_email(self):
for lookup, string in zip(self.case_sensitive_lookups, ('john', 'john', 'john.com', 'john.com')):
query = {'email__{}'.format(lookup): string}
self.assertSequenceEqual(CITestModel.objects.filter(**query), [self.john])