diff options
author | Gagaro <gagaro42@gmail.com> | 2022-01-31 16:04:13 +0100 |
---|---|---|
committer | Mariusz Felisiak <felisiak.mariusz@gmail.com> | 2022-05-10 11:22:23 +0200 |
commit | 667105877e6723c6985399803a364848891513cc (patch) | |
tree | b6b3a9fe9f2c8767bc6f6a68f0580eef021b2b55 /tests/postgres_tests | |
parent | 441103a04d1d167dc870eaaf90e3fba974f67c93 (diff) | |
download | django-667105877e6723c6985399803a364848891513cc.tar.gz |
Fixed #30581 -- Added support for Meta.constraints validation.
Thanks Simon Charette, Keryn Knight, and Mariusz Felisiak for reviews.
Diffstat (limited to 'tests/postgres_tests')
-rw-r--r-- | tests/postgres_tests/test_constraints.py | 101 |
1 files changed, 75 insertions, 26 deletions
diff --git a/tests/postgres_tests/test_constraints.py b/tests/postgres_tests/test_constraints.py index 377af41042..b8e53eb4a0 100644 --- a/tests/postgres_tests/test_constraints.py +++ b/tests/postgres_tests/test_constraints.py @@ -2,6 +2,7 @@ import datetime from unittest import mock from django.contrib.postgres.indexes import OpClass +from django.core.exceptions import ValidationError from django.db import IntegrityError, NotSupportedError, connection, transaction from django.db.models import ( CheckConstraint, @@ -612,18 +613,26 @@ class ExclusionConstraintTests(PostgreSQLTestCase): timezone.datetime(2018, 6, 28), timezone.datetime(2018, 6, 29), ] - HotelReservation.objects.create( + reservation = HotelReservation.objects.create( datespan=DateRange(datetimes[0].date(), datetimes[1].date()), start=datetimes[0], end=datetimes[1], room=room102, ) + constraint.validate(HotelReservation, reservation) HotelReservation.objects.create( datespan=DateRange(datetimes[1].date(), datetimes[3].date()), start=datetimes[1], end=datetimes[3], room=room102, ) + HotelReservation.objects.create( + datespan=DateRange(datetimes[3].date(), datetimes[4].date()), + start=datetimes[3], + end=datetimes[4], + room=room102, + cancelled=True, + ) # Overlap dates. with self.assertRaises(IntegrityError), transaction.atomic(): reservation = HotelReservation( @@ -632,33 +641,58 @@ class ExclusionConstraintTests(PostgreSQLTestCase): end=datetimes[2], room=room102, ) + msg = f"Constraint “{constraint.name}” is violated." + with self.assertRaisesMessage(ValidationError, msg): + constraint.validate(HotelReservation, reservation) reservation.save() # Valid range. - HotelReservation.objects.bulk_create( - [ - # Other room. - HotelReservation( - datespan=(datetimes[1].date(), datetimes[2].date()), - start=datetimes[1], - end=datetimes[2], - room=room101, - ), - # Cancelled reservation. - HotelReservation( - datespan=(datetimes[1].date(), datetimes[1].date()), - start=datetimes[1], - end=datetimes[2], - room=room102, - cancelled=True, - ), - # Other adjacent dates. - HotelReservation( - datespan=(datetimes[3].date(), datetimes[4].date()), - start=datetimes[3], - end=datetimes[4], - room=room102, - ), - ] + other_valid_reservations = [ + # Other room. + HotelReservation( + datespan=(datetimes[1].date(), datetimes[2].date()), + start=datetimes[1], + end=datetimes[2], + room=room101, + ), + # Cancelled reservation. + HotelReservation( + datespan=(datetimes[1].date(), datetimes[1].date()), + start=datetimes[1], + end=datetimes[2], + room=room102, + cancelled=True, + ), + # Other adjacent dates. + HotelReservation( + datespan=(datetimes[3].date(), datetimes[4].date()), + start=datetimes[3], + end=datetimes[4], + room=room102, + ), + ] + for reservation in other_valid_reservations: + constraint.validate(HotelReservation, reservation) + HotelReservation.objects.bulk_create(other_valid_reservations) + # Excluded fields. + constraint.validate( + HotelReservation, + HotelReservation( + datespan=(datetimes[1].date(), datetimes[2].date()), + start=datetimes[1], + end=datetimes[2], + room=room102, + ), + exclude={"room"}, + ) + constraint.validate( + HotelReservation, + HotelReservation( + datespan=(datetimes[1].date(), datetimes[2].date()), + start=datetimes[1], + end=datetimes[2], + room=room102, + ), + exclude={"datespan", "start", "end", "room"}, ) @ignore_warnings(category=RemovedInDjango50Warning) @@ -731,6 +765,21 @@ class ExclusionConstraintTests(PostgreSQLTestCase): constraint_name, self.get_constraints(RangesModel._meta.db_table) ) + def test_validate_range_adjacent(self): + constraint = ExclusionConstraint( + name="ints_adjacent", + expressions=[("ints", RangeOperators.ADJACENT_TO)], + violation_error_message="Custom error message.", + ) + range_obj = RangesModel.objects.create(ints=(20, 50)) + constraint.validate(RangesModel, range_obj) + msg = "Custom error message." + with self.assertRaisesMessage(ValidationError, msg): + constraint.validate(RangesModel, RangesModel(ints=(10, 20))) + constraint.validate(RangesModel, RangesModel(ints=(10, 19))) + constraint.validate(RangesModel, RangesModel(ints=(51, 60))) + constraint.validate(RangesModel, RangesModel(ints=(10, 20)), exclude={"ints"}) + def test_expressions_with_params(self): constraint_name = "scene_left_equal" self.assertNotIn(constraint_name, self.get_constraints(Scene._meta.db_table)) |