Esempio n. 1
0
    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']
Esempio n. 3
0
    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
Esempio n. 5
0
    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'])
Esempio n. 6
0
    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
Esempio n. 10
0
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']
Esempio n. 11
0
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
Esempio n. 14
0
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)
    ]