Skip to content

Commit

Permalink
update export registe after for replacement
Browse files Browse the repository at this point in the history
  • Loading branch information
kelvin-muchiri committed Jan 21, 2025
1 parent 5c0278b commit 46894da
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 24 deletions.
21 changes: 11 additions & 10 deletions onadata/apps/logger/models/xform.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@
from pyxform import SurveyElementBuilder, constants, create_survey_element_from_dict
from pyxform.question import Question
from pyxform.section import RepeatingSection
from pyxform.xform2json import create_survey_element_from_xml
from six import iteritems
from taggit.managers import TaggableManager

Expand Down Expand Up @@ -374,18 +373,20 @@ def get_unique_id_string(self, id_string, count=0):

return id_string

def _get_survey(self):
try:
builder = SurveyElementBuilder()
if isinstance(self.json, str):
return builder.create_survey_element_from_json(self.json)
if isinstance(self.json, dict):
return builder.create_survey_element_from_dict(self.json)
except ValueError:
return bytes(bytearray(self.xml, encoding="utf-8"))

def get_survey(self):
"""Returns an XML XForm survey object."""
if not hasattr(self, "_survey"):
try:
builder = SurveyElementBuilder()
if isinstance(self.json, str):
self._survey = builder.create_survey_element_from_json(self.json)
if isinstance(self.json, dict):
self._survey = builder.create_survey_element_from_dict(self.json)
except ValueError:
xml = bytes(bytearray(self.xml, encoding="utf-8"))
self._survey = create_survey_element_from_xml(xml)
self._survey = self._get_survey()
return self._survey

survey = property(get_survey)
Expand Down
30 changes: 17 additions & 13 deletions onadata/apps/viewer/models/data_dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -446,20 +446,24 @@ def create_export_columns_register(sender, instance=None, created=False, **kwarg
"""Create export repeat register for the form"""
# Avoid cyclic import by using importlib
csv_builder = importlib.import_module("onadata.libs.utils.csv_builder")
logger_tasks = importlib.import_module("onadata.apps.logger.tasks")
ordered_columns = OrderedDict()
# pylint: disable=protected-access
csv_builder.CSVDataFrameBuilder._build_ordered_columns(
instance._get_survey(), ordered_columns
)
MetaData.objects.update_or_create(
content_type=ContentType.objects.get_for_model(instance),
object_id=instance.pk,
data_type=EXPORT_COLUMNS_REGISTER,
defaults={
"data_value": "",
"extra_data": json.dumps(ordered_columns),
},
)

if created:
ordered_columns = OrderedDict()
# pylint: disable=protected-access
csv_builder.CSVDataFrameBuilder._build_ordered_columns(
instance.survey, ordered_columns
)
MetaData.objects.create(
content_type=ContentType.objects.get_for_model(instance),
object_id=instance.pk,
data_type=EXPORT_COLUMNS_REGISTER,
data_value="",
extra_data=json.dumps(ordered_columns),
)
if not created:
logger_tasks.register_xform_export_columns_async.delay(instance.pk)


post_save.connect(
Expand Down
54 changes: 53 additions & 1 deletion onadata/apps/viewer/models/tests/test_data_dictionary.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
"""Tests for onadata.apps.viewer.models.data_dictionary"""

import json
from collections import OrderedDict
from unittest.mock import patch

from django.contrib.contenttypes.models import ContentType
from django.core.cache import cache
Expand Down Expand Up @@ -310,7 +312,7 @@ def test_cache_invalidated(self):
self.assertIsNone(cache.get(key))

def test_export_columns_register_created(self):
"""Export export columns register is created when form is published"""
"""Export columns register is created when form is published"""
xform = self._publish_markdown(self.registration_form, self.user)
content_type = ContentType.objects.get_for_model(xform)
exists = MetaData.objects.filter(
Expand All @@ -320,3 +322,53 @@ def test_export_columns_register_created(self):
).exists()

self.assertTrue(exists)

@patch("onadata.apps.logger.tasks.register_xform_export_columns_async.delay")
def test_export_columns_register_updated(self, mock_register_xform_columns):
"""Export columns register is updated when form is replaced"""
md = """
| survey |
| | type | name | label |
| | text | name | First Name |
| settings| | | |
| | form_title | form_id | |
| | Students | students | |
"""
xform = self._publish_markdown(md, self.user)
content_type = ContentType.objects.get_for_model(xform)
register = MetaData.objects.get(
data_type="export_columns_register",
object_id=xform.pk,
content_type=content_type,
)
ordered_columns = json.loads(register.extra_data, object_pairs_hook=OrderedDict)
expected_columns = OrderedDict(
[
("name", None),
("meta/instanceID", None),
]
)
self.assertEqual(ordered_columns, expected_columns)
# Replace form
md = """
| survey |
| | type | name | label |
| | text | name | First Name |
| | text | age | Age |
| settings| | | |
| | form_title | form_id | |
| | Students | students | |
"""
self._replace_form(md, xform)
register.refresh_from_db()
ordered_columns = json.loads(register.extra_data, object_pairs_hook=OrderedDict)
expected_columns = OrderedDict(
[
("name", None),
("age", None),
("meta/instanceID", None),
]
)
self.assertEqual(ordered_columns, expected_columns)
# Task is called to add columns for repeat data
mock_register_xform_columns.assert_called_once_with(xform.pk)

0 comments on commit 46894da

Please sign in to comment.