2018-08-06 01:06:52 +00:00
|
|
|
from django.db import IntegrityError, connection, models
|
2018-08-06 02:12:27 +00:00
|
|
|
from django.db.models.constraints import BaseConstraint
|
|
|
|
from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
|
2016-11-05 13:12:12 +00:00
|
|
|
|
|
|
|
from .models import Product
|
|
|
|
|
|
|
|
|
2018-08-06 01:06:52 +00:00
|
|
|
def get_constraints(table):
|
|
|
|
with connection.cursor() as cursor:
|
|
|
|
return connection.introspection.get_constraints(cursor, table)
|
|
|
|
|
|
|
|
|
2018-08-06 02:12:27 +00:00
|
|
|
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)
|
|
|
|
|
|
|
|
|
2016-11-05 13:12:12 +00:00
|
|
|
class CheckConstraintTests(TestCase):
|
|
|
|
def test_repr(self):
|
2018-08-06 02:15:10 +00:00
|
|
|
check = models.Q(price__gt=models.F('discounted_price'))
|
2016-11-05 13:12:12 +00:00
|
|
|
name = 'price_gt_discounted_price'
|
2018-08-06 02:15:10 +00:00
|
|
|
constraint = models.CheckConstraint(check=check, name=name)
|
2016-11-05 13:12:12 +00:00
|
|
|
self.assertEqual(
|
2018-08-06 02:15:10 +00:00
|
|
|
repr(constraint),
|
|
|
|
"<CheckConstraint: check='{}' name='{}'>".format(check, name),
|
2016-11-05 13:12:12 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
def test_deconstruction(self):
|
2018-08-06 02:15:10 +00:00
|
|
|
check = models.Q(price__gt=models.F('discounted_price'))
|
2016-11-05 13:12:12 +00:00
|
|
|
name = 'price_gt_discounted_price'
|
2018-08-06 02:15:10 +00:00
|
|
|
constraint = models.CheckConstraint(check=check, name=name)
|
|
|
|
path, args, kwargs = constraint.deconstruct()
|
2016-11-05 13:12:12 +00:00
|
|
|
self.assertEqual(path, 'django.db.models.CheckConstraint')
|
|
|
|
self.assertEqual(args, ())
|
2018-08-06 02:15:10 +00:00
|
|
|
self.assertEqual(kwargs, {'check': check, 'name': name})
|
2016-11-05 13:12:12 +00:00
|
|
|
|
|
|
|
@skipUnlessDBFeature('supports_table_check_constraints')
|
2018-09-25 15:14:45 +00:00
|
|
|
def test_database_constraint(self):
|
2016-11-05 13:12:12 +00:00
|
|
|
Product.objects.create(name='Valid', price=10, discounted_price=5)
|
|
|
|
with self.assertRaises(IntegrityError):
|
|
|
|
Product.objects.create(name='Invalid', price=10, discounted_price=20)
|
2018-08-06 01:06:52 +00:00
|
|
|
|
|
|
|
@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)
|