Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(OpenRosa): support XLSForm name setting TASK-1074 #5137

Merged
merged 5 commits into from
Nov 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions kobo/apps/openrosa/apps/viewer/models/data_dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
DictOrganizer,
)
from kobo.apps.openrosa.libs.utils.model_tools import queryset_iterator, set_uuid
from kpi.constants import DEFAULT_SURVEY_NAME
from kpi.utils.mongo_helper import MongoHelper


Expand Down Expand Up @@ -156,10 +157,11 @@ def add_instances(self):

def save(self, *args, **kwargs):
if self.xls:
survey = create_survey_from_xls(self.xls)
survey.update({
'name': survey.id_string,
})
survey = create_survey_from_xls(
self.xls, default_name=DEFAULT_SURVEY_NAME
)
if survey.name == DEFAULT_SURVEY_NAME:
survey.name = survey.id_string
self.json = survey.to_json()
self.xml = survey.to_xml()
self._mark_start_time_boolean()
Expand Down
2 changes: 2 additions & 0 deletions kpi/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@
ASSET_TYPE_TEMPLATE: [ASSET_TYPE_SURVEY, ASSET_TYPE_TEMPLATE]
}

DEFAULT_SURVEY_NAME = '__kobo_default_survey_name_value__'

ASSET_TYPE_ARG_NAME = 'asset_type'

# List of app labels that need to read/write data from KoBoCAT database
Expand Down
76 changes: 76 additions & 0 deletions kpi/tests/test_assets.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from rest_framework import serializers

from kobo.apps.kobo_auth.shortcuts import User
from kobo.apps.openrosa.apps.logger.models import XForm
from kobo.apps.openrosa.apps.logger.xform_instance_parser import XFormInstanceParser
from kpi.constants import (
ASSET_TYPE_SURVEY,
ASSET_TYPE_COLLECTION,
Expand Down Expand Up @@ -779,3 +781,77 @@ def test_anonymous_as_baseline_for_authenticated(self):
for user_obj in AnonymousUser(), self.anotheruser:
self.assertTrue(user_obj.has_perm(
PERM_VIEW_ASSET, self.asset))


class TestAssetNameSettingHandling(AssetsTestCase):
"""
Tests for the 'name' setting in the asset content
"""
def test_asset_name_matches_instance_root(self):
"""
Test if 'name' setting is provided, it should match with the root node.
"""
content = {
'survey': [
{
'type': 'text',
'name': 'some_text',
'label': 'Enter some text',
},
],
'settings': {'name': 'custom_root_node_name'}
}

# Create and deploy the asset
asset = Asset.objects.create(
owner=User.objects.get(username=self.user),
content=content,
asset_type=ASSET_TYPE_SURVEY
)
asset.deploy(backend='mock', active=True)

# Get the deployed XForm and parse it
xform = XForm.objects.get(id_string=asset.uid)
parser = XFormInstanceParser(xform.xml, xform.data_dictionary())

# Access the first child element of the <instance> node
instance_node = parser.get_root_node().getElementsByTagName('instance')[0]
root_element = instance_node.firstChild

# Assert that the name setting matches the root node name
assert root_element.nodeName == 'custom_root_node_name'

def test_asset_without_name_setting(self):
"""
Test if 'name' setting is not provided, the root node should fall back
to asset UID
"""
content = {
'survey': [
{
'type': 'text',
'name': 'some_text',
'label': 'Enter some text',
},
],
# No 'name' setting provided in this case
}

# Create and deploy the asset
asset = Asset.objects.create(
owner=User.objects.get(username=self.user),
content=content,
asset_type=ASSET_TYPE_SURVEY
)
asset.deploy(backend='mock', active=True)

# Get the deployed XForm and parse it
xform = XForm.objects.get(id_string=asset.uid)
parser = XFormInstanceParser(xform.xml, xform.data_dictionary())

# Access the first child element of the <instance> node
instance_node = parser.get_root_node().getElementsByTagName('instance')[0]
root_element = instance_node.firstChild

# Assert that the root node name is the asset.uid
assert root_element.nodeName == asset.uid
Loading