Projet

Général

Profil

0001-misc-allow-items-fields-to-be-prefilled-by-template-.patch

Frédéric Péters, 19 octobre 2021 13:59

Télécharger (5,92 ko)

Voir les différences:

Subject: [PATCH] misc: allow items fields to be prefilled by template (#56159)

 tests/admin_pages/test_form.py |  3 +-
 tests/form_pages/test_all.py   | 73 ++++++++++++++++++++++++++++++++++
 wcs/fields.py                  | 20 +++++++---
 3 files changed, 90 insertions(+), 6 deletions(-)
tests/admin_pages/test_form.py
1909 1909
    assert FormDef.get(1).fields[0].min_choices == 2
1910 1910
    assert FormDef.get(1).fields[0].max_choices == 5
1911 1911

  
1912
    # check prefilling is only possible with Python
1912
    # check prefilling is possible with a template or a Python expression
1913 1913
    resp = resp.follow()
1914 1914
    resp = resp.click('Edit', href='1/')
1915 1915
    assert resp.forms[0]['prefill$type'].options == [
1916 1916
        ('None', True, 'None'),
1917
        ('String / Template', False, 'String / Template'),
1917 1918
        ('Python Expression', False, 'Python Expression'),
1918 1919
    ]
1919 1920

  
tests/form_pages/test_all.py
3180 3180
        assert resp.form['f0$element2'].checked
3181 3181

  
3182 3182

  
3183
def test_form_page_template_prefill_items_field(pub):
3184
    create_user(pub)
3185
    formdef = create_formdef()
3186
    formdef.data_class().wipe()
3187
    formdef.fields = [
3188
        fields.ItemsField(
3189
            id='0',
3190
            label='items',
3191
            items=['foo', 'bar', 'baz'],
3192
            prefill={'type': 'string', 'value': 'foo,baz'},
3193
        )
3194
    ]
3195
    formdef.store()
3196

  
3197
    resp = get_app(pub).get('/test/')
3198
    assert resp.form['f0$element0'].checked
3199
    assert not resp.form['f0$element1'].checked
3200
    assert resp.form['f0$element2'].checked
3201
    # this selection will be reused in the complex data test
3202
    resp.form['f0$element1'].checked = True
3203
    resp.form['f0$element2'].checked = False
3204
    assert 'widget-prefilled' in resp.text
3205
    resp = resp.form.submit('submit')
3206
    resp = resp.form.submit('submit')
3207
    assert formdef.data_class().count() == 1
3208

  
3209
    # check with remote json
3210
    ds = {'type': 'json', 'value': 'http://remote.example.net/json'}
3211
    formdef.fields = [
3212
        fields.ItemsField(
3213
            id='0',
3214
            label='items',
3215
            data_source=ds,
3216
            display_disabled_items=True,
3217
            prefill={'type': 'string', 'value': 'foo,baz'},
3218
        )
3219
    ]
3220
    formdef.store()
3221

  
3222
    with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
3223
        data = {
3224
            'data': [
3225
                {'id': 'foo', 'text': 'hello'},
3226
                {'id': 'bar', 'text': 'world'},
3227
                {'id': 'baz', 'text': '!'},
3228
            ]
3229
        }
3230
        urlopen.side_effect = lambda *args: io.StringIO(json.dumps(data))
3231
        resp = get_app(pub).get('/test/')
3232
        assert resp.form['f0$elementfoo'].checked
3233
        assert not resp.form['f0$elementbar'].checked
3234
        assert resp.form['f0$elementbaz'].checked
3235

  
3236
        # check with template returning a complex data
3237
        formdef.fields = [
3238
            fields.ItemsField(
3239
                id='0',
3240
                varname='items',
3241
                label='items',
3242
                data_source=ds,
3243
                display_disabled_items=True,
3244
                prefill={'type': 'string', 'value': '{{form_objects|first|get:"form_var_items_raw"}}'},
3245
            )
3246
        ]
3247
        formdef.store()
3248

  
3249
        # it will use foo,bar as selected in the first part of this test
3250
        resp = get_app(pub).get('/test/')
3251
        assert resp.form['f0$elementfoo'].checked
3252
        assert resp.form['f0$elementbar'].checked
3253
        assert not resp.form['f0$elementbaz'].checked
3254

  
3255

  
3183 3256
def test_form_page_changing_prefill(pub):
3184 3257
    formdef = create_formdef()
3185 3258
    formdef.data_class().wipe()
wcs/fields.py
106 106
        ]
107 107

  
108 108
        if field and field.type == 'items':
109
            # limit choices to python as items field are prefilled with list
110
            # of strings
111
            options = [x for x in options if x[0] in ('none', 'formula')]
109
            # limit choices strings (must be templates giving complex data) or
110
            # python; items field are prefilled with list of strings
111
            options = [x for x in options if x[0] in ('none', 'string', 'formula')]
112 112
        elif field and field.type == 'map':
113 113
            # limit choices to geolocation
114 114
            options = [x for x in options if x[0] in ('none', 'string', 'geolocation')]
......
463 463
            if not Template.is_template_string(value):
464 464
                return (value, explicit_lock)
465 465

  
466
            context = get_publisher().substitutions.get_context_variables(mode='lazy')
466
            from wcs.workflows import WorkflowStatusItem
467

  
467 468
            try:
468
                return (Template(value, autoescape=False, raises=True).render(context), explicit_lock)
469
                with get_publisher().complex_data():
470
                    v = WorkflowStatusItem.compute(
471
                        value,
472
                        raises=True,
473
                        allow_complex=self.allow_complex and not force_string,
474
                        record_errors=False,
475
                    )
476
                    if v and self.allow_complex:
477
                        v = get_publisher().get_cached_complex_data(v)
478
                return (v, explicit_lock)
469 479
            except TemplateError:
470 480
                return ('', explicit_lock)
471 481
            except AttributeError as e:
472
-