Project

General

Profile

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

Benjamin Dauvergne, 25 Sep 2020 08:40 PM

Download (8.91 KB)

View differences:

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

 tests/conftest.py  | 14 ++++++++++++--
 tests/olap.model   | 11 +++++++++--
 tests/test_wcs.py  | 23 +++++++++++++++++++++++
 wcs_olap/feeder.py | 31 ++++++++++++++++++++-----------
 4 files changed, 64 insertions(+), 15 deletions(-)
tests/conftest.py
101 101
    fields.BoolField(id='3', label='3rd field', type='bool', varname='bool'),
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
    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'),
104
    fields.BoolField(id='6', label='6th field bad duplicate', type='bool', 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='9th field good duplicate', type='string', anonymise=False,
109
                       required=False, varname='good_duplicate'),
110
    fields.StringField(id='10', label='10th field good duplicate', type='string', anonymise=False,
111
                       required=False, varname='good_duplicate'),
112
    fields.StringField(id='11', label='11th field third bad duplicate', type='string',
113
                       anonymise=False, varname='duplicate'),
108 114
]
109 115
formdef.store()
110 116

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

  
138 148
    formdata.data['3'] = bool(i % 2)
139 149
    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": "10th 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 bad duplicate », tous les champs avec ce nom seront ignorés (string != bool).",
430
               "Le champ « 11th field third bad duplicate » est un doublon d'un champ de type différent, il a été ignoré."
424 431
         ]
425 432
      }
426 433
   ],
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 bad duplicate », '
60
        'tous les champs avec ce nom seront ignorés (string != bool).') in caplog.text
61
    assert (
62
        'Le champ « 11th field third bad duplicate » est un doublon d\'un '
63
        'champ de type différent, il a été ignoré.') in caplog.text
64

  
57 65
    expected_schema = [
58 66
        ('agent', 'id'),
59 67
        ('agent', 'label'),
......
103 111
        ('formdata_demande', 'field_itemOpen'),
104 112
        ('formdata_demande', 'field_stringCaseSensitive-\xe9'),
105 113
        ('formdata_demande', 'field_integer'),
114
        ('formdata_demande', 'field_good_duplicate'),
106 115
        ('formdata_demande', 'function__receiver'),
107 116
        ('formdata_demande_field_item', 'id'),
108 117
        ('formdata_demande_field_item', 'label'),
......
167 176
        expected_json_schema['pg_dsn'] = postgres_db.dsn
168 177
        assert json_schema == expected_json_schema
169 178

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

  
170 192

  
171 193
def test_requests_exception(wcs, postgres_db, tmpdir, olap_cmd, caplog):
172 194
    @httmock.urlmatch()
......
189 211
            olap_cmd(no_log_errors=False)
190 212
    assert 'invalid signature' in caplog.text
191 213

  
214

  
192 215
def test_requests_not_json(wcs, postgres_db, tmpdir, olap_cmd, caplog):
193 216
    @httmock.urlmatch()
194 217
    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 » 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
-