Skip to content

Commit

Permalink
Merge pull request #235 from lincmba/234_fix_choice_filter_in_json
Browse files Browse the repository at this point in the history
Include choice filter choices in json['children'] field
  • Loading branch information
ukanga committed Nov 13, 2018
2 parents e4b3824 + 75aea0c commit 8e85ca7
Show file tree
Hide file tree
Showing 4 changed files with 155 additions and 15 deletions.
Binary file added pyxform/tests/example_xls/choice_filter_test.xlsx
Binary file not shown.
2 changes: 1 addition & 1 deletion pyxform/tests/test_output/yes_or_no_question.json
Expand Up @@ -22,7 +22,7 @@
}
],
"type": "select one",
"name": "good_day",
"name": "good_day",
"label": {
"english": "have you had a good day today?"
}
Expand Down
125 changes: 125 additions & 0 deletions pyxform/tests/xls2json_tests.py
Expand Up @@ -158,6 +158,131 @@ def test_table(self):
actual_json = json.load(actual_file)
self.assertEqual(expected_json, actual_json)

def test_choice_filter_choice_fields(self):
"""
Test that the choice filter fields appear on children field of json
"""
choice_filter_survey = SurveyReader(
utils.path_to_text_fixture("choice_filter_test.xlsx"))

expected_dict = [
{
u'choices': [
{
u'name': u'texas',
u'label': u'Texas'
},
{
u'name': u'washington',
u'label': u'Washington'
}
],
u'type': u'select one',
u'name': u'state',
u'parameters': {},
u'label': u'state'
},
{
u'name': u'county',
u'parameters': {},
u'choice_filter': u'${state}=cf',
u'label': u'county',
u'itemset': u'counties',
u'choices': [
{
u'label': u'King',
u'cf': u'washington',
u'name': u'king'
},
{
u'label': u'Pierce',
u'cf': u'washington',
u'name': u'pierce'
},
{
u'label': u'King',
u'cf': u'texas',
u'name': u'king'
},
{
u'label': u'Cameron',
u'cf': u'texas',
u'name': u'cameron'
}
],
u'type': u'select one'
},
{
u'name': u'city',
u'parameters': {},
u'choice_filter': u'${county}=cf',
u'label': u'city',
u'itemset': u'cities',
u'choices': [
{
u'label': u'Dumont',
u'cf': u'king',
u'name': u'dumont'
},
{
u'label': u'Finney',
u'cf': u'king',
u'name': u'finney'
},
{
u'label': u'brownsville',
u'cf': u'cameron',
u'name': u'brownsville'
},
{
u'label': u'harlingen',
u'cf': u'cameron',
u'name': u'harlingen'
},
{
u'label': u'Seattle',
u'cf': u'king',
u'name': u'seattle'
},
{
u'label': u'Redmond',
u'cf': u'king',
u'name': u'redmond'
},
{
u'label': u'Tacoma',
u'cf': u'pierce',
u'name': u'tacoma'
},
{
u'label': u'Puyallup',
u'cf': u'pierce',
u'name': u'puyallup'
}
],
u'type': u'select one'
},
{
u'control': {
u'bodyless': True
},
u'type': u'group',
u'name': u'meta',
u'children': [
{
u'bind': {
u'readonly': u'true()',
u'calculate': u"concat('uuid:', uuid())"
},
u'type': u'calculate',
u'name': u'instanceID'
}
]
}
]
self.assertEqual(
choice_filter_survey.to_json_dict()[u"children"], expected_dict)


class CsvReaderEquivalencyTest(TestCase):
def test_equivalency(self):
Expand Down
43 changes: 29 additions & 14 deletions pyxform/xls2json.py
Expand Up @@ -265,7 +265,8 @@ def process_range_question_type(row):
Raises PyXFormError when invalid range parameters are used.
"""
new_dict = row.copy()
parameters = get_parameters(new_dict.get('parameters', ''), ['start', 'end', 'step'])
parameters = get_parameters(
new_dict.get('parameters', ''), ['start', 'end', 'step'])
parameters_map = {'start': 'start', 'end': 'end', 'step': 'step'}
defaults = {'start': '1', 'end': '10', 'step': '1'}

Expand Down Expand Up @@ -803,21 +804,26 @@ def replace_prefix(d, prefix):
new_json_dict[constants.TYPE] = select_type

# Look at parameters column for randomization parameters
parameters = get_parameters(row.get('parameters', ''), ['randomize', 'seed'])
parameters = get_parameters(
row.get('parameters', ''), ['randomize', 'seed'])

if "randomize" in parameters.keys():
if parameters["randomize"] != "true" and parameters["randomize"] != "false":
raise PyXFormError("randomize must be set to true or false: "
"'%s' is an invalid value" % parameters["randomize"])
if parameters["randomize"] != "true" and \
parameters["randomize"] != "false":
raise PyXFormError(
"randomize must be set to true or false: "
"'%s' is an invalid value" %
parameters["randomize"])

if "seed" in parameters.keys():
try:
float(parameters["seed"])
except ValueError:
raise PyXFormError("seed value must be a number.")
elif "seed" in parameters.keys():
raise PyXFormError("Parameters must include randomize=true to use a seed.")

raise PyXFormError(
"Parameters must include randomize=true to use a seed."
)

new_json_dict['parameters'] = parameters

Expand All @@ -827,7 +833,11 @@ def replace_prefix(d, prefix):
else:
new_json_dict['itemset'] = list_name
json_dict['choices'] = choices
elif "randomize" in parameters.keys() and parameters["randomize"] == "true":
if choices.get(list_name):
new_json_dict[constants.CHOICES] = \
choices[list_name]
elif "randomize" in parameters.keys() and \
parameters["randomize"] == "true":
new_json_dict['itemset'] = list_name
json_dict['choices'] = choices
elif file_extension in ['.csv', '.xml']:
Expand Down Expand Up @@ -895,16 +905,19 @@ def replace_prefix(d, prefix):

if question_type == 'photo':
new_dict = row.copy()
parameters = get_parameters(row.get('parameters', ''), ['max-pixels'])
parameters = get_parameters(
row.get('parameters', ''), ['max-pixels'])

if 'max-pixels' in parameters.keys():
try:
int(parameters['max-pixels'])
except:
raise PyXFormError("Parameter max-pixels must have an integer value.")
raise PyXFormError(
"Parameter max-pixels must have an integer value.")

new_dict['bind'] = new_dict.get('bind', {})
new_dict['bind'].update({'orx:max-pixels': parameters['max-pixels']})
new_dict['bind'].update(
{'orx:max-pixels': parameters['max-pixels']})
parent_children_array.append(new_dict)
continue

Expand Down Expand Up @@ -961,7 +974,7 @@ def replace_prefix(d, prefix):
noop, survey_children_array = stack[0]
survey_children_array.append(meta_element)

#print_pyobj_to_json(json_dict)
# print_pyobj_to_json(json_dict)
return json_dict


Expand Down Expand Up @@ -1027,6 +1040,7 @@ def organize_by_values(dict_list, key):
result[val] = dicty_copy
return result


def get_parameters(raw_parameters, allowed_parameters):
parts = raw_parameters.split(';')
if len(parts) == 1:
Expand All @@ -1038,14 +1052,15 @@ def get_parameters(raw_parameters, allowed_parameters):
for param in parts:
if '=' not in param:
raise PyXFormError("Expecting parameters to be in the form of "
"'parameter1=value parameter2=value'.")
"'parameter1=value parameter2=value'.")
k, v = param.split('=')[:2]
key = k.lower().strip()
if key in allowed_parameters:
params[key] = v.lower().strip()
else:
raise PyXFormError("Accepted parameters are "
"'%s': '%s' is an invalid parameter." % (", ".join(allowed_parameters), key))
"'%s': '%s' is an invalid parameter."
% (", ".join(allowed_parameters), key))

return params

Expand Down

0 comments on commit 8e85ca7

Please sign in to comment.