form: fix dynamic item field value on reload (#48495)
This commit is contained in:
parent
c5c52e4ab8
commit
62cf149fe7
|
@ -1,4 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
import mock
|
||||
|
||||
from django.utils.six import StringIO
|
||||
|
||||
import pytest
|
||||
from webtest import Upload
|
||||
|
@ -870,3 +874,81 @@ def test_block_post_condition_on_2nd_page(pub, blocks_feature):
|
|||
assert 'You shall not pass.' not in resp.text
|
||||
resp = resp.form.submit('submit') # -> submit
|
||||
resp = resp.follow()
|
||||
|
||||
|
||||
@mock.patch('wcs.qommon.misc.urlopen')
|
||||
def test_block_with_dynamic_item_field(mock_urlopen, pub, blocks_feature):
|
||||
def data_source(url):
|
||||
url, query = url.split('?q=')
|
||||
payload = []
|
||||
if query == 'foo':
|
||||
payload = [{'id': '1', 'text': 'foo'}]
|
||||
elif query == 'bar':
|
||||
payload = [{'id': '2', 'text': 'bar'}]
|
||||
return StringIO(json.dumps({'data': payload}))
|
||||
mock_urlopen.side_effect = lambda url: data_source(url)
|
||||
|
||||
FormDef.wipe()
|
||||
BlockDef.wipe()
|
||||
|
||||
block = BlockDef()
|
||||
block.name = 'foobar'
|
||||
block.fields = [
|
||||
fields.StringField(
|
||||
id='123', required=True, label='Test',
|
||||
type='string', varname='foo'),
|
||||
]
|
||||
block.store()
|
||||
|
||||
formdef = FormDef()
|
||||
formdef.name = 'foo'
|
||||
formdef.fields = [
|
||||
fields.StringField(
|
||||
id='1', label='field 1',
|
||||
type='string', varname='foo'),
|
||||
fields.ItemField(
|
||||
id='2', label='field 2',
|
||||
varname='bar', data_source={'type': 'json', 'value': 'http://whatever/data-source?q={{form_var_foo|default:""}}'}),
|
||||
fields.BlockField(id='3', label='block', type='block:foobar', max_items=3),
|
||||
]
|
||||
formdef.store()
|
||||
|
||||
app = get_app(pub)
|
||||
|
||||
resp = app.get(formdef.get_url())
|
||||
# select first field
|
||||
resp.form['f1'] = 'foo'
|
||||
live_resp = app.post('/foo/live?modified_field_id=1', params=resp.form.submit_fields())
|
||||
assert live_resp.json['result']['2']['items'] == [{'id': '1', 'text': 'foo'}]
|
||||
|
||||
resp.form['f2'].options = []
|
||||
for item in live_resp.json['result']['2']['items']:
|
||||
# simulate javascript filling the <select>
|
||||
resp.form['f2'].options.append((item['id'], False, item['text']))
|
||||
|
||||
# select second field
|
||||
resp.form['f2'] = '1'
|
||||
|
||||
# add block
|
||||
resp = resp.form.submit('f3$add_element')
|
||||
# second field value is kept
|
||||
assert resp.form['f2'].value == '1'
|
||||
|
||||
resp = app.get(formdef.get_url())
|
||||
# select first field
|
||||
resp.form['f1'] = 'foo'
|
||||
live_resp = app.post('/foo/live?modified_field_id=1', params=resp.form.submit_fields())
|
||||
assert live_resp.json['result']['2']['items'] == [{'id': '1', 'text': 'foo'}]
|
||||
|
||||
resp.form['f2'].options = []
|
||||
for item in live_resp.json['result']['2']['items']:
|
||||
# simulate javascript filling the <select>
|
||||
resp.form['f2'].options.append((item['id'], False, item['text']))
|
||||
|
||||
# select second field
|
||||
resp.form['f2'] = '1'
|
||||
|
||||
# submit form with empty value in block
|
||||
resp = resp.form.submit()
|
||||
# second field value is kept
|
||||
assert resp.form['f2'].value == '1'
|
||||
|
|
|
@ -396,7 +396,7 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
had_prefill = True
|
||||
return had_prefill
|
||||
|
||||
def page(self, page, page_change=True, page_error_messages=None, submit_button=None):
|
||||
def page(self, page, page_change=True, page_error_messages=None, submit_button=None, transient_formdata=None):
|
||||
displayed_fields = []
|
||||
|
||||
session = get_session()
|
||||
|
@ -405,7 +405,10 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
magictoken = get_request().form['magictoken']
|
||||
self.feed_current_data(magictoken)
|
||||
|
||||
form = self.create_form(page, displayed_fields)
|
||||
with get_publisher().substitutions.temporary_feed(
|
||||
transient_formdata, force_mode='lazy'):
|
||||
form = self.create_form(page, displayed_fields, transient_formdata=transient_formdata)
|
||||
|
||||
if submit_button is True:
|
||||
# submit_button at True means a non-submitting button has been
|
||||
# clicked; details in [ADD_ROW_BUTTON].
|
||||
|
@ -952,7 +955,8 @@ class FormPage(Directory, FormTemplateMixin):
|
|||
if form.has_errors() or form.get_submit() is True:
|
||||
return self.page(page, page_change=False,
|
||||
page_error_messages=page_error_messages,
|
||||
submit_button=form.get_submit())
|
||||
submit_button=form.get_submit(),
|
||||
transient_formdata=transient_formdata)
|
||||
|
||||
form_data = session.get_by_magictoken(magictoken, {})
|
||||
with get_publisher().substitutions.temporary_feed(
|
||||
|
|
Loading…
Reference in New Issue