summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/backends/postgresql/tests.py14
-rw-r--r--tests/constraints/tests.py36
-rw-r--r--tests/lookup/tests.py10
3 files changed, 60 insertions, 0 deletions
diff --git a/tests/backends/postgresql/tests.py b/tests/backends/postgresql/tests.py
index 31aac022c8..a045195991 100644
--- a/tests/backends/postgresql/tests.py
+++ b/tests/backends/postgresql/tests.py
@@ -369,6 +369,20 @@ class Tests(TestCase):
with self.subTest(lookup=lookup):
self.assertIn("::text", do.lookup_cast(lookup))
+ def test_lookup_cast_isnull_noop(self):
+ from django.db.backends.postgresql.operations import DatabaseOperations
+
+ do = DatabaseOperations(connection=None)
+ # Using __isnull lookup doesn't require casting.
+ tests = [
+ "CharField",
+ "EmailField",
+ "TextField",
+ ]
+ for field_type in tests:
+ with self.subTest(field_type=field_type):
+ self.assertEqual(do.lookup_cast("isnull", field_type), "%s")
+
def test_correct_extraction_psycopg_version(self):
from django.db.backends.postgresql.base import Database, psycopg_version
diff --git a/tests/constraints/tests.py b/tests/constraints/tests.py
index 55397449d9..e1b95baf60 100644
--- a/tests/constraints/tests.py
+++ b/tests/constraints/tests.py
@@ -995,6 +995,42 @@ class UniqueConstraintTests(TestCase):
exclude={"name"},
)
+ def test_validate_nullable_textfield_with_isnull_true(self):
+ is_null_constraint = models.UniqueConstraint(
+ "price",
+ "discounted_price",
+ condition=models.Q(unit__isnull=True),
+ name="uniq_prices_no_unit",
+ )
+ is_not_null_constraint = models.UniqueConstraint(
+ "price",
+ "discounted_price",
+ condition=models.Q(unit__isnull=False),
+ name="uniq_prices_unit",
+ )
+
+ Product.objects.create(price=2, discounted_price=1)
+ Product.objects.create(price=4, discounted_price=3, unit="ng/mL")
+
+ msg = "Constraint “uniq_prices_no_unit” is violated."
+ with self.assertRaisesMessage(ValidationError, msg):
+ is_null_constraint.validate(
+ Product, Product(price=2, discounted_price=1, unit=None)
+ )
+ is_null_constraint.validate(
+ Product, Product(price=2, discounted_price=1, unit="ng/mL")
+ )
+ is_null_constraint.validate(Product, Product(price=4, discounted_price=3))
+
+ msg = "Constraint “uniq_prices_unit” is violated."
+ with self.assertRaisesMessage(ValidationError, msg):
+ is_not_null_constraint.validate(
+ Product,
+ Product(price=4, discounted_price=3, unit="μg/mL"),
+ )
+ is_not_null_constraint.validate(Product, Product(price=4, discounted_price=3))
+ is_not_null_constraint.validate(Product, Product(price=2, discounted_price=1))
+
def test_name(self):
constraints = get_constraints(UniqueConstraintProduct._meta.db_table)
expected_name = "name_color_uniq"
diff --git a/tests/lookup/tests.py b/tests/lookup/tests.py
index 398cc89cab..8af459ccd7 100644
--- a/tests/lookup/tests.py
+++ b/tests/lookup/tests.py
@@ -1337,6 +1337,16 @@ class LookupTests(TestCase):
with self.assertRaisesMessage(ValueError, msg):
qs.exists()
+ def test_isnull_textfield(self):
+ self.assertSequenceEqual(
+ Author.objects.filter(bio__isnull=True),
+ [self.au2],
+ )
+ self.assertSequenceEqual(
+ Author.objects.filter(bio__isnull=False),
+ [self.au1],
+ )
+
def test_lookup_rhs(self):
product = Product.objects.create(name="GME", qty_target=5000)
stock_1 = Stock.objects.create(product=product, short=True, qty_available=180)