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)
|
from_state = self.apply_operations(app_label, ProjectState(), operations)
|
||||||
# "%" generated in startswith lookup should be escaped in a way that is
|
checks = [
|
||||||
# considered a leading wildcard.
|
# "%" generated in startswith lookup should be escaped in a way
|
||||||
check = models.Q(name__startswith="Albert")
|
# that is considered a leading wildcard.
|
||||||
constraint = models.CheckConstraint(check=check, name="name_constraint")
|
(
|
||||||
operation = migrations.AddConstraint("Author", constraint)
|
models.Q(name__startswith="Albert"),
|
||||||
to_state = from_state.clone()
|
{"name": "Alberta"},
|
||||||
operation.state_forwards(app_label, to_state)
|
{"name": "Artur"},
|
||||||
with connection.schema_editor() as editor:
|
),
|
||||||
operation.database_forwards(app_label, editor, from_state, to_state)
|
# Literal "%" should be escaped in a way that is not a considered a
|
||||||
Author = to_state.apps.get_model(app_label, "Author")
|
# wildcard.
|
||||||
with self.assertRaises(IntegrityError), transaction.atomic():
|
(models.Q(rebate__endswith="%"), {"rebate": "10%"}, {"rebate": "10$"}),
|
||||||
Author.objects.create(name="Artur")
|
# Right-hand-side baked "%" literals should not be used for
|
||||||
# Literal "%" should be escaped in a way that is not a considered a
|
# parameters interpolation.
|
||||||
# wildcard.
|
(
|
||||||
check = models.Q(rebate__endswith="%")
|
~models.Q(surname__startswith=models.F("name")),
|
||||||
constraint = models.CheckConstraint(check=check, name="rebate_constraint")
|
{"name": "Albert"},
|
||||||
operation = migrations.AddConstraint("Author", constraint)
|
{"name": "Albert", "surname": "Alberto"},
|
||||||
from_state = to_state
|
),
|
||||||
to_state = from_state.clone()
|
]
|
||||||
operation.state_forwards(app_label, to_state)
|
for check, valid, invalid in checks:
|
||||||
Author = to_state.apps.get_model(app_label, "Author")
|
with self.subTest(check=check, valid=valid, invalid=invalid):
|
||||||
with connection.schema_editor() as editor:
|
constraint = models.CheckConstraint(check=check, name="constraint")
|
||||||
operation.database_forwards(app_label, editor, from_state, to_state)
|
operation = migrations.AddConstraint("Author", constraint)
|
||||||
Author = to_state.apps.get_model(app_label, "Author")
|
to_state = from_state.clone()
|
||||||
with self.assertRaises(IntegrityError), transaction.atomic():
|
operation.state_forwards(app_label, to_state)
|
||||||
Author.objects.create(name="Albert", rebate="10$")
|
with connection.schema_editor() as editor:
|
||||||
author = Author.objects.create(name="Albert", rebate="10%")
|
operation.database_forwards(app_label, editor, from_state, to_state)
|
||||||
self.assertEqual(Author.objects.get(), author)
|
Author = to_state.apps.get_model(app_label, "Author")
|
||||||
# Right-hand-side baked "%" literals should not be used for parameters
|
try:
|
||||||
# interpolation.
|
with transaction.atomic():
|
||||||
check = ~models.Q(surname__startswith=models.F("name"))
|
Author.objects.create(**valid).delete()
|
||||||
constraint = models.CheckConstraint(check=check, name="name_constraint_rhs")
|
with self.assertRaises(IntegrityError), transaction.atomic():
|
||||||
operation = migrations.AddConstraint("Author", constraint)
|
Author.objects.create(**invalid)
|
||||||
from_state = to_state
|
finally:
|
||||||
to_state = from_state.clone()
|
with connection.schema_editor() as editor:
|
||||||
operation.state_forwards(app_label, to_state)
|
operation.database_backwards(
|
||||||
with connection.schema_editor() as editor:
|
app_label, editor, from_state, to_state
|
||||||
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", surname="Alberto")
|
|
||||||
|
|
||||||
@skipUnlessDBFeature("supports_table_check_constraints")
|
@skipUnlessDBFeature("supports_table_check_constraints")
|
||||||
def test_add_or_constraint(self):
|
def test_add_or_constraint(self):
|
||||||
|
Loading…
Reference in New Issue
Block a user