1import json
2
3from django.test import TestCase
4
5from jsonfield.fields import JSONField
6from jsonfield.json import JSONString
7
8
9class TestFieldAPIMethods(TestCase):
10
11    def test_get_prep_value_always_json_dumps_if_not_null(self):
12        json_field_instance = JSONField(null=False)
13        value = {'a': 1}
14        prepared_value = json_field_instance.get_prep_value(value)
15        self.assertIsInstance(prepared_value, str)
16        self.assertDictEqual(value, json.loads(prepared_value))
17        already_json = json.dumps(value)
18        double_prepared_value = json_field_instance.get_prep_value(
19            already_json)
20        self.assertDictEqual(value,
21                             json.loads(json.loads(double_prepared_value)))
22        self.assertEqual(json_field_instance.get_prep_value(None), 'null')
23
24    def test_get_prep_value_can_return_none_if_null(self):
25        json_field_instance = JSONField(null=True)
26        value = {'a': 1}
27        prepared_value = json_field_instance.get_prep_value(value)
28        self.assertIsInstance(prepared_value, str)
29        self.assertDictEqual(value, json.loads(prepared_value))
30        already_json = json.dumps(value)
31        double_prepared_value = json_field_instance.get_prep_value(
32            already_json)
33        self.assertDictEqual(value,
34                             json.loads(json.loads(double_prepared_value)))
35        self.assertIs(json_field_instance.get_prep_value(None), None)
36
37    def test_deconstruct_default_kwargs(self):
38        field = JSONField()
39
40        _, _, _, kwargs = field.deconstruct()
41
42        self.assertNotIn('dump_kwargs', kwargs)
43        self.assertNotIn('load_kwargs', kwargs)
44
45    def test_deconstruct_non_default_kwargs(self):
46        field = JSONField(
47            dump_kwargs={'separators': (',', ':')},
48            load_kwargs={'object_pairs_hook': dict},
49        )
50
51        _, _, _, kwargs = field.deconstruct()
52
53        self.assertEqual(kwargs['dump_kwargs'], {'separators': (',', ':')})
54        self.assertEqual(kwargs['load_kwargs'], {'object_pairs_hook': dict})
55
56    def test_from_db_value_loaded_types(self):
57        values = [
58            # (label, db value, loaded type)
59            ('object', '{"a": "b"}', dict),
60            ('array', '[1, 2]', list),
61            ('string', '"test"', JSONString),
62            ('float', '1.2', float),
63            ('int', '1234', int),
64            ('bool', 'true', bool),
65            ('null', 'null', type(None)),
66        ]
67
68        for label, db_value, inst_type in values:
69            with self.subTest(type=label, db_value=db_value):
70                value = JSONField().from_db_value(db_value, None, None)
71
72                self.assertIsInstance(value, inst_type)
73