Skip to content
Closed
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
92 changes: 92 additions & 0 deletions corehq/apps/app_manager/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,21 @@ def _apply_updates_to_mappings(current_mappings, updates):
if all_missing_mappings:
raise MissingPropertyMapException(*all_missing_mappings)

def get_mappings(self):
mappings = {}
self.make_multi()

for (case_property, updates) in self.update_multi.items():
mappings[case_property] = [self.update_to_json(update) for update in updates]

return mappings

def update_to_json(self, update):
json = update.to_json()
if 'doc_type' in json:
del json['doc_type']
return json


class PreloadAction(FormAction):

Expand Down Expand Up @@ -655,6 +670,34 @@ def has_name_update(self):
def _update_has_name(self, update):
return bool(update.question_path)

def get_assigned_names(self):
questions = []
if self.name_update_multi:
questions.extend(self.name_update_multi)

if self.name_update:
questions.append(self.name_update)

return [question.question_path for question in questions if question.question_path]

def assign_name_update(self, question_path):
self.name_update = ConditionalCaseUpdate(question_path=question_path)
self.name_update_multi = []

def get_mappings(self):
mappings = {}
self.make_multi()

mappings['name'] = [self.update_to_json(update) for update in self.name_update_multi]

return mappings

def update_to_json(self, update):
json = update.to_json()
if 'doc_type' in json:
del json['doc_type']
return json


class OpenSubCaseAction(FormAction, IndexedSchema):

Expand Down Expand Up @@ -697,6 +740,33 @@ class FormActionsDiff(DocumentSchema):
open_case = SchemaProperty(OpenCaseDiff)
update_case = SchemaProperty(UpdateCaseDiff)

@classmethod
def parse_universal_diff(cls, universal_diff_json, is_registration=False):
open_diff = OpenCaseDiff()
update_diff = UpdateCaseDiff(universal_diff_json)

if is_registration:
if 'name' in update_diff.add:
name_additions = update_diff.add['name']
open_diff.add = name_additions
del update_diff.add['name']

if 'name' in update_diff.update:
name_updates = update_diff.update['name']
open_diff.update = name_updates
del update_diff.update['name']

if 'name' in update_diff.delete:
name_deletions = update_diff.delete['name']
open_diff.delete = name_deletions
del update_diff.delete['name']

diff = FormActionsDiff()
diff.open_case = open_diff
diff.update_case = update_diff

return diff


class FormActions(UpdateableDocument):
open_case = SchemaProperty(OpenCaseAction)
Expand Down Expand Up @@ -767,6 +837,17 @@ def make_single(self, allow_conflicts=True):
else:
self.update_case.make_single()

def get_mappings(self):
mappings = {}

if self.open_case:
mappings.update(self.open_case.get_mappings())

if self.update_case:
mappings.update(self.update_case.get_mappings())

return mappings


class CaseIndex(DocumentSchema):
tag = StringProperty()
Expand Down Expand Up @@ -1726,6 +1807,9 @@ def get_case_updates_for_case_type(self, case_type):
"""
return self.get_case_updates().get(case_type, [])

def get_source_with_mappings(self):
return self.source


class JRResourceProperty(StringProperty):

Expand Down Expand Up @@ -2113,6 +2197,14 @@ def get_contributed_case_relationships(self):
(parent_case_type, subcase.reference_id or 'parent'))
return case_relationships_by_child_type

def get_source_with_mappings(self):
if not self._parent.case_type:
return self.source

xform = XForm(self.source)
xform.add_case_mappings(self)
return xform.render_pretty().decode('utf-8')


class GraphAnnotations(IndexedSchema):
display_text = DictProperty()
Expand Down
121 changes: 121 additions & 0 deletions corehq/apps/app_manager/tests/test_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,48 @@ def test_has_name_update_requires_name_update_multi_to_have_a_path(self):

self.assertFalse(action.has_name_update())

def test_get_assigned_names_spans_update_and_update_multi(self):
action = OpenCaseAction({
'name_update': {'question_path': 'one'},
'name_update_multi': [{'question_path': 'two'}]
})

self.assertEqual(set(action.get_assigned_names()), {'one', 'two'})

def test_get_assigned_names_ignores_empty_values(self):
action = OpenCaseAction({
'name_update': {'question_path': None}
})

self.assertEqual(set(action.get_assigned_names()), set())

def test_assign_name_update_sets_name_update(self):
action = OpenCaseAction()
action.assign_name_update('name_question')

self.assertEqual(action.name_update.question_path, 'name_question')

def test_assign_name_update_removes_update_multi(self):
action = OpenCaseAction({
'name_update_multi': [{'question_path': 'one'}, {'question_path': 'two'}]
})
action.assign_name_update('three')

self.assertEqual(action.name_update_multi, [])

def test_get_mappings_serializes_name_updates(self):
action = OpenCaseAction({
'name_update_multi': [{'question_path': 'one'}, {'question_path': 'two'}]
})

json = action.get_mappings()
self.assertEqual(json, {
'name': [
{'question_path': 'one', 'update_mode': 'always'},
{'question_path': 'two', 'update_mode': 'always'}
]
})


class OpenCaseAction_ApplyUpdates_Tests(SimpleTestCase):
def test_no_changes(self):
Expand Down Expand Up @@ -391,6 +433,37 @@ def test_get_property_names_returns_keys_from_update_multi(self):

self.assertEqual(action.get_property_names(), {'one'})

def test_get_mappings_serializes_updates(self):
action = UpdateCaseAction({
'update_multi': {
'one': [{'question_path': '/A/'}, {'question_path': '/B/'}],
'two': [{'question_path': '/C/'}],
}
})

json = action.get_mappings()

self.assertEqual(json, {
'one': [
{'question_path': '/A/', 'update_mode': 'always'},
{'question_path': '/B/', 'update_mode': 'always'}
],
'two': [{'question_path': '/C/', 'update_mode': 'always'}]
})

def test_get_mappings_removes_doc_type(self):
action = UpdateCaseAction({
'update': {
'one': {'question_path': '/A/', 'update_mode': 'edit', 'doc_type': 'TestDoc'},
}
})

json = action.get_mappings()

self.assertEqual(json, {
'one': [{'question_path': '/A/', 'update_mode': 'edit'}]
})


class UpdateCaseAction_ApplyUpdates_Tests(SimpleTestCase):
def test_no_changes(self):
Expand Down Expand Up @@ -759,6 +832,54 @@ def test_json_construction(self):
assert diff.open_case.add[0].question_path == 'one'
assert diff.update_case.delete['case_two'][0].question_path == 'two'

def test_parse_universal_diff_creates_diff_object(self):
universal_json = {
'add': {
'prop1': [{'question_path': 'one'}]
},
'update': {
'prop2': [{'question_path': 'two'}]
},
'delete': {
'prop3': [{'question_path': 'three'}]
}
}

diff = FormActionsDiff.parse_universal_diff(universal_json)

assert len(diff.update_case.add['prop1']) == 1
assert diff.update_case.add['prop1'][0].question_path == 'one'

assert len(diff.update_case.update['prop2']) == 1
assert diff.update_case.update['prop2'][0].question_path == 'two'

assert len(diff.update_case.delete['prop3']) == 1
assert diff.update_case.delete['prop3'][0].question_path == 'three'

def test_parse_universal_diff_non_registration_name_stays_in_update(self):
universal_json = {
'add': {
'name': [{'question_path': 'one'}]
}
}

diff = FormActionsDiff.parse_universal_diff(universal_json)

assert diff.update_case.add['name'][0].question_path == 'one'
assert 'name' not in diff.open_case.add

def test_parse_universal_diff_registration_name_is_in_open_case(self):
universal_json = {
'add': {
'name': [{'question_path': 'one'}]
}
}

diff = FormActionsDiff.parse_universal_diff(universal_json, is_registration=True)

assert diff.open_case.add[0].question_path == 'one'
assert 'name' not in diff.update_case.add


class FormActionTests(SimpleTestCase):
def test_get_action_properties_for_name_update(self):
Expand Down
Loading
Loading