Projet

Général

Profil

0001-misc-accept-duplicate-fields-with-the-same-type-4242.patch

Benjamin Dauvergne, 25 septembre 2020 10:41

Télécharger (8,28 ko)

Voir les différences:

Subject: [PATCH] misc: accept duplicate fields with the same type (#42429)

 tests/conftest.py  | 10 +++++++++-
 tests/olap.model   | 10 ++++++++--
 tests/test_wcs.py  | 20 ++++++++++++++++++++
 wcs_olap/feeder.py | 31 ++++++++++++++++++++-----------
 4 files changed, 57 insertions(+), 14 deletions(-)
tests/conftest.py
102 102
    fields.ItemField(id='4', label='4rth field', type='item', varname='itemOpen'),
103 103
    fields.StringField(id='5', label='5th field', type='string', anonymise=False, varname='stringCaseSensitive-é'),
104 104
    fields.BoolField(id='6', label='6th field duplicate', type='bool', varname='duplicate'),
105
    fields.StringField(id='7', label='7th field duplicate', type='string', anonymise=False, varname='duplicate'),
105
    fields.StringField(id='7', label='7th field bad duplicate', type='string', anonymise=False, varname='duplicate'),
106 106
    fields.StringField(id='8', label='8th field integer', type='string', anonymise=False, varname='integer',
107 107
        validation={'type': 'digits'}),
108
    fields.StringField(id='9', label='8th field duplicate', type='string', anonymise=False,
109
                       required=False, varname='good_duplicate'),
110
    fields.StringField(id='10', label='9th field good duplicate', type='string', anonymise=False,
111
                       required=False, varname='good_duplicate'),
108 112
]
109 113
formdef.store()
110 114

  
......
124 128
        formdata.data['2_display'] = 'foo'
125 129
        formdata.data['4'] = 'open_one'
126 130
        formdata.data['4_display'] = 'open_one'
131
        formdata.data['9'] = 'a'
127 132
    elif i%4 == 1:
128 133
        formdata.data['2'] = 'bar'
129 134
        formdata.data['2_display'] = 'bar'
130 135
        formdata.data['4'] = 'open_two'
131 136
        formdata.data['4_display'] = 'open_two'
137
        formdata.data['10'] = 'b'
132 138
    else:
133 139
        formdata.data['2'] = 'baz'
134 140
        formdata.data['2_display'] = 'baz'
135 141
        formdata.data['4'] = "open'three"
136 142
        formdata.data['4_display'] = "open'three"
143
        formdata.data['9'] = 'a'
144
        formdata.data['10'] = 'b'
137 145

  
138 146
    formdata.data['3'] = bool(i % 2)
139 147
    formdata.data['8'] = str(i % 10)
tests/olap.model
287 287
               "name": "stringCaseSensitive-é",
288 288
               "type": "string",
289 289
               "value": "\"field_stringCaseSensitive-é\""
290
            },
291
            {
292
               "filter": true,
293
               "label": "9th field good duplicate",
294
               "name": "good_duplicate",
295
               "type": "string",
296
               "value": "\"field_good_duplicate\""
290 297
            }
291 298
         ],
292 299
         "fact_table" : "\"formdata_demande\"",
......
419 426
         ],
420 427
         "name" : "formdata_demande",
421 428
         "warnings": [
422
            "le champ « 6th field duplicate » a un nom de variable dupliqué « duplicate »",
423
            "le champ « 7th field duplicate » a un nom de variable dupliqué « duplicate »"
429
               "Le champ « 7th field bad duplicate » a un nom de variable dupliqué « duplicate » mais pas le même type que « 6th field duplicate », tous les champs avec ce nom seront ignorés (string != bool)."
424 430
         ]
425 431
      }
426 432
   ],
tests/test_wcs.py
54 54
    for url_with_limit in url_with_limits:
55 55
        assert 'limit=500&' in url_with_limit
56 56

  
57
    assert (
58
        'Le champ « 7th field bad duplicate » a un nom de variable dupliqué '
59
        '« duplicate » mais pas le même type que « 6th field duplicate », '
60
        'tous les champs avec ce nom seront ignorés (string != bool).') in caplog.text
61

  
57 62
    expected_schema = [
58 63
        ('agent', 'id'),
59 64
        ('agent', 'label'),
......
103 108
        ('formdata_demande', 'field_itemOpen'),
104 109
        ('formdata_demande', 'field_stringCaseSensitive-\xe9'),
105 110
        ('formdata_demande', 'field_integer'),
111
        ('formdata_demande', 'field_good_duplicate'),
106 112
        ('formdata_demande', 'function__receiver'),
107 113
        ('formdata_demande_field_item', 'id'),
108 114
        ('formdata_demande_field_item', 'label'),
......
167 173
        expected_json_schema['pg_dsn'] = postgres_db.dsn
168 174
        assert json_schema == expected_json_schema
169 175

  
176
    # verify data in duplicated columns
177
    with postgres_db.conn() as conn:
178
        with conn.cursor() as c:
179
            c.execute('SET search_path = olap')
180
            c.execute('SELECT field_good_duplicate, count(id) '
181
                      'FROM formdata_demande '
182
                      'GROUP BY field_good_duplicate '
183
                      'ORDER BY field_good_duplicate')
184
            assert dict(c.fetchall()) == {
185
                'a': 37,
186
                'b': 13,
187
            }
188

  
170 189

  
171 190
def test_requests_exception(wcs, postgres_db, tmpdir, olap_cmd, caplog):
172 191
    @httmock.urlmatch()
......
189 208
            olap_cmd(no_log_errors=False)
190 209
    assert 'invalid signature' in caplog.text
191 210

  
211

  
192 212
def test_requests_not_json(wcs, postgres_db, tmpdir, olap_cmd, caplog):
193 213
    @httmock.urlmatch()
194 214
    def return_invalid_json(url, request):
wcs_olap/feeder.py
1023 1023
            fields += self.formdef.schema.workflow.fields
1024 1024

  
1025 1025
        # filter duplicates
1026
        duplicate_varnames = set()
1027 1026
        self.good_fields = good_fields = OrderedDict()
1027
        bad_varnames = set()
1028 1028
        for field in fields:
1029 1029
            if field.type not in ('item', 'bool', 'string'):
1030 1030
                continue
1031 1031
            if field.anonymise is True:
1032 1032
                continue
1033 1033
            if not field.varname:
1034
                add_warning('le champ « %s » n\' a pas de nom de variable, il a été ignoré' % field.label)
1034
                add_warning('Le champ « %s » n\' a pas de nom de variable, il a été ignoré' % field.label)
1035 1035
                continue
1036
            if field.varname in good_fields:
1037
                # duplicate found
1038
                duplicate_varnames.add(field.varname)
1039
                add_warning('le champ « %(label)s » a un nom de variable dupliqué « %(varname)s »' % {
1040
                    'label': good_fields[field.varname].label,
1041
                    'varname': field.varname
1042
                })
1036
            if field.varname in good_fields and good_fields[field.varname].type != field.type:
1037
                # duplicate found, but type is not coherent
1038
                add_warning(
1039
                    'Le champ « %(label)s » a un nom de variable dupliqué « %(varname)s » '
1040
                    'mais pas le même type que « %(label_good)s », tous les champs avec ce nom seront ignorés '
1041
                    '(%(type)s != %(type_good)s).' % {
1042
                        'label': field.label,
1043
                        'varname': field.varname,
1044
                        'type': field.type,
1045
                        'label_good': good_fields[field.varname].label,
1046
                        'type_good': good_fields[field.varname].type,
1047
                    }
1048
                )
1043 1049
                del self.good_fields[field.varname]
1044
            if field.varname in duplicate_varnames:
1045
                add_warning('le champ « %(label)s » a un nom de variable dupliqué « %(varname)s »' % field.__dict__)
1050
                bad_varnames.add(field.varname)
1051
                continue
1052
            if field.varname in bad_varnames:
1053
                add_warning('Le champ « %s » n\' est un doublon d\'un champ de type différent, il a été ignoré'
1054
                            % field.label)
1046 1055
                continue
1047 1056
            self.good_fields[field.varname] = field
1048 1057

  
1049
-