diff options
Diffstat (limited to 'tests/postgres_tests/test_app_installed_check.py')
| -rw-r--r-- | tests/postgres_tests/test_app_installed_check.py | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/tests/postgres_tests/test_app_installed_check.py b/tests/postgres_tests/test_app_installed_check.py new file mode 100644 index 0000000000..95315384e6 --- /dev/null +++ b/tests/postgres_tests/test_app_installed_check.py @@ -0,0 +1,142 @@ +from django.core import checks +from django.db import models +from django.test import modify_settings +from django.test.utils import isolate_apps + +from . import PostgreSQLTestCase +from .fields import ( + BigIntegerRangeField, + DateRangeField, + DateTimeRangeField, + DecimalRangeField, + HStoreField, + IntegerRangeField, + SearchVectorField, +) +from .models import IntegerArrayModel, NestedIntegerArrayModel, PostgreSQLModel + +try: + from django.contrib.postgres.constraints import ExclusionConstraint + from django.contrib.postgres.fields.ranges import RangeOperators + from django.contrib.postgres.indexes import GinIndex, PostgresIndex + from django.contrib.postgres.search import SearchQueryField +except ImportError: + pass + + +@isolate_apps("postgres_tests") +class TestPostgresAppInstalledCheck(PostgreSQLTestCase): + + def _make_error(self, obj, klass_name): + """Helper to create postgres.E005 error for specific objects.""" + return checks.Error( + "'django.contrib.postgres' must be in INSTALLED_APPS in order to " + f"use {klass_name}.", + obj=obj, + id="postgres.E005", + ) + + def assert_model_check_errors(self, model_class, expected_errors): + errors = model_class.check(databases=self.databases) + self.assertEqual(errors, []) + with modify_settings(INSTALLED_APPS={"remove": "django.contrib.postgres"}): + errors = model_class.check(databases=self.databases) + self.assertEqual(errors, expected_errors) + + def test_indexes(self): + class IndexModel(PostgreSQLModel): + field = models.IntegerField() + + class Meta: + indexes = [ + PostgresIndex(fields=["id"], name="postgres_index_test"), + GinIndex(fields=["field"], name="gin_index_test"), + ] + + self.assert_model_check_errors( + IndexModel, + [ + self._make_error(IndexModel, "PostgresIndex"), + self._make_error(IndexModel, "GinIndex"), + ], + ) + + def test_exclusion_constraint(self): + class ExclusionModel(PostgreSQLModel): + value = models.IntegerField() + + class Meta: + constraints = [ + ExclusionConstraint( + name="exclude_equal", + expressions=[("value", RangeOperators.EQUAL)], + ) + ] + + self.assert_model_check_errors( + ExclusionModel, [self._make_error(ExclusionModel, "ExclusionConstraint")] + ) + + def test_array_field(self): + field = IntegerArrayModel._meta.get_field("field") + self.assert_model_check_errors( + IntegerArrayModel, + [self._make_error(field, "ArrayField")], + ) + + def test_nested_array_field(self): + """Inner ArrayField does not cause a postgres.E001 error.""" + field = NestedIntegerArrayModel._meta.get_field("field") + self.assert_model_check_errors( + NestedIntegerArrayModel, + [ + self._make_error(field, "ArrayField"), + ], + ) + + def test_hstore_field(self): + class HStoreFieldModel(PostgreSQLModel): + field = HStoreField() + + field = HStoreFieldModel._meta.get_field("field") + self.assert_model_check_errors( + HStoreFieldModel, + [ + self._make_error(field, "HStoreField"), + ], + ) + + def test_range_fields(self): + class RangeFieldsModel(PostgreSQLModel): + int_range = IntegerRangeField() + bigint_range = BigIntegerRangeField() + decimal_range = DecimalRangeField() + datetime_range = DateTimeRangeField() + date_range = DateRangeField() + + expected_errors = [ + self._make_error(field, field.__class__.__name__) + for field in [ + RangeFieldsModel._meta.get_field("int_range"), + RangeFieldsModel._meta.get_field("bigint_range"), + RangeFieldsModel._meta.get_field("decimal_range"), + RangeFieldsModel._meta.get_field("datetime_range"), + RangeFieldsModel._meta.get_field("date_range"), + ] + ] + self.assert_model_check_errors(RangeFieldsModel, expected_errors) + + def test_search_vector_field(self): + class SearchModel(PostgreSQLModel): + search_vector = SearchVectorField() + search_query = SearchQueryField() + + vector_field = SearchModel._meta.get_field("search_vector") + query_field = SearchModel._meta.get_field("search_query") + self.assert_model_check_errors( + SearchModel, + [ + self._make_error(vector_field, "SearchVectorField"), + self._make_error(query_field, "SearchQueryField"), + ], + ) |
