From 1d4cbee39af2ec772d43a146ca724d34613c6a76 Mon Sep 17 00:00:00 2001 From: Olivier Dalang Date: Fri, 11 Aug 2023 16:06:07 +0200 Subject: [PATCH] contribute to constraints test - minimal --- tests/contribute_to_meta/__init__.py | 0 tests/contribute_to_meta/fields.py | 14 ++++++ .../contribute_to_meta/migrations/.gitignore | 1 + .../contribute_to_meta/migrations/__init__.py | 0 tests/contribute_to_meta/models.py | 14 ++++++ tests/contribute_to_meta/tests.py | 49 +++++++++++++++++++ 6 files changed, 78 insertions(+) create mode 100644 tests/contribute_to_meta/__init__.py create mode 100644 tests/contribute_to_meta/fields.py create mode 100644 tests/contribute_to_meta/migrations/.gitignore create mode 100644 tests/contribute_to_meta/migrations/__init__.py create mode 100644 tests/contribute_to_meta/models.py create mode 100644 tests/contribute_to_meta/tests.py diff --git a/tests/contribute_to_meta/__init__.py b/tests/contribute_to_meta/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/contribute_to_meta/fields.py b/tests/contribute_to_meta/fields.py new file mode 100644 index 0000000000..9bf530c838 --- /dev/null +++ b/tests/contribute_to_meta/fields.py @@ -0,0 +1,14 @@ +from django.db import models + + +class ConstraintField(models.CharField): + """A field that contributes a DB contraint to the model's Meta""" + + def contribute_to_class(self, cls, name, private_only=False): + super().contribute_to_class(cls, name, private_only) + cls._meta.constraints.append( + models.CheckConstraint( + check=models.Q(**{name: "valid"}), + name=f"test_constraint_{cls.__name__.lower()}", + ) + ) diff --git a/tests/contribute_to_meta/migrations/.gitignore b/tests/contribute_to_meta/migrations/.gitignore new file mode 100644 index 0000000000..26a35de2cd --- /dev/null +++ b/tests/contribute_to_meta/migrations/.gitignore @@ -0,0 +1 @@ +0001_initial.py diff --git a/tests/contribute_to_meta/migrations/__init__.py b/tests/contribute_to_meta/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/contribute_to_meta/models.py b/tests/contribute_to_meta/models.py new file mode 100644 index 0000000000..d680fa3574 --- /dev/null +++ b/tests/contribute_to_meta/models.py @@ -0,0 +1,14 @@ +from django.db import models + +from .fields import ConstraintField + + +class ModelA(models.Model): + field = ConstraintField(max_length=10) + + +class ModelC(models.Model): + class Meta: + constraints = [] + + field = ConstraintField(max_length=10) diff --git a/tests/contribute_to_meta/tests.py b/tests/contribute_to_meta/tests.py new file mode 100644 index 0000000000..6613588a4b --- /dev/null +++ b/tests/contribute_to_meta/tests.py @@ -0,0 +1,49 @@ +from pathlib import Path + +from django.core.management import call_command +from django.db import IntegrityError +from django.test import TestCase, skipUnlessDBFeature + +from .models import ModelA, ModelC + + +@skipUnlessDBFeature("supports_table_check_constraints") +class ConstraintsTests(TestCase): + """Check that the constraints allow valid values and reject invalid ones""" + + def test_ModelA_constraint(self): + ModelA.objects.create(field="valid") + with self.assertRaises(IntegrityError): + ModelA.objects.create(field="invalid") + + def test_ModelC_constraint(self): + ModelC.objects.create(field="valid") + with self.assertRaises(IntegrityError): + ModelC.objects.create(field="invalid") + + +class ConstraintsMigrationsTests(TestCase): + """Check that migrations correctly generate the constraints""" + + @classmethod + def setUpClass(cls): + super().setUpClass() + # Clean and recreate migration files for further inspection + init_file = Path(__file__).parent / "migrations" / "0001_initial.py" + init_file.unlink(missing_ok=True) + call_command("makemigrations", verbosity=0) + cls.migration_content = init_file.read_text() + + def test_ModelA(self): + # check migration contents + self.assertTrue( + "test_constraint_modela" in self.migration_content, + "Could not find constraint `test_constraint_modela` in migration", + ) + + def test_ModelC(self): + # check migration contents + self.assertTrue( + "test_constraint_modelc" in self.migration_content, + "Could not find constraint `test_constraint_modelc` in migration", + )