From adcd1dda1c310b328767458f53661da5e281cd9b Mon Sep 17 00:00:00 2001 From: Davis Raymond Muro Date: Tue, 28 Jul 2020 10:45:54 +0300 Subject: [PATCH] Retrieve root node name from XForm survey object --- .../viewsets/test_xform_submission_viewset.py | 9 +++-- onadata/libs/serializers/data_serializer.py | 3 +- onadata/libs/utils/logger_tools.py | 37 +++++++++++++++++-- 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/onadata/apps/api/tests/viewsets/test_xform_submission_viewset.py b/onadata/apps/api/tests/viewsets/test_xform_submission_viewset.py index ee0d048a9c..d5ace9d464 100644 --- a/onadata/apps/api/tests/viewsets/test_xform_submission_viewset.py +++ b/onadata/apps/api/tests/viewsets/test_xform_submission_viewset.py @@ -556,16 +556,17 @@ def test_rapidpro_post_submission(self): self.assertContains(response, 'Successful submission', status_code=201) self.assertTrue(response.has_header('Date')) self.assertEqual(response['Location'], 'http://testserver/submission') - # InstanceID is returned as uuid: + # InstanceID is returned as uuid:. # Retrieving the uuid without the prefix in order to retrieve - # the actual instance + # the Instance object uuid = response.data.get('instanceID').split(':')[1] instance = Instance.objects.get(uuid=uuid) expected_xml = ( - "<{self.xform.survey.name} id=" "'transportation_2011_07_25'>orange" - "") + f"") self.assertEqual(instance.xml, expected_xml) + self.assertEqual(self.xform.survey.name, 'data') def test_legacy_rapidpro_post_submission(self): """ diff --git a/onadata/libs/serializers/data_serializer.py b/onadata/libs/serializers/data_serializer.py index 59e247639c..af3e3d93de 100644 --- a/onadata/libs/serializers/data_serializer.py +++ b/onadata/libs/serializers/data_serializer.py @@ -46,7 +46,8 @@ def create_submission(request, username, data_dict, xform_id): """ Returns validated data object instances """ - xml_string = dict2xform(data_dict, xform_id, root='data') + xml_string = dict2xform( + data_dict, xform_id, username=username) xml_file = BytesIO(xml_string.encode('utf-8')) error, instance = safe_create_instance(username, xml_file, [], None, diff --git a/onadata/libs/utils/logger_tools.py b/onadata/libs/utils/logger_tools.py index 76b10c3158..1116f9c4c8 100644 --- a/onadata/libs/utils/logger_tools.py +++ b/onadata/libs/utils/logger_tools.py @@ -112,10 +112,41 @@ def _get_instance(xml, new_uuid, submitted_by, status, xform, checksum): return instance -def dict2xform(jsform, form_id, root=None): +def dict2xform(jsform, form_id, root=None, username=None): + """ + Converts a dictionary containing submission data into an XML + Submission for the appropriate form. + + :param jsform (dict): A python dictionary object containing the submission + data + :param form_id (str or XForm): An XForm object or a string value + representing the forms id_string + :param root (str): An optional string that should be used as the + root nodes name. Defaults to None + :param: username (str): An optional string representing a users + username. Used alongside the `form_id` to + locate the XForm object the user is + trying to submit data too. Defaults to None + :returns: Returns a string containing the Submission XML + :rtype: str + """ if not root: - root = form_id - return u"<{0} id='{1}'>{2}".format( + if username: + if isinstance(form_id, XForm): + root = form_id.survey.name + else: + try: + form = XForm.objects.filter( + id_string__iexact=form_id, + user__username__iexact=username, + deleted_at__isnull=True).first() + root = form.survey.name + except XForm.DoesNotExist: + root = 'data' + else: + root = 'data' + + return "<{0} id='{1}'>{2}".format( root, form_id, dict2xml(jsform))