def test_list_fields_from_many_versions_on_packs(self): title, schemas, submissions = build_fixture('site_inspection') fp = FormPack(schemas, title) self.assertEqual(len(fp.versions), 5) fields = { field.name: field for field in fp.get_fields_for_versions( fp.versions.keys()) } field_names = sorted(fields.keys()) self.assertListEqual(field_names, [ 'did_you_find_the_site', 'inspector', 'is_plant_life_encroaching', 'is_the_gate_secure', 'ping', 'please_rate_the_impact_of_any_defects_observed', 'rssi', 'was_there_damage_to_the_site', 'was_there_damage_to_the_site_dupe', ]) field_types = [fields[name].__class__.__name__ for name in field_names] self.assertListEqual(field_types, [ 'FormChoiceField', 'TextField', 'FormChoiceField', 'FormChoiceField', 'NumField', 'FormChoiceField', 'NumField', 'FormChoiceField', 'FormChoiceField', ])
def test_get_fields_for_versions_returns_unique_fields(): """ As described in #127, `get_field_for_versions()` would return identical fields multiple times. This is was a failing test to reproduce that issue """ fp = FormPack([ { 'content': { 'survey': [ { 'name': 'hey', 'type': 'image' }, { 'name': 'two', 'type': 'image' }, ] }, 'version': 'vRR7hH6SxTupvtvCqu7n5d', }, { 'content': { 'survey': [ { 'name': 'one', 'type': 'image' }, { 'name': 'two', 'type': 'image' }, ] }, 'version': 'vA8xs9JVi8aiSfypLgyYW2', }, { 'content': { 'survey': [ { 'name': 'one', 'type': 'image' }, { 'name': 'two', 'type': 'image' }, ] }, 'version': 'vNqgh8fJqyjFk6jgiCk4rn', }, ]) fields = fp.get_fields_for_versions(fp.versions) field_names = [field.name for field in fields] assert sorted(field_names) == ['hey', 'one', 'two']
def test_list_fields_on_packs(self): title, schemas, _ = build_fixture('restaurant_profile') fp = FormPack(schemas, title) fields = fp.get_fields_for_versions() field_names = [field.name for field in fields] assert field_names == ['restaurant_name', 'location', 'eatery_type'] field_types = [field.__class__.__name__ for field in fields] assert ' '.join(field_types) == ' '.join(['TextField', 'FormGPSField', 'FormChoiceFieldWithMultipleSelect'])
def test_fields_for_versions_list_index_out_of_range(): title, schemas, submissions = build_fixture( 'fields_for_versions_list_index_out_of_range') fp = FormPack(schemas, title) all_fields = fp.get_fields_for_versions(fp.versions.keys()) expected = [ 'one', 'third', 'first_but_not_one', ] field_names = [field.name for field in all_fields] assert len(all_fields) == 3 assert field_names == expected
def test_temporary_test_of_formpack_issue_163_patch(self): # FIXME: Flesh this out and move it into formpack from formpack import FormPack schemas = [ {'content': {u'schema': u'1', u'survey': [{u'label': [u'first but not one'], 'name': u'first_but_not_one', u'type': u'text'}, {u'label': [u'one'], 'name': u'one', u'type': u'text'}, {u'label': [u'third'], 'name': u'third', u'type': u'text'}]}, 'version': u'v8wZaeXndV3KpfYkaHLjxC'}, {'content': {u'schema': u'1', u'survey': [{u'label': [u'one'], 'name': u'one', u'type': u'text'}]}, 'version': u'vwjRCb6B7Mje2iRbeW2iyQ'} ] fp = FormPack(schemas) # Will raise IndexError if patch is not applied fp.get_fields_for_versions(fp.versions.keys())
def test_get_fields_for_versions_returns_newest_of_fields_with_same_name(): schemas = [ { 'version': 'v1', 'content': { 'survey': [ { 'name': 'constant_question_name', 'type': 'select_one choice', 'label': 'first version question label', 'hxl': '#first_version_hxl', }, ], 'choices': [ { 'list_name': 'choice', 'name': 'constant_choice_name', 'label': 'first version choice label', }, ], }, }, { 'version': 'v2', 'content': { 'survey': [ { 'name': 'constant_question_name', 'type': 'select_one choice', 'label': 'second version question label', 'hxl': '#second_version_hxl', }, ], 'choices': [{ 'list_name': 'choice', 'name': 'constant_choice_name', 'label': 'second version choice label', }], }, }, ] fp = FormPack(schemas) fields = fp.get_fields_for_versions(fp.versions) # The first and only field returned should be the first field of the first # section of the last version section_value = get_first_occurrence(fp[-1].sections.values()) assert fields[0] == get_first_occurrence(section_value.fields.values())
def test_field_position_with_multiple_versions(): title, schemas, submissions = build_fixture( 'field_position_with_multiple_versions') fp = FormPack(schemas, title) all_fields = fp.get_fields_for_versions(fp.versions.keys()) expected = [ 'City', 'Firstname', 'Lastname', 'Gender', 'Age', 'Fullname', ] field_names = [field.name for field in all_fields] assert len(all_fields) == 6 assert field_names == expected
def test_get_fields_for_versions_returns_all_choices(): schemas = [ { 'version': 'v1', 'content': { 'survey': [ { 'name': 'constant_question_name', 'type': 'select_one choice', 'label': 'first version question label', }, ], 'choices': [ { 'list_name': 'choice', 'name': 'first_version_choice_name', 'label': 'first version choice label', }, ], }, }, { 'version': 'v2', 'content': { 'survey': [ { 'name': 'constant_question_name', 'type': 'select_one choice', 'label': 'second version question label', }, ], 'choices': [{ 'list_name': 'choice', 'name': 'second_version_choice_name', 'label': 'second version choice label', }], }, }, ] fp = FormPack(schemas) fields = fp.get_fields_for_versions(fp.versions) choice_names = fields[0].choice.options.keys() assert 'first_version_choice_name' in choice_names assert 'second_version_choice_name' in choice_names
def test_get_fields_for_versions_returns_unique_fields(): ''' As described in #127, `get_field_for_versions()` would return identical fields multiple times. This is a (soon-to-be-fixed) failing test to reproduce that issue ''' fp = FormPack([{ 'content': { u'survey': [{ u'name': u'hey', u'type': u'image' }, { u'name': u'two', u'type': u'image' }] }, 'version': u'vRR7hH6SxTupvtvCqu7n5d' }, { 'content': { u'survey': [{ u'name': u'one', u'type': u'image' }, { u'name': u'two', u'type': u'image' }] }, 'version': u'vA8xs9JVi8aiSfypLgyYW2' }, { 'content': { u'survey': [{ u'name': u'one', u'type': u'image' }, { u'name': u'two', u'type': u'image' }] }, 'version': u'vNqgh8fJqyjFk6jgiCk4rn' }]) fields = fp.get_fields_for_versions(fp.versions) field_names = [field.name for field in fields] assert sorted(field_names) == [u'hey', u'one', u'two']
def data_by_identifiers(asset, field_names=None, submission_stream=None, report_styles=None, lang=None, fields=None, split_by=None): if submission_stream is None: _userform_id = asset.deployment.mongo_userform_id submission_stream = get_instances_for_userform_id(_userform_id) _versions = asset.deployed_versions # need ability to look up deprecated IDs _reversion_ids = dict([(str(v._reversion_version_id), v.uid) for v in _versions if v._reversion_version_id]) schemas = [v.to_formpack_schema() for v in _versions] _version_id = schemas[0]['version'] _version_id_key = schemas[0].get('version_id_key', '__version__') def _inject_version_id(result): if _version_id_key not in result: result[_version_id_key] = _version_id elif result[_version_id_key] in _reversion_ids: result[_version_id_key] = _reversion_ids[result[_version_id_key]] return result submission_stream = (_inject_version_id(result) for result in submission_stream) pack = FormPack(versions=schemas, id_string=asset.uid) _all_versions = pack.versions.keys() report = pack.autoreport(versions=_all_versions) fields_by_name = OrderedDict([ (field.name, field) for field in pack.get_fields_for_versions(versions=_all_versions) ]) if field_names is None: field_names = fields_by_name.keys() if split_by and (split_by not in fields_by_name): raise serializers.ValidationError( _("`split_by` field '{}' not found.").format(split_by)) if split_by and (fields_by_name[split_by].data_type != 'select_one'): raise serializers.ValidationError( _("`split_by` field '{}' is not a select one question.").format( split_by)) if report_styles is None: report_styles = asset.report_styles specified_styles = report_styles.get('specified', {}) kuids = report_styles.get('kuid_names', {}) def _stat_dict_to_array(stat, field_name): freq = stat.pop('frequency', []) if len(freq) > 0: prcntg = stat.pop('percentage') responses, frequencies = zip(*freq) responses_percentage, percentages = zip(*prcntg) if responses != responses_percentage: raise ValueError( "Frequency and percentage response lists for field '{}' mismatch." .format(field_name)) stat.update({ 'responses': responses, 'frequencies': frequencies, 'percentages': percentages }) def _package_stat(field, _, stat, split_by): identifier = kuids.get(field.name) if not split_by: _stat_dict_to_array(stat, field.name) elif 'values' in stat: for _, sub_stat in stat['values']: _stat_dict_to_array(sub_stat, field.name) return { 'name': field.name, 'row': { 'type': fields_by_name.get(field.name).data_type }, 'data': stat, 'kuid': identifier, 'style': specified_styles.get(identifier, {}), } return [ _package_stat(*stat_tup, split_by=split_by) for stat_tup in report.get_stats(submission_stream, fields=field_names, lang=lang, split_by=split_by) ]
def test_get_fields_for_versions_returns_all_fields_with_repeat_groups(): """ Test for #275 to ensure that all repeat groups across versions are included especially if the question names remain the same and only the group name changes """ fp = FormPack([ { 'content': { 'survey': [ { 'name': 'old_name', 'type': 'begin_repeat' }, { 'name': 'one', 'type': 'image' }, { 'name': 'two', 'type': 'image' }, { 'type': 'end_repeat' }, ] }, 'version': 'vRR7hH6SxTupvtvCqu7n5d', }, { 'content': { 'survey': [ { 'name': 'new_name', 'type': 'begin_repeat' }, { 'name': 'one', 'type': 'image' }, { 'name': 'two', 'type': 'image' }, { 'type': 'end_repeat' }, ] }, 'version': 'vA8xs9JVi8aiSfypLgyYW2', }, ]) fields = fp.get_fields_for_versions(fp.versions) field_and_section_names = [(field.name, field.section.name) for field in fields] assert field_and_section_names == [ ('one', 'new_name'), ('two', 'new_name'), ('one', 'old_name'), ('two', 'old_name'), ]
def test_null_untranslated_labels(): content = json.loads(''' { "translations": [ "arabic", null ], "choices": [ { "list_name": "aid_types", "name": "1", "label": [ "سلل غذائية", null ] }, { "list_name": "aid_types", "name": "2", "label": [ "سلل شتوية", null ] }, { "list_name": "aid_types", "name": "3", "label": [ "سلل زراعية", null ] }, { "list_name": "aid_types", "name": "4", "label": [ "قسائم", null ] }, { "list_name": "aid_types", "name": "5", "label": [ "أخرى", null ] } ], "survey": [ { "select_from_list_name": "aid_types", "name": "what_aid_do_you_receive", "required": true, "label": [ "إذا كان نعم ماهي المساعدات التي تتلقاها؟", null ], "type": "select_multiple" } ], "translated": [ "hint", "label" ] } ''') fp = FormPack({'content': content}, id_string='arabic_and_null') fields = fp.get_fields_for_versions() field = fields[0] assert len(fields) == 1 expected_arabic_labels = [ 'إذا كان نعم ماهي المساعدات التي تتلقاها؟', 'إذا كان نعم ماهي المساعدات التي تتلقاها؟/سلل غذائية', 'إذا كان نعم ماهي المساعدات التي تتلقاها؟/سلل شتوية', 'إذا كان نعم ماهي المساعدات التي تتلقاها؟/سلل زراعية', 'إذا كان نعم ماهي المساعدات التي تتلقاها؟/قسائم', 'إذا كان نعم ماهي المساعدات التي تتلقاها؟/أخرى', ] arabic_labels = field.get_labels('arabic') assert arabic_labels == expected_arabic_labels untranslated_labels = field.get_labels(constants.UNTRANSLATED) question_names = field.get_labels(constants.UNSPECIFIED_TRANSLATION) assert untranslated_labels == question_names
def data_by_identifiers(asset, field_names=None, submission_stream=None, report_styles=None, lang=None, fields=None, split_by=None): if submission_stream is None: _userform_id = asset.deployment.mongo_userform_id submission_stream = get_instances_for_userform_id(_userform_id) _versions = asset.deployed_versions # need ability to look up deprecated IDs _reversion_ids = dict([ (str(v._reversion_version_id), v.uid) for v in _versions if v._reversion_version_id ]) schemas = [v.to_formpack_schema() for v in _versions] _version_id = schemas[0]['version'] _version_id_key = schemas[0].get('version_id_key', '__version__') def _inject_version_id(result): if _version_id_key not in result: result[_version_id_key] = _version_id elif result[_version_id_key] in _reversion_ids: result[_version_id_key] = _reversion_ids[result[_version_id_key]] return result submission_stream = (_inject_version_id(result) for result in submission_stream) pack = FormPack(versions=schemas, id_string=asset.uid) _all_versions = pack.versions.keys() report = pack.autoreport(versions=_all_versions) fields_by_name = OrderedDict([ (field.name, field) for field in pack.get_fields_for_versions(versions=_all_versions) ]) if field_names is None: field_names = fields_by_name.keys() if split_by and (split_by not in fields_by_name): raise serializers.ValidationError(_("`split_by` field '{}' not found.").format(split_by)) if split_by and (fields_by_name[split_by].data_type != 'select_one'): raise serializers.ValidationError(_("`split_by` field '{}' is not a select one question."). format(split_by)) if report_styles is None: report_styles = asset.report_styles specified_styles = report_styles.get('specified', {}) kuids = report_styles.get('kuid_names', {}) def _stat_dict_to_array(stat, field_name): freq = stat.pop('frequency', []) if len(freq) > 0: prcntg = stat.pop('percentage') responses, frequencies = zip(*freq) responses_percentage, percentages = zip(*prcntg) if responses != responses_percentage: raise ValueError("Frequency and percentage response lists for field '{}' mismatch." .format(field_name)) stat.update({'responses': responses, 'frequencies': frequencies, 'percentages': percentages}) def _package_stat(field, _, stat, split_by): identifier = kuids.get(field.name) if not split_by: _stat_dict_to_array(stat, field.name) elif 'values' in stat: for _, sub_stat in stat['values']: _stat_dict_to_array(sub_stat, field.name) return { 'name': field.name, 'row': {'type': fields_by_name.get(field.name).data_type}, 'data': stat, 'kuid': identifier, 'style': specified_styles.get(identifier, {}), } return [_package_stat(*stat_tup, split_by=split_by) for stat_tup in report.get_stats(submission_stream, fields=field_names, lang=lang, split_by=split_by) ]