File: test_app_installed_check.py

package info (click to toggle)
python-django 3%3A6.0~alpha1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 62,204 kB
  • sloc: python: 370,694; javascript: 19,376; xml: 211; makefile: 187; sh: 28
file content (142 lines) | stat: -rw-r--r-- 4,945 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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"),
            ],
        )