Projet

Général

Profil

0001-testdef-add-support-for-computed-fields-73330.patch

Valentin Deniaud, 12 janvier 2023 16:34

Télécharger (6,14 ko)

Voir les différences:

Subject: [PATCH] testdef: add support for computed fields (#73330)

 tests/test_testdef.py | 94 +++++++++++++++++++++++++++++++++++++++++++
 wcs/testdef.py        | 29 +++++++++++--
 2 files changed, 120 insertions(+), 3 deletions(-)
tests/test_testdef.py
437 437
    with pytest.raises(TestError) as excinfo:
438 438
        testdef.run(formdef)
439 439
    assert str(excinfo.value) == 'Invalid value "hop.pdf" for field "File": forbidden file type.'
440

  
441

  
442
def test_computed_field_support(pub):
443
    formdef = FormDef()
444
    formdef.name = 'test title'
445
    formdef.fields = [
446
        fields.PageField(
447
            id='0',
448
            label='1st page',
449
            type='page',
450
            post_conditions=[
451
                {
452
                    'condition': {
453
                        'type': 'django',
454
                        'value': 'form_var_foo == "xxx" and form_var_bar == "hop"',
455
                    },
456
                    'error_message': '',
457
                }
458
            ],
459
        ),
460
        fields.ComputedField(
461
            id='1',
462
            label='Computed (frozen)',
463
            varname='foo',
464
            value_template='{% firstof form_var_text "xxx" %}',
465
            freeze_on_initial_value=True,
466
        ),
467
        fields.ComputedField(
468
            id='2', label='Computed (live)', varname='bar', value_template='{% firstof form_var_text "xxx" %}'
469
        ),
470
        fields.StringField(id='3', label='Text', varname='text'),
471
    ]
472
    formdef.store()
473

  
474
    formdata = formdef.data_class()()
475
    formdata.just_created()
476
    formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
477
    formdata.data['1'] = 'zzz'
478
    formdata.data['3'] = 'hop'
479

  
480
    testdef = TestDef.create_from_formdata(formdef, formdata)
481
    testdef.run(formdef)
482

  
483
    formdef.fields[1].value_template = '{% for %}'
484
    testdef = TestDef.create_from_formdata(formdef, formdata)
485
    with pytest.raises(TestError) as excinfo:
486
        testdef.run(formdef)
487
    assert (
488
        str(excinfo.value)
489
        == 'Page 1 post condition was not met (form_var_foo == "xxx" and form_var_bar == "hop").'
490
    )
491

  
492

  
493
def test_computed_field_support_complex_data(pub):
494
    formdef = FormDef()
495
    formdef.name = 'test title'
496
    formdef.fields = [
497
        fields.PageField(
498
            id='0',
499
            label='1st page',
500
            type='page',
501
            post_conditions=[
502
                {'condition': {'type': 'django', 'value': '"z" in form_var_foo'}, 'error_message': ''}
503
            ],
504
        ),
505
        fields.ComputedField(
506
            id='1',
507
            label='Computed',
508
            varname='foo',
509
            value_template='{{form_objects|first|get:"form_var_items_raw"}}',
510
        ),
511
        fields.ItemsField(id='2', label='Items', varname='items', required=False),
512
    ]
513
    formdef.store()
514

  
515
    submitted_formdata = formdef.data_class()()
516
    submitted_formdata.just_created()
517
    submitted_formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
518
    submitted_formdata.data['2'] = ['a', 'b']
519
    submitted_formdata.store()
520

  
521
    formdata = formdef.data_class()()
522
    formdata.just_created()
523
    formdata.receipt_time = datetime.datetime(2021, 1, 1, 0, 0).timetuple()
524

  
525
    testdef = TestDef.create_from_formdata(formdef, formdata)
526
    with pytest.raises(TestError) as excinfo:
527
        testdef.run(formdef)
528
    assert str(excinfo.value) == 'Page 1 post condition was not met ("z" in form_var_foo).'
529

  
530
    submitted_formdata.data['2'] = ['a', 'b', 'z']
531
    submitted_formdata.store()
532

  
533
    testdef.run(formdef)
wcs/testdef.py
24 24
from wcs.compat import CompatHTTPRequest
25 25
from wcs.fields import Field, PageField
26 26
from wcs.qommon.form import FileWithPreviewWidget, Form, get_selection_error_text
27
from wcs.qommon.template import TemplateError
28
from wcs.workflows import WorkflowStatusItem
27 29

  
28 30
from .qommon import _, misc
29 31
from .qommon.storage import Equal
......
158 160
            self.evaluate_page_conditions(previous_page, formdata, objectdef)
159 161

  
160 162
    def fill_page_fields(self, fields, page, formdata, objectdef):
163
        computed_fields = []
161 164
        for field in fields:
162 165
            if field.type in ('subtitle', 'title', 'comment', 'computed'):
163 166
                continue
......
170 173
                    )
171 174
                continue
172 175

  
173
            value = self.data['fields'].get(field.id)
174
            value = field.from_json_value(value)
175
            self.run_widget_validation(field, value)
176
            if field.key == 'computed':
177
                try:
178
                    value = WorkflowStatusItem.compute(field.value_template, raises=True, allow_complex=True)
179
                except TemplateError:
180
                    continue
181

  
182
                if not field.freeze_on_initial_value:
183
                    computed_fields.append(field)
184

  
185
                formdata.data[field.id] = value
186
            else:
187
                value = self.data['fields'].get(field.id)
188
                value = field.from_json_value(value)
189
                self.run_widget_validation(field, value)
176 190
            formdata.data[field.id] = value
177 191

  
178 192
            get_publisher().substitutions.invalidate_cache()
179 193

  
194
        for field in computed_fields:
195
            try:
196
                value = WorkflowStatusItem.compute(field.value_template, raises=True, allow_complex=True)
197
            except TemplateError:
198
                continue
199

  
200
            formdata.data[field.id] = value
201
            get_publisher().substitutions.invalidate_cache()
202

  
180 203
    def evaluate_page_conditions(self, page, formdata, objectdef):
181 204
        for post_condition in page.post_conditions or []:
182 205
            condition = post_condition.get('condition', {})
183
-