From ad56227970dcce168b9cb86d999f2542a2837573 Mon Sep 17 00:00:00 2001 From: Kelvin Muchiri Date: Thu, 27 Jun 2024 13:11:36 +0300 Subject: [PATCH] fix 0 integer, decimal values parsed as string when saving json (#2621) --- onadata/apps/logger/models/instance.py | 8 +-- .../apps/logger/tests/models/test_instance.py | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+), 6 deletions(-) diff --git a/onadata/apps/logger/models/instance.py b/onadata/apps/logger/models/instance.py index e84aafe019..6543423a06 100644 --- a/onadata/apps/logger/models/instance.py +++ b/onadata/apps/logger/models/instance.py @@ -421,17 +421,13 @@ def numeric_converter(self, json_dict, numeric_fields=None): numeric_fields = get_numeric_fields(self.xform) for key, value in json_dict.items(): if isinstance(value, str) and key in numeric_fields: - converted_value = numeric_checker(value) - if converted_value: - json_dict[key] = converted_value + json_dict[key] = numeric_checker(value) elif isinstance(value, dict): json_dict[key] = self.numeric_converter(value, numeric_fields) elif isinstance(value, list): for k, v in enumerate(value): if isinstance(v, str) and key in numeric_fields: - converted_value = numeric_checker(v) - if converted_value: - json_dict[key] = converted_value + json_dict[key] = numeric_checker(v) elif isinstance(v, dict): value[k] = self.numeric_converter(v, numeric_fields) return json_dict diff --git a/onadata/apps/logger/tests/models/test_instance.py b/onadata/apps/logger/tests/models/test_instance.py index 9d4e953fe7..dc160c322b 100644 --- a/onadata/apps/logger/tests/models/test_instance.py +++ b/onadata/apps/logger/tests/models/test_instance.py @@ -1005,3 +1005,70 @@ def test_create_entity_exists(self): "label": "300cm purpleheart", }, ) + + def test_parse_numbers(self): + """Integers and decimals are parsed correctly""" + md = """ + | survey | + | | type | name | label | + | | integer | num_integer | I am an integer| + | | decimal | num_decimal | I am a decimal | + """ + self._publish_markdown(md, self.user) + xform = XForm.objects.order_by("-pk").first() + xml = ( + '' + "" + "bd4278ad2fd8418fba5e6a822e2623e7" + "" + "4" + "5.5" + "" + "uuid:49d75027-405a-4e08-be71-db9a75c70fc2" + "" + "" + ) + instance = Instance.objects.create(xml=xml, xform=xform) + instance.refresh_from_db() + + self.assertEqual(instance.json["num_integer"], 4) + self.assertEqual(instance.json["num_decimal"], 5.5) + + # Test 0 + xml = ( + '' + "" + "bd4278ad2fd8418fba5e6a822e2623e7" + "" + "0" + "0.0" + "" + "uuid:59d75027-405a-4e08-be71-db9a75c70fc2" + "" + "" + ) + instance = Instance.objects.create(xml=xml, xform=xform) + instance.refresh_from_db() + self.assertEqual(instance.json["num_integer"], 0) + self.assertEqual(instance.json["num_decimal"], 0.0) + + # Test negatives + xml = ( + '' + "" + "bd4278ad2fd8418fba5e6a822e2623e7" + "" + "-1" + "-1.0" + "" + "uuid:69d75027-405a-4e08-be71-db9a75c70fc2" + "" + "" + ) + instance = Instance.objects.create(xml=xml, xform=xform) + instance.refresh_from_db() + self.assertEqual(instance.json["num_integer"], -1) + self.assertEqual(instance.json["num_decimal"], -1.0)