mirror of
https://github.com/django/django.git
synced 2025-01-03 15:06:09 +00:00
Refs #34553 -- Split constraint escaping test in subtests.
This ensures that constraint violations are tested in isolation from
each other as an IntegrityError only ensures a least one constraint is
violated.
For example, the assertion added in 42e8cf4
break both the
name_constraint_rhs and the rebate_constraint constraints and thus
doesn't constitute a proper regression test. Refs #32369.
This commit is contained in:
parent
6e32d1fa1d
commit
e0f8104a96
@ -3652,47 +3652,44 @@ class OperationTests(OperationTestBase):
|
||||
),
|
||||
]
|
||||
from_state = self.apply_operations(app_label, ProjectState(), operations)
|
||||
# "%" generated in startswith lookup should be escaped in a way that is
|
||||
# considered a leading wildcard.
|
||||
check = models.Q(name__startswith="Albert")
|
||||
constraint = models.CheckConstraint(check=check, name="name_constraint")
|
||||
operation = migrations.AddConstraint("Author", constraint)
|
||||
to_state = from_state.clone()
|
||||
operation.state_forwards(app_label, to_state)
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards(app_label, editor, from_state, to_state)
|
||||
Author = to_state.apps.get_model(app_label, "Author")
|
||||
with self.assertRaises(IntegrityError), transaction.atomic():
|
||||
Author.objects.create(name="Artur")
|
||||
checks = [
|
||||
# "%" generated in startswith lookup should be escaped in a way
|
||||
# that is considered a leading wildcard.
|
||||
(
|
||||
models.Q(name__startswith="Albert"),
|
||||
{"name": "Alberta"},
|
||||
{"name": "Artur"},
|
||||
),
|
||||
# Literal "%" should be escaped in a way that is not a considered a
|
||||
# wildcard.
|
||||
check = models.Q(rebate__endswith="%")
|
||||
constraint = models.CheckConstraint(check=check, name="rebate_constraint")
|
||||
(models.Q(rebate__endswith="%"), {"rebate": "10%"}, {"rebate": "10$"}),
|
||||
# Right-hand-side baked "%" literals should not be used for
|
||||
# parameters interpolation.
|
||||
(
|
||||
~models.Q(surname__startswith=models.F("name")),
|
||||
{"name": "Albert"},
|
||||
{"name": "Albert", "surname": "Alberto"},
|
||||
),
|
||||
]
|
||||
for check, valid, invalid in checks:
|
||||
with self.subTest(check=check, valid=valid, invalid=invalid):
|
||||
constraint = models.CheckConstraint(check=check, name="constraint")
|
||||
operation = migrations.AddConstraint("Author", constraint)
|
||||
from_state = to_state
|
||||
to_state = from_state.clone()
|
||||
operation.state_forwards(app_label, to_state)
|
||||
Author = to_state.apps.get_model(app_label, "Author")
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards(app_label, editor, from_state, to_state)
|
||||
Author = to_state.apps.get_model(app_label, "Author")
|
||||
with self.assertRaises(IntegrityError), transaction.atomic():
|
||||
Author.objects.create(name="Albert", rebate="10$")
|
||||
author = Author.objects.create(name="Albert", rebate="10%")
|
||||
self.assertEqual(Author.objects.get(), author)
|
||||
# Right-hand-side baked "%" literals should not be used for parameters
|
||||
# interpolation.
|
||||
check = ~models.Q(surname__startswith=models.F("name"))
|
||||
constraint = models.CheckConstraint(check=check, name="name_constraint_rhs")
|
||||
operation = migrations.AddConstraint("Author", constraint)
|
||||
from_state = to_state
|
||||
to_state = from_state.clone()
|
||||
operation.state_forwards(app_label, to_state)
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_forwards(app_label, editor, from_state, to_state)
|
||||
Author = to_state.apps.get_model(app_label, "Author")
|
||||
try:
|
||||
with transaction.atomic():
|
||||
Author.objects.create(**valid).delete()
|
||||
with self.assertRaises(IntegrityError), transaction.atomic():
|
||||
Author.objects.create(name="Albert", surname="Alberto")
|
||||
Author.objects.create(**invalid)
|
||||
finally:
|
||||
with connection.schema_editor() as editor:
|
||||
operation.database_backwards(
|
||||
app_label, editor, from_state, to_state
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature("supports_table_check_constraints")
|
||||
def test_add_or_constraint(self):
|
||||
|
Loading…
Reference in New Issue
Block a user