diff options
| author | John Parton <john.parton.iv@gmail.com> | 2024-09-04 18:13:05 -0500 |
|---|---|---|
| committer | Sarah Boyce <42296566+sarahboyce@users.noreply.github.com> | 2025-01-06 10:08:32 +0100 |
| commit | 40d5516385448a73426aad396778f369a363eda9 (patch) | |
| tree | 50e398547b428cbf1aa5d1a9ec6cd44d1fee7f76 /tests/db_functions/json | |
| parent | d734f1651ccc0a74325f7b55f7eecc68edef6453 (diff) | |
Fixed #35718 -- Add JSONArray to django.db.models.functions.
Co-authored-by: Sarah Boyce <42296566+sarahboyce@users.noreply.github.com>
Co-authored-by: Mariusz Felisiak <felisiak.mariusz@gmail.com>
Diffstat (limited to 'tests/db_functions/json')
| -rw-r--r-- | tests/db_functions/json/test_json_array.py | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/tests/db_functions/json/test_json_array.py b/tests/db_functions/json/test_json_array.py new file mode 100644 index 0000000000..406511ae4d --- /dev/null +++ b/tests/db_functions/json/test_json_array.py @@ -0,0 +1,177 @@ +import unittest + +from django.db import NotSupportedError, connection +from django.db.models import CharField, F, Value +from django.db.models.functions import Cast, JSONArray, JSONObject, Lower +from django.test import TestCase +from django.test.testcases import skipIfDBFeature, skipUnlessDBFeature +from django.utils import timezone + +from ..models import Article, Author + + +@skipUnlessDBFeature("supports_json_field") +class JSONArrayTests(TestCase): + @classmethod + def setUpTestData(cls): + Author.objects.create(name="Ivan Ivanov", alias="iivanov") + + def test_empty(self): + obj = Author.objects.annotate(json_array=JSONArray()).first() + self.assertEqual(obj.json_array, []) + + def test_basic(self): + obj = Author.objects.annotate( + json_array=JSONArray(Value("name"), F("name")) + ).first() + self.assertEqual(obj.json_array, ["name", "Ivan Ivanov"]) + + def test_expressions(self): + obj = Author.objects.annotate( + json_array=JSONArray( + Lower("name"), + F("alias"), + F("goes_by"), + Value(30000.15), + F("age") * 2, + ) + ).first() + self.assertEqual( + obj.json_array, + [ + "ivan ivanov", + "iivanov", + None, + 30000.15, + 60, + ], + ) + + def test_nested_json_array(self): + obj = Author.objects.annotate( + json_array=JSONArray( + F("name"), + JSONArray(F("alias"), F("age")), + ) + ).first() + self.assertEqual( + obj.json_array, + [ + "Ivan Ivanov", + ["iivanov", 30], + ], + ) + + def test_nested_empty_json_array(self): + obj = Author.objects.annotate( + json_array=JSONArray( + F("name"), + JSONArray(), + ) + ).first() + self.assertEqual( + obj.json_array, + [ + "Ivan Ivanov", + [], + ], + ) + + def test_textfield(self): + Article.objects.create( + title="The Title", + text="x" * 4000, + written=timezone.now(), + ) + obj = Article.objects.annotate(json_array=JSONArray(F("text"))).first() + self.assertEqual(obj.json_array, ["x" * 4000]) + + @unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific tests") + def test_explicit_cast(self): + qs = Author.objects.annotate( + json_array=JSONArray(Cast("age", CharField())) + ).values("json_array") + with self.assertNumQueries(1) as ctx: + self.assertSequenceEqual(qs, [{"json_array": ["30"]}]) + sql = ctx.captured_queries[0]["sql"] + self.assertIn("::varchar", sql) + self.assertNotIn("::varchar)::varchar", sql) + + def test_order_by_key(self): + qs = Author.objects.annotate(arr=JSONArray(F("alias"))).order_by("arr__0") + self.assertQuerySetEqual(qs, Author.objects.order_by("alias")) + + def test_order_by_nested_key(self): + qs = Author.objects.annotate(arr=JSONArray(JSONArray(F("alias")))).order_by( + "-arr__0__0" + ) + self.assertQuerySetEqual(qs, Author.objects.order_by("-alias")) + + +@skipIfDBFeature("supports_json_field") +class JSONArrayNotSupportedTests(TestCase): + def test_not_supported(self): + msg = "JSONFields are not supported on this database backend." + with self.assertRaisesMessage(NotSupportedError, msg): + Author.objects.annotate(json_array=JSONArray()).first() + + +@skipUnlessDBFeature("has_json_object_function", "supports_json_field") +class JSONArrayObjectTests(TestCase): + @classmethod + def setUpTestData(cls): + Author.objects.create(name="Ivan Ivanov", alias="iivanov") + + def test_nested_json_array_object(self): + obj = Author.objects.annotate( + json_array=JSONArray( + JSONObject( + name1="name", + nested_json_object1=JSONObject(alias1="alias", age1="age"), + ), + JSONObject( + name2="name", + nested_json_object2=JSONObject(alias2="alias", age2="age"), + ), + ) + ).first() + self.assertEqual( + obj.json_array, + [ + { + "name1": "Ivan Ivanov", + "nested_json_object1": {"alias1": "iivanov", "age1": 30}, + }, + { + "name2": "Ivan Ivanov", + "nested_json_object2": {"alias2": "iivanov", "age2": 30}, + }, + ], + ) + + def test_nested_json_object_array(self): + obj = Author.objects.annotate( + json_object=JSONObject( + name="name", + nested_json_array=JSONArray( + JSONObject(alias1="alias", age1="age"), + JSONObject(alias2="alias", age2="age"), + ), + ) + ).first() + self.assertEqual( + obj.json_object, + { + "name": "Ivan Ivanov", + "nested_json_array": [ + {"alias1": "iivanov", "age1": 30}, + {"alias2": "iivanov", "age2": 30}, + ], + }, + ) + + def test_order_by_nested_key(self): + qs = Author.objects.annotate( + arr=JSONArray(JSONObject(alias=F("alias"))) + ).order_by("-arr__0__alias") + self.assertQuerySetEqual(qs, Author.objects.order_by("-alias")) |
