summaryrefslogtreecommitdiff
path: root/tests/postgres_tests
diff options
context:
space:
mode:
authorFlávio Juvenal <flaviojuvenal@gmail.com>2017-08-17 16:21:35 -0700
committerTim Graham <timograham@gmail.com>2017-10-20 13:17:22 -0400
commitf6e1789654e82bac08cead5a2d2a9132f6403f52 (patch)
treeabc80ed75f7c67ac7e44125e25c9898ff89fd68b /tests/postgres_tests
parent5ceaf14686ce626404afb6a5fbd3d8286410bf13 (diff)
Fixed #28577 -- Added checks for ArrayField and JSONField to prevent mutable defaults.
Diffstat (limited to 'tests/postgres_tests')
-rw-r--r--tests/postgres_tests/models.py2
-rw-r--r--tests/postgres_tests/test_array.py34
-rw-r--r--tests/postgres_tests/test_json.py41
3 files changed, 73 insertions, 4 deletions
diff --git a/tests/postgres_tests/models.py b/tests/postgres_tests/models.py
index fa390daaa8..35e76d0622 100644
--- a/tests/postgres_tests/models.py
+++ b/tests/postgres_tests/models.py
@@ -41,7 +41,7 @@ class PostgreSQLModel(models.Model):
class IntegerArrayModel(PostgreSQLModel):
- field = ArrayField(models.IntegerField(), default=[], blank=True)
+ field = ArrayField(models.IntegerField(), default=list, blank=True)
class NullableIntegerArrayModel(PostgreSQLModel):
diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py
index e2e4ccdeb2..77ac049ce4 100644
--- a/tests/postgres_tests/test_array.py
+++ b/tests/postgres_tests/test_array.py
@@ -4,7 +4,7 @@ import unittest
import uuid
from django import forms
-from django.core import exceptions, serializers, validators
+from django.core import checks, exceptions, serializers, validators
from django.core.exceptions import FieldError
from django.core.management import call_command
from django.db import IntegrityError, connection, models
@@ -424,6 +424,38 @@ class TestChecks(PostgreSQLTestCase):
self.assertEqual(len(errors), 1)
self.assertEqual(errors[0].id, 'postgres.E002')
+ def test_invalid_default(self):
+ class MyModel(PostgreSQLModel):
+ field = ArrayField(models.IntegerField(), default=[])
+
+ model = MyModel()
+ self.assertEqual(model.check(), [
+ checks.Warning(
+ msg=(
+ "ArrayField default should be a callable instead of an "
+ "instance so that it's not shared between all field "
+ "instances."
+ ),
+ hint='Use a callable instead, e.g., use `list` instead of `[]`.',
+ obj=MyModel._meta.get_field('field'),
+ id='postgres.E003',
+ )
+ ])
+
+ def test_valid_default(self):
+ class MyModel(PostgreSQLModel):
+ field = ArrayField(models.IntegerField(), default=list)
+
+ model = MyModel()
+ self.assertEqual(model.check(), [])
+
+ def test_valid_default_none(self):
+ class MyModel(PostgreSQLModel):
+ field = ArrayField(models.IntegerField(), default=None)
+
+ model = MyModel()
+ self.assertEqual(model.check(), [])
+
def test_nested_field_checks(self):
"""
Nested ArrayFields are permitted.
diff --git a/tests/postgres_tests/test_json.py b/tests/postgres_tests/test_json.py
index cdabca04d6..acbd855f1a 100644
--- a/tests/postgres_tests/test_json.py
+++ b/tests/postgres_tests/test_json.py
@@ -2,13 +2,14 @@ import datetime
import uuid
from decimal import Decimal
-from django.core import exceptions, serializers
+from django.core import checks, exceptions, serializers
from django.core.serializers.json import DjangoJSONEncoder
from django.forms import CharField, Form, widgets
+from django.test.utils import isolate_apps
from django.utils.html import escape
from . import PostgreSQLTestCase
-from .models import JSONModel
+from .models import JSONModel, PostgreSQLModel
try:
from django.contrib.postgres import forms
@@ -259,6 +260,42 @@ class TestQuerying(PostgreSQLTestCase):
self.assertTrue(JSONModel.objects.filter(field__foo__iregex=r'^bAr$').exists())
+@isolate_apps('postgres_tests')
+class TestChecks(PostgreSQLTestCase):
+
+ def test_invalid_default(self):
+ class MyModel(PostgreSQLModel):
+ field = JSONField(default={})
+
+ model = MyModel()
+ self.assertEqual(model.check(), [
+ checks.Warning(
+ msg=(
+ "JSONField default should be a callable instead of an "
+ "instance so that it's not shared between all field "
+ "instances."
+ ),
+ hint='Use a callable instead, e.g., use `dict` instead of `{}`.',
+ obj=MyModel._meta.get_field('field'),
+ id='postgres.E003',
+ )
+ ])
+
+ def test_valid_default(self):
+ class MyModel(PostgreSQLModel):
+ field = JSONField(default=dict)
+
+ model = MyModel()
+ self.assertEqual(model.check(), [])
+
+ def test_valid_default_none(self):
+ class MyModel(PostgreSQLModel):
+ field = JSONField(default=None)
+
+ model = MyModel()
+ self.assertEqual(model.check(), [])
+
+
class TestSerialization(PostgreSQLTestCase):
test_data = (
'[{"fields": {"field": {"a": "b", "c": null}, "field_custom": null}, '