Projet

Général

Profil

0001-formdef-do-not-load-data-from-item-s-widgets-with-er.patch

Benjamin Dauvergne, 26 octobre 2021 22:37

Télécharger (4,41 ko)

Voir les différences:

Subject: [PATCH] formdef: do not load data from item's widgets with errors
 (#58207)

 tests/form_pages/test_all.py | 71 ++++++++++++++++++++++++++++++++++++
 wcs/formdef.py               | 14 ++++++-
 2 files changed, 83 insertions(+), 2 deletions(-)
tests/form_pages/test_all.py
7987 7987
    # and persist after being saved again
7988 7988
    resp = resp.form.submit('submit').follow()
7989 7989
    assert '<span>test.txt</span>' in resp.text
7990

  
7991

  
7992
def test_autosave_and_datasource_failure(mocker, pub, settings):
7993
    values = [
7994
        {'id': '1', 'text': 'item 1', 'foo': 'bar'},
7995
        {'id': '2', 'text': 'item 2', 'bar': 'foo'},
7996
    ]
7997

  
7998
    _get_structured_items_mock = mocker.patch('wcs.data_sources._get_structured_items')
7999
    _get_structured_items_mock.return_value = values
8000
    get_value_by_id_mock = mocker.patch('wcs.data_sources.NamedDataSource.get_value_by_id')
8001
    get_value_by_id_mock.return_value = values[0]
8002

  
8003
    create_user(pub)
8004

  
8005
    NamedDataSource.wipe()
8006
    data_source = NamedDataSource(name='foobar')
8007
    data_source.data_source = {'type': 'json', 'value': 'http://remote.example.net/json'}
8008
    data_source.query_parameter = 'q'
8009
    data_source.id_parameter = 'id'
8010
    data_source.store()
8011

  
8012
    formdef = create_formdef()
8013
    formdef.data_class().wipe()
8014

  
8015
    formdef.fields = [
8016
        fields.PageField(id='0', label='1st page', type='page'),
8017
        fields.ItemField(
8018
            id='1',
8019
            label='string',
8020
            type='item',
8021
            data_source={'type': 'foobar'},
8022
        ),
8023
        fields.StringField(id='2', label='string', required=False),
8024
        fields.PageField(id='3', label='2nd page', type='page'),
8025
        fields.StringField(id='4', label='string', required=False),
8026
    ]
8027
    formdef.store()
8028

  
8029
    app = get_app(pub)
8030
    login(app, username='foo', password='foo')
8031

  
8032
    resp = app.get('/test/')
8033
    # select item 1
8034
    resp.form['f1'].force_value('1')
8035
    # prevent nothing to save during autosave
8036
    resp.form['f2'].force_value('foobar')
8037
    # save data for asynchronous autosave
8038
    autosave_data = resp.form.submit_fields()
8039
    # submit first page
8040
    resp = resp.form.submit('submit')  # -> next page
8041

  
8042
    # simulate a still valid _ajax_form_token
8043
    valid_ajax_form_token = resp.form['_ajax_form_token'].value
8044
    autosave_data = [
8045
        (k, v) if k != '_ajax_form_token' else (k, valid_ajax_form_token) for k, v in autosave_data
8046
    ]
8047

  
8048
    # simulate data source failure
8049
    _get_structured_items_mock.return_value = []
8050
    resp_autosave = app.post('/test/autosave', params=autosave_data)
8051
    _get_structured_items_mock.return_value = values
8052
    assert resp_autosave.json == {'result': 'success'}
8053

  
8054
    # submit second page
8055
    resp = resp.form.submit('submit')  # -> validation page
8056
    # validate
8057
    resp = resp.form.submit('submit')  # -> submit
8058

  
8059
    data = formdef.data_class().select()[0].data
8060
    assert '1' not in data or (data['1'] is not None and data['1_display'] is not None)
wcs/formdef.py
29 29
import xml.etree.ElementTree as ET
30 30

  
31 31
from django.utils.encoding import force_bytes, force_text
32
from quixote import get_publisher, get_session
32
from quixote import get_publisher, get_request, get_session
33 33
from quixote.html import htmltext
34 34
from quixote.http_request import Upload
35 35

  
......
808 808
    @classmethod
809 809
    def get_field_data(cls, field, widget):
810 810
        d = {}
811
        d[field.id] = widget.parse()
811
        value = widget.parse()
812
        # ignore temporarily invalid value from item(s) fields
813
        if (
814
            field.key in ['item', 'items']
815
            and not value
816
            and widget.has_error()
817
            and get_request().form.get(widget.name)
818
        ):
819
            return {}
820

  
821
        d[field.id] = value
812 822
        if d.get(field.id) is not None and field.convert_value_from_str:
813 823
            d[field.id] = field.convert_value_from_str(d[field.id])
814 824
        field.set_value(d, d[field.id])
815
-