django1/tests/constraints/tests.py

93 lines
3.5 KiB
Python

from django.core.exceptions import ValidationError
from django.db import IntegrityError, connection, models
from django.db.models.constraints import BaseConstraint
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
from .models import Product
def get_constraints(table):
with connection.cursor() as cursor:
return connection.introspection.get_constraints(cursor, table)
class BaseConstraintTests(SimpleTestCase):
def test_constraint_sql(self):
c = BaseConstraint('name')
msg = 'This method must be implemented by a subclass.'
with self.assertRaisesMessage(NotImplementedError, msg):
c.constraint_sql(None, None)
class CheckConstraintTests(TestCase):
def test_repr(self):
check = models.Q(price__gt=models.F('discounted_price'))
name = 'price_gt_discounted_price'
constraint = models.CheckConstraint(check=check, name=name)
self.assertEqual(
repr(constraint),
"<CheckConstraint: check='{}' name='{}'>".format(check, name),
)
def test_deconstruction(self):
check = models.Q(price__gt=models.F('discounted_price'))
name = 'price_gt_discounted_price'
constraint = models.CheckConstraint(check=check, name=name)
path, args, kwargs = constraint.deconstruct()
self.assertEqual(path, 'django.db.models.CheckConstraint')
self.assertEqual(args, ())
self.assertEqual(kwargs, {'check': check, 'name': name})
@skipUnlessDBFeature('supports_table_check_constraints')
def test_database_constraint(self):
Product.objects.create(name='Valid', price=10, discounted_price=5)
with self.assertRaises(IntegrityError):
Product.objects.create(name='Invalid', price=10, discounted_price=20)
@skipUnlessDBFeature('supports_table_check_constraints')
def test_name(self):
constraints = get_constraints(Product._meta.db_table)
expected_name = 'price_gt_discounted_price'
if connection.features.uppercases_column_names:
expected_name = expected_name.upper()
self.assertIn(expected_name, constraints)
class UniqueConstraintTests(TestCase):
@classmethod
def setUpTestData(cls):
cls.p1 = Product.objects.create(name='p1')
def test_repr(self):
fields = ['foo', 'bar']
name = 'unique_fields'
constraint = models.UniqueConstraint(fields=fields, name=name)
self.assertEqual(
repr(constraint),
"<UniqueConstraint: fields=('foo', 'bar') name='unique_fields'>",
)
def test_deconstruction(self):
fields = ['foo', 'bar']
name = 'unique_fields'
check = models.UniqueConstraint(fields=fields, name=name)
path, args, kwargs = check.deconstruct()
self.assertEqual(path, 'django.db.models.UniqueConstraint')
self.assertEqual(args, ())
self.assertEqual(kwargs, {'fields': tuple(fields), 'name': name})
def test_database_constraint(self):
with self.assertRaises(IntegrityError):
Product.objects.create(name=self.p1.name)
def test_model_validation(self):
with self.assertRaisesMessage(ValidationError, 'Product with this Name already exists.'):
Product(name=self.p1.name).validate_unique()
def test_name(self):
constraints = get_constraints(Product._meta.db_table)
expected_name = 'unique_name'
if connection.features.uppercases_column_names:
expected_name = expected_name.upper()
self.assertIn(expected_name, constraints)