]> ToastFreeware Gitweb - philipp/winterrodeln/wrpylib.git/blob - tests/test_json_validate.py
Nähere Details zu Rodelverleihs.
[philipp/winterrodeln/wrpylib.git] / tests / test_json_validate.py
1 import unittest
2 from copy import deepcopy
3 from typing import Dict
4
5 from wrpylib.json_tools import order_json_keys, _resolve_ref
6
7 schema_object: Dict = {
8     "$schema": "http://json-schema.org/draft-07/schema#",
9     "type": "object",
10     "required": [
11         "name"
12     ],
13     "properties": {
14         "name": {
15             "type": "string",
16         },
17         "aliases": {
18             "type": "array",
19             "items": {
20                 "type": "string",
21                 "title": "Alternativer Name"
22             }
23         },
24         "entry_under_construction": {
25             "type": "boolean",
26             "default": True,
27         },
28         "length": {
29             "type": "number",
30             "minimum": 1,
31             "optional": True
32         },
33         "difficulty": {
34             "type": "string",
35             "enum": [
36                 "leicht",
37                 "mittel",
38                 "schwer"
39             ],
40         },
41         "walkup_time": {
42             "type": "number",
43         },
44     }
45 }
46
47
48 schema_array = {
49     "$schema": "http://json-schema.org/draft-07/schema#",
50     "type": "array",
51     "items": {
52         "type": "string",
53     }
54 }
55
56
57 class TestResolveRef(unittest.TestCase):
58     def test_no_ref(self):
59         sub_schema = schema_object['properties']['aliases']
60         actual = _resolve_ref(sub_schema, schema_object)
61         self.assertEqual(actual, sub_schema)
62
63     def test_ref(self):
64         root_schema = schema_object.copy()
65         root_schema["definitions"] = {
66             "weblink": {
67                 "type": "string",
68             }
69         }
70         sub_schema = {
71             "$ref": "#/definitions/weblink"
72         }
73         expected = {
74             "type": "string",
75         }
76         actual = _resolve_ref(sub_schema, root_schema)
77         self.assertEqual(expected, actual)
78
79
80 class TestOrderJsonKeys(unittest.TestCase):
81     def test_string_empty(self):
82         actual = order_json_keys('', {"type": "string"})
83         self.assertEqual('', actual)
84
85     def test_string_valid(self):
86         actual = order_json_keys('äüß', {"type": "string"})
87         self.assertEqual('äüß', actual)
88
89     def test_string_wrong_types(self):
90         for value in [True, False, None, 0, 1, 0.5, [], ['abc'], {}, {'a': 'b'}]:
91             with self.subTest(f'Try invalid value {value}.', value=value):
92                 with self.assertRaises(ValueError):
93                     order_json_keys(value, {"type": "string"})
94
95     def test_number_valid(self):
96         for value in [0, 1, -10, 8.8, 0.0, -1024.9]:
97             with self.subTest(f'Valid number {value}.', value=value):
98                 actual = order_json_keys(value, {"type": "number"})
99                 self.assertEqual(value, actual)
100
101     def test_number_wrong_types(self):
102         for value in [True, False, None, '', 'abc', [], [0], [1], {}, {'a': 1}]:
103             with self.subTest(f'Try invalid value {value}.', value=value):
104                 with self.assertRaises(ValueError):
105                     order_json_keys(value, {"type": "number"})
106
107     def test_object_empty(self):
108         schema = schema_object.copy()
109         del schema['required']
110         actual = order_json_keys({}, schema)
111         self.assertEqual({}, actual)
112
113     def test_object_missing_keys(self):
114         with self.assertRaises(ValueError):
115             order_json_keys({}, schema_object)
116
117     def test_object_some_keys(self):
118         actual = order_json_keys({'name': 'X', 'walkup_time': 30, 'difficulty': 'mittel'}, schema_object)
119         self.assertEqual({'name': 'X', 'difficulty': 'mittel', 'walkup_time': 30}, actual)
120
121     def test_object_all_keys(self):
122         value = {
123             'walkup_time': 120,
124             'aliases': ['c', 'a', 'b'],
125             'entry_under_construction': False,
126             'name': 'ÖÄÜ',
127             'difficulty': 'leicht',
128             'length': 60,
129         }
130         expected = {
131             'name': 'ÖÄÜ',
132             'aliases': ['c', 'a', 'b'],
133             'entry_under_construction': False,
134             'length': 60,
135             'difficulty': 'leicht',
136             'walkup_time': 120,
137         }
138         actual = order_json_keys(value, schema_object)
139         self.assertEqual(expected, actual)
140
141     def test_object_additional_keys(self):
142         value = {
143             'walkup_time': 120,
144             'aliases': ['c', 'a', 'b'],
145             'entry_under_construction': False,
146             'name': 'ÖÄÜ',
147             'surprise': True,
148             'difficulty': 'leicht',
149             'length': 60,
150         }
151         expected = {
152             'name': 'ÖÄÜ',
153             'aliases': ['c', 'a', 'b'],
154             'entry_under_construction': False,
155             'length': 60,
156             'difficulty': 'leicht',
157             'walkup_time': 120,
158             'surprise': True,
159         }
160         actual = order_json_keys(value, schema_object)
161         self.assertEqual(expected, actual)
162
163     def test_object_forbidden_additional_keys(self):
164         value = {
165             'name': 'abc',
166             'surprise': True,
167             'difficulty': 'leicht',
168         }
169         schema = schema_object.copy()
170         schema['additionalProperties'] = False
171         with self.assertRaises(ValueError):
172             order_json_keys(value, schema)
173
174     def test_object_nested(self):
175         schema = deepcopy(schema_object)
176         schema['properties']['nested'] = schema_object
177         value = {
178             'nested': {
179                 'length': 3,
180                 'name': 'Mustermann',
181             },
182             'name': 'parent',
183         }
184         expected = {
185             'name': 'parent',
186             'nested': {
187                 'name': 'Mustermann',
188                 'length': 3,
189             }
190         }
191         actual = order_json_keys(value, schema)
192         self.assertEqual(expected, actual)
193
194     def test_object_nested_wrong_type(self):
195         schema = deepcopy(schema_object)
196         schema['properties']['nested'] = schema_object
197         with self.assertRaises(ValueError) as cm:
198             order_json_keys({'name': 'name', 'nested': {'name': True}}, schema)
199         self.assertIn("['nested']['name']", str(cm.exception))
200
201     def test_array_empty(self):
202         schema = schema_array
203         actual = order_json_keys([], schema)
204         self.assertEqual([], actual)
205
206     def test_array_string(self):
207         schema = schema_array
208         actual = order_json_keys(['', 'a', 'ßöÄ'], schema)
209         self.assertEqual(['', 'a', 'ßöÄ'], actual)
210
211     def test_array_number(self):
212         schema = deepcopy(schema_array)
213         schema['items']['type'] = "number"
214         value = [0, 6.3, -3]
215         actual = order_json_keys(value, schema)
216         self.assertEqual(value, actual)
217
218     def test_array_object(self):
219         schema = deepcopy(schema_array)
220         schema['items']['type'] = "object"
221         value = [{}, {'a': 'b'}]
222         actual = order_json_keys(value, schema)
223         self.assertEqual(value, actual)
224
225     def test_array_array(self):
226         schema = deepcopy(schema_array)
227         schema['items']['type'] = "array"
228         value = [[], [3], [6, 8, 3.3]]
229         actual = order_json_keys(value, schema)
230         self.assertEqual(value, actual)
231
232     def test_array_boolean(self):
233         schema = deepcopy(schema_array)
234         schema['items']['type'] = "boolean"
235         value = [False, True, False]
236         actual = order_json_keys(value, schema)
237         self.assertEqual(value, actual)
238
239     def test_array_null(self):
240         schema = deepcopy(schema_array)
241         schema['items']['type'] = "null"
242         value = [None, None]
243         actual = order_json_keys(value, schema)
244         self.assertEqual(value, actual)
245
246     def test_array_wrong_string_types(self):
247         schema = {
248             "type": "array",
249             "items": {
250                 "type": "string",
251             }
252         }
253         for v in [7, 0.4, {}, {'a': 'b'}, [], [1, 2, 3], True, False, None]:
254             value = [v]
255             with self.subTest(f'Try invalid value {value}.', value=value):
256                 with self.assertRaises(ValueError):
257                     order_json_keys(value, schema)
258
259     def test_array_mixed_types(self):
260         schema = {
261             "type": "array",
262             "items": {
263                 "type": "string",
264             }
265         }
266         for v in [7, 0.4, {}, {'a': 'b'}, [], [1, 2, 3], True, False, None]:
267             value = ['a', v]
268             with self.subTest(f'Try invalid value {value}.', value=value):
269                 with self.assertRaises(ValueError):
270                     order_json_keys(value, schema)
271
272     def test_boolean_valid(self):
273         for value in [False, True]:
274             with self.subTest(f'Valid boolean {value}.', value=value):
275                 actual = order_json_keys(value, {"type": "boolean"})
276                 self.assertEqual(value, actual)
277
278     def test_boolean_wrong_types(self):
279         for value in [0, 1, -3, 10, 5.5, None, '', 'True', [], [True], [False], {}, {'a': True}]:
280             with self.subTest(f'Try invalid value {value}.', value=value):
281                 with self.assertRaises(ValueError):
282                     order_json_keys(value, {"type": "boolean"})
283
284     def test_null_valid(self):
285         actual = order_json_keys(None, {"type": "null"})
286         self.assertEqual(None, actual)
287
288     def test_null_wrong_types(self):
289         for value in [True, False, 0, 1, -3, 10, 5.5, '', 'abc', [], [0], [1], {}, {'a': 1}]:
290             with self.subTest(f'Try invalid value {value}.', value=value):
291                 with self.assertRaises(ValueError):
292                     order_json_keys(value, {"type": "null"})