tests.py 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. from django.core.exceptions import ValidationError
  2. from django.db import IntegrityError, connection, models
  3. from django.db.models.constraints import BaseConstraint
  4. from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature
  5. from .models import Product
  6. def get_constraints(table):
  7. with connection.cursor() as cursor:
  8. return connection.introspection.get_constraints(cursor, table)
  9. class BaseConstraintTests(SimpleTestCase):
  10. def test_constraint_sql(self):
  11. c = BaseConstraint('name')
  12. msg = 'This method must be implemented by a subclass.'
  13. with self.assertRaisesMessage(NotImplementedError, msg):
  14. c.constraint_sql(None, None)
  15. class CheckConstraintTests(TestCase):
  16. def test_repr(self):
  17. check = models.Q(price__gt=models.F('discounted_price'))
  18. name = 'price_gt_discounted_price'
  19. constraint = models.CheckConstraint(check=check, name=name)
  20. self.assertEqual(
  21. repr(constraint),
  22. "<CheckConstraint: check='{}' name='{}'>".format(check, name),
  23. )
  24. def test_deconstruction(self):
  25. check = models.Q(price__gt=models.F('discounted_price'))
  26. name = 'price_gt_discounted_price'
  27. constraint = models.CheckConstraint(check=check, name=name)
  28. path, args, kwargs = constraint.deconstruct()
  29. self.assertEqual(path, 'django.db.models.CheckConstraint')
  30. self.assertEqual(args, ())
  31. self.assertEqual(kwargs, {'check': check, 'name': name})
  32. @skipUnlessDBFeature('supports_table_check_constraints')
  33. def test_database_constraint(self):
  34. Product.objects.create(name='Valid', price=10, discounted_price=5)
  35. with self.assertRaises(IntegrityError):
  36. Product.objects.create(name='Invalid', price=10, discounted_price=20)
  37. @skipUnlessDBFeature('supports_table_check_constraints')
  38. def test_name(self):
  39. constraints = get_constraints(Product._meta.db_table)
  40. expected_name = 'price_gt_discounted_price'
  41. if connection.features.uppercases_column_names:
  42. expected_name = expected_name.upper()
  43. self.assertIn(expected_name, constraints)
  44. class UniqueConstraintTests(TestCase):
  45. @classmethod
  46. def setUpTestData(cls):
  47. cls.p1 = Product.objects.create(name='p1')
  48. def test_repr(self):
  49. fields = ['foo', 'bar']
  50. name = 'unique_fields'
  51. constraint = models.UniqueConstraint(fields=fields, name=name)
  52. self.assertEqual(
  53. repr(constraint),
  54. "<UniqueConstraint: fields=('foo', 'bar') name='unique_fields'>",
  55. )
  56. def test_deconstruction(self):
  57. fields = ['foo', 'bar']
  58. name = 'unique_fields'
  59. check = models.UniqueConstraint(fields=fields, name=name)
  60. path, args, kwargs = check.deconstruct()
  61. self.assertEqual(path, 'django.db.models.UniqueConstraint')
  62. self.assertEqual(args, ())
  63. self.assertEqual(kwargs, {'fields': tuple(fields), 'name': name})
  64. def test_database_constraint(self):
  65. with self.assertRaises(IntegrityError):
  66. Product.objects.create(name=self.p1.name)
  67. def test_model_validation(self):
  68. with self.assertRaisesMessage(ValidationError, 'Product with this Name already exists.'):
  69. Product(name=self.p1.name).validate_unique()
  70. def test_name(self):
  71. constraints = get_constraints(Product._meta.db_table)
  72. expected_name = 'unique_name'
  73. if connection.features.uppercases_column_names:
  74. expected_name = expected_name.upper()
  75. self.assertIn(expected_name, constraints)