diff --git a/pyxform/tests/example_xls/choice_filter_test.xlsx b/pyxform/tests/example_xls/choice_filter_test.xlsx new file mode 100644 index 000000000..74088b8e4 Binary files /dev/null and b/pyxform/tests/example_xls/choice_filter_test.xlsx differ diff --git a/pyxform/tests/test_output/yes_or_no_question.json b/pyxform/tests/test_output/yes_or_no_question.json index 3b8ee3e13..2fdedd886 100644 --- a/pyxform/tests/test_output/yes_or_no_question.json +++ b/pyxform/tests/test_output/yes_or_no_question.json @@ -22,7 +22,7 @@ } ], "type": "select one", - "name": "good_day", + "name": "good_day", "label": { "english": "have you had a good day today?" } diff --git a/pyxform/tests/xls2json_tests.py b/pyxform/tests/xls2json_tests.py index 2ec6a32a7..983cd0362 100644 --- a/pyxform/tests/xls2json_tests.py +++ b/pyxform/tests/xls2json_tests.py @@ -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): diff --git a/pyxform/xls2json.py b/pyxform/xls2json.py index 2411d05e5..51475c507 100644 --- a/pyxform/xls2json.py +++ b/pyxform/xls2json.py @@ -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'} @@ -803,12 +804,16 @@ 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: @@ -816,8 +821,9 @@ def replace_prefix(d, prefix): 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 @@ -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']: @@ -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 @@ -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 @@ -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: @@ -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