1583 lines
54 KiB
Python
1583 lines
54 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
import io
|
|
import json
|
|
|
|
import mock
|
|
import pytest
|
|
from webtest import Upload
|
|
|
|
from wcs import fields
|
|
from wcs.blocks import BlockDef
|
|
from wcs.categories import Category
|
|
from wcs.data_sources import NamedDataSource
|
|
from wcs.formdef import FormDef
|
|
from wcs.wf.form import FormWorkflowStatusItem, WorkflowFormFieldsFormDef
|
|
from wcs.workflows import JumpOnSubmitWorkflowStatusItem, Workflow
|
|
|
|
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
|
|
from .test_all import create_user
|
|
|
|
|
|
def pytest_generate_tests(metafunc):
|
|
if 'pub' in metafunc.fixturenames:
|
|
metafunc.parametrize('pub', ['pickle', 'sql', 'pickle-templates', 'pickle-lazy'], indirect=True)
|
|
|
|
|
|
@pytest.fixture
|
|
def pub(request, emails):
|
|
pub = create_temporary_pub(
|
|
sql_mode=bool('sql' in request.param),
|
|
templates_mode=bool('templates' in request.param),
|
|
lazy_mode=bool('lazy' in request.param),
|
|
)
|
|
pub.cfg['identification'] = {'methods': ['password']}
|
|
pub.cfg['language'] = {'language': 'en'}
|
|
pub.write_cfg()
|
|
|
|
if Category.count() == 0:
|
|
cat = Category(name='foobar')
|
|
cat.store()
|
|
|
|
return pub
|
|
|
|
|
|
def teardown_module(module):
|
|
clean_temporary_pub()
|
|
|
|
|
|
def test_block_simple(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar', hint='hintblock'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert resp.text.count('>hintblock<') == 1
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert resp.form['f1$element0$f123'].attrs['readonly']
|
|
assert resp.form['f1$element0$f123'].value == 'foo'
|
|
assert resp.form['f1$element0$f234'].attrs['readonly']
|
|
assert resp.form['f1$element0$f234'].value == 'bar'
|
|
resp = resp.form.submit('submit') # -> end page
|
|
resp = resp.follow()
|
|
assert '>foo<' in resp
|
|
assert '>bar<' in resp
|
|
|
|
|
|
def test_block_required(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp = resp.form.submit('submit') # -> error page
|
|
assert 'There were errors processing the form' in resp
|
|
assert resp.text.count('required field') == 1
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp = resp.form.submit('submit') # -> error page
|
|
assert 'There were errors processing the form' in resp
|
|
assert resp.text.count('required field') == 1
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
|
|
# only one required
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.StringField(id='234', required=False, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
|
|
# none required, but globally required
|
|
block.fields = [
|
|
fields.StringField(id='123', required=False, label='Test', type='string'),
|
|
fields.StringField(id='234', required=False, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
resp = app.get(formdef.get_url())
|
|
resp = resp.form.submit('submit') # -> error page
|
|
assert 'There were errors processing the form' in resp
|
|
assert resp.text.count('required field') == 1
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
|
|
|
|
def test_block_required_previous_page(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
for multipage in (False, True):
|
|
# single block, go to validation page, come back
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
if multipage:
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.BlockField(id='1', label='test', type='block:foobar', required=True),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
]
|
|
else:
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar', required=True),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp = resp.form.submit('submit') # -> error page
|
|
assert 'There were errors processing the form' in resp
|
|
assert resp.text.count('required field') == 1
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
if multipage:
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
|
|
if multipage:
|
|
resp = resp.form.submit('previous') # -> 2nd page
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
assert resp.text.count('required field') == 0
|
|
assert resp.form['f1$element0$f123'].value == 'foo'
|
|
assert resp.form['f1$element0$f234'].value == 'bar'
|
|
|
|
if multipage:
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
resp = resp.form.submit('submit') # -> submitted
|
|
|
|
assert formdef.data_class().count() == 1
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.data['1']['data'] == [{'123': 'foo', '234': 'bar'}]
|
|
|
|
# add two blocks, go to validation page, come back
|
|
if multipage:
|
|
formdef.fields[1].max_items = 3
|
|
else:
|
|
formdef.fields[0].max_items = 3
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('f1$add_element') # -> 1st page
|
|
resp.form['f1$element1$f123'] = 'foo2'
|
|
resp.form['f1$element1$f234'] = 'bar2'
|
|
if multipage:
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
|
|
if multipage:
|
|
resp = resp.form.submit('previous') # -> 2nd page
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
assert resp.text.count('required field') == 0
|
|
assert resp.form['f1$element0$f123'].value == 'foo'
|
|
assert resp.form['f1$element0$f234'].value == 'bar'
|
|
assert resp.form['f1$element1$f123'].value == 'foo2'
|
|
assert resp.form['f1$element1$f234'].value == 'bar2'
|
|
|
|
if multipage:
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
resp = resp.form.submit('submit') # -> submitted
|
|
|
|
assert formdef.data_class().count() == 1
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.data['1']['data'] == [{'123': 'foo', '234': 'bar'}, {'123': 'foo2', '234': 'bar2'}]
|
|
|
|
|
|
def test_block_date(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.DateField(id='234', required=True, label='Test2', type='date'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = '2020-06-16'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
resp = resp.form.submit('submit') # -> submit
|
|
resp = resp.follow()
|
|
assert '>2020-06-16<' in resp
|
|
|
|
|
|
def test_block_bool(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.BoolField(id='234', required=False, label='Test2', type='bool'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar'),
|
|
]
|
|
formdef.store()
|
|
|
|
for value in (True, False):
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'].checked = value
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert resp.form['f1$element0$f234disabled'].checked is value
|
|
assert resp.form['f1$element0$f234'].value == str(value)
|
|
assert 'Check values then click submit.' in resp
|
|
resp = resp.form.submit('submit') # -> submit
|
|
resp = resp.follow()
|
|
if value:
|
|
assert '<div class="value">Yes</div>' in resp
|
|
else:
|
|
assert '<div class="value">No</div>' in resp
|
|
|
|
|
|
def test_block_autocomplete_list(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.ItemField(
|
|
id='234',
|
|
required=True,
|
|
label='Test2',
|
|
type='item',
|
|
display_mode='autocomplete',
|
|
items=['Foo', 'Bar'],
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'Bar'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
resp = resp.form.submit('submit') # -> submit
|
|
resp = resp.follow()
|
|
assert '>Bar<' in resp
|
|
|
|
|
|
def test_block_geoloc_prefill(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(
|
|
id='123',
|
|
required=True,
|
|
label='Test',
|
|
type='string',
|
|
prefill={'type': 'geolocation', 'value': 'road'},
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert 'qommon.geolocation.js' in resp
|
|
assert resp.html.find('div', {'data-geolocation': 'road'})
|
|
|
|
|
|
def test_block_string_prefill(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(
|
|
id='123',
|
|
required=True,
|
|
label='Test',
|
|
type='string',
|
|
prefill={'type': 'string', 'value': '{{ form_var_foo }} World'},
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
block2 = BlockDef()
|
|
block2.name = 'foobar2'
|
|
block2.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
]
|
|
block2.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.StringField(id='1', label='string', varname='foo'),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
fields.BlockField(id='3', label='test', type='block:foobar'),
|
|
fields.BlockField(id='4', label='test', type='block:foobar2'),
|
|
]
|
|
formdef.store()
|
|
|
|
for i in range(2):
|
|
if i == 1:
|
|
# second pass, add another prefilled field in second block
|
|
block2.fields.append(
|
|
fields.StringField(
|
|
id='124',
|
|
required=True,
|
|
label='Test',
|
|
type='string',
|
|
prefill={'type': 'string', 'value': '{{ form_var_foo }} World'},
|
|
)
|
|
)
|
|
block2.store()
|
|
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1'] = 'Hello'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert not resp.pyquery('#form_error_f3') # not marked as error
|
|
assert not resp.pyquery('#form_error_f4') # ...
|
|
assert '>required field<' not in resp
|
|
assert resp.form['f3$element0$f123'].value == 'Hello World'
|
|
assert resp.form['f4$element0$f123'].value == ''
|
|
resp.form['f4$element0$f123'] = 'plop'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> end page
|
|
resp = resp.follow()
|
|
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.data['3']['data'][0]['123'] == 'Hello World'
|
|
if i == 1:
|
|
assert formdata.data['4']['data'][0]['124'] == 'Hello World'
|
|
|
|
# check unmodified prefilled field
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1'] = 'Hello'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.form['f3$element0$f123'].value == 'Hello World'
|
|
resp.form['f4$element0$f123'] = 'plop'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('previous') # -> 2nd page
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
resp.form['f1'] = 'Test'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.form['f3$element0$f123'].value == 'Test World'
|
|
|
|
# check modified prefilled field
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1'] = 'Hello'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.form['f3$element0$f123'].value == 'Hello World'
|
|
resp.form['f3$element0$f123'] = 'Foobar'
|
|
resp.form['f4$element0$f123'] = 'plop'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('previous') # -> 2nd page
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
resp.form['f1'] = 'Test'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.form['f3$element0$f123'].value == 'Foobar'
|
|
|
|
|
|
def test_block_prefill_and_required(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(
|
|
id='123', required=True, label='Test', type='string', prefill={'type': 'string', 'value': 'World'}
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
block2 = BlockDef()
|
|
block2.name = 'foobar2'
|
|
block2.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.BoolField(id='234', required=True, label='Test2', type='bool'),
|
|
]
|
|
block2.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.ItemField(id='1', required=True, label='Test2', type='item', items=['Foo', 'Bar']),
|
|
fields.BlockField(id='2', label='test', type='block:foobar'),
|
|
fields.BlockField(id='3', label='test', type='block:foobar2'),
|
|
]
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert '>required field<' not in resp
|
|
assert resp.form['f2$element0$f123'].value == 'World'
|
|
resp.form['f3$element0$f123'] = 'Hello'
|
|
resp = resp.form.submit('submit') # -> same page, error displyed
|
|
assert resp.text.count('>required field<') == 1
|
|
resp.form['f3$element0$f234'].checked = True
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> end page
|
|
resp = resp.follow()
|
|
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.data['2']['data'][0]['123'] == 'World'
|
|
assert formdata.data['3']['data'][0]['123'] == 'Hello'
|
|
assert formdata.data['3']['data'][0]['234'] is True
|
|
|
|
|
|
def test_block_locked_prefill(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(
|
|
id='123',
|
|
required=True,
|
|
label='Test',
|
|
type='string',
|
|
prefill={'type': 'string', 'value': '{{ form_var_foo }} World', 'locked': True},
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.StringField(id='1', label='string', varname='foo'),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
fields.BlockField(id='3', label='test', type='block:foobar'),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1'] = 'Hello'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.form['f3$element0$f123'].value == 'Hello World'
|
|
assert 'readonly' in resp.form['f3$element0$f123'].attrs
|
|
resp.form['f3$element0$f123'].value = 'Hello' # try changing the value
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> end page
|
|
resp = resp.follow()
|
|
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.data['3']['data'][0]['123'] == 'Hello World' # value got reverted
|
|
|
|
|
|
def test_block_multi_string_prefill(pub):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(
|
|
id='123',
|
|
required=True,
|
|
label='Test',
|
|
type='string',
|
|
prefill={'type': 'string', 'value': '{{ form_var_foo }} World'},
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.StringField(id='1', label='string', varname='foo'),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
fields.BlockField(id='3', label='test', type='block:foobar', max_items=5),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1'] = 'Hello'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert not resp.pyquery('#form_error_f3') # not marked as error
|
|
assert resp.form['f3$element0$f123'].value == 'Hello World'
|
|
resp = resp.form.submit('f3$add_element') # add second row
|
|
assert resp.form['f3$element1$f123'].value == 'Hello World'
|
|
resp.form['f3$element1$f123'].value = 'Something else'
|
|
resp = resp.form.submit('f3$add_element') # add third row
|
|
assert resp.form['f3$element0$f123'].value == 'Hello World'
|
|
assert resp.form['f3$element1$f123'].value == 'Something else' # unchanged
|
|
assert resp.form['f3$element2$f123'].value == 'Hello World'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> end page
|
|
resp = resp.follow()
|
|
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.data['3']['data'][0]['123'] == 'Hello World'
|
|
assert formdata.data['3']['data'][1]['123'] == 'Something else'
|
|
assert formdata.data['3']['data'][2]['123'] == 'Hello World'
|
|
|
|
|
|
def test_block_multi_string_modify_prefill(pub):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(
|
|
id='123',
|
|
required=True,
|
|
label='Test',
|
|
type='string',
|
|
prefill={'type': 'string', 'value': '{{ form_var_foo }} World'},
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.StringField(id='1', label='string', varname='foo'),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
fields.BlockField(id='3', label='test', type='block:foobar', max_items=5),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
|
|
formdef.data_class().wipe()
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1'] = 'Hello'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert not resp.pyquery('#form_error_f3') # not marked as error
|
|
assert resp.form['f3$element0$f123'].value == 'Hello World'
|
|
resp = resp.form.submit('f3$add_element') # add second row
|
|
assert resp.form['f3$element1$f123'].value == 'Hello World'
|
|
resp.form['f3$element1$f123'].value = 'Something else'
|
|
resp = resp.form.submit('f3$add_element') # add third row
|
|
assert resp.form['f3$element0$f123'].value == 'Hello World'
|
|
assert resp.form['f3$element1$f123'].value == 'Something else' # unchanged
|
|
assert resp.form['f3$element2$f123'].value == 'Hello World'
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
resp.form['f1'] = 'Bye'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.form['f3$element0$f123'].value == 'Bye World' # updated
|
|
assert resp.form['f3$element1$f123'].value == 'Something else' # unchanged
|
|
assert resp.form['f3$element2$f123'].value == 'Bye World' # updated
|
|
|
|
|
|
def test_workflow_form_block_prefill(pub):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
create_user(pub)
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(
|
|
id='123', required=True, label='Test', type='string', prefill={'type': 'user', 'value': 'email'}
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
wf = Workflow(name='status')
|
|
st1 = wf.add_status('Status1', 'st1')
|
|
|
|
display_form = FormWorkflowStatusItem()
|
|
display_form.id = '_x'
|
|
display_form.by = ['_submitter']
|
|
display_form.varname = 'xxx'
|
|
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
|
|
display_form.formdef.fields.append(fields.BlockField(id='3', label='test', type='block:foobar'))
|
|
st1.items.append(display_form)
|
|
display_form.parent = st1
|
|
|
|
wf.store()
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'test'
|
|
formdef.fields = []
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
resp = login(get_app(pub), username='foo', password='foo').get('/test/')
|
|
resp = resp.form.submit('submit') # -> validation
|
|
resp = resp.form.submit('submit').follow()
|
|
assert 'The form has been recorded' in resp
|
|
assert resp.form['fxxx_3$element0$f123'].value == 'foo@localhost'
|
|
|
|
|
|
def test_block_title_and_comment(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.TitleField(id='234', label='Blah', type='title'),
|
|
fields.CommentField(id='345', label='Blah', type='comment'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
resp = resp.form.submit('submit') # -> submit
|
|
resp = resp.follow()
|
|
|
|
|
|
def test_block_label(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(
|
|
id='1', label='Block Label', type='block:foobar', hint='', required=False, label_display='normal'
|
|
),
|
|
]
|
|
formdef.store()
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert resp.pyquery.find('div.title label.field--label#form_label_f1').text() == 'Block Label'
|
|
|
|
formdef.fields[0].label_display = 'subtitle'
|
|
formdef.fields[0].hint = 'foo bar !'
|
|
formdef.fields[0].required = True
|
|
formdef.store()
|
|
resp = app.get(formdef.get_url())
|
|
assert resp.pyquery.find('h4').text() == 'Block Label*'
|
|
resp.form['f1$element0$f123'] = 'something'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
assert resp.pyquery.find('h4').text() == 'Block Label'
|
|
|
|
formdef.fields[0].label_display = 'hidden'
|
|
formdef.store()
|
|
resp = app.get(formdef.get_url())
|
|
assert 'Block Label' not in resp.text
|
|
resp.form['f1$element0$f123'] = 'something'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
assert 'Block Label' not in resp.text
|
|
|
|
|
|
def test_block_multipage(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.BlockField(id='1', label='test', type='block:foobar'),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert resp.form['f1$element0$f123'].attrs['readonly']
|
|
assert resp.form['f1$element0$f123'].value == 'foo'
|
|
resp = resp.form.submit('previous') # -> 2nd page
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
assert 'readonly' not in resp.form['f1$element0$f123'].attrs
|
|
assert resp.form['f1$element0$f123'].value == 'foo'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> submit
|
|
resp = resp.follow()
|
|
assert '>foo<' in resp
|
|
assert '>bar<' in resp
|
|
|
|
|
|
def test_block_repeated(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.BlockField(id='1', label='test', type='block:foobar', max_items=3, hint='hintblock'),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert resp.text.count('>Test<') == 1
|
|
assert resp.text.count('>hintblock<') == 1
|
|
assert 'wcs-block-add-clicked' not in resp
|
|
assert 'Add another' in resp
|
|
assert resp.html.find('div', {'class': 'list-add'})
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.text.count('>Test<') == 2
|
|
assert resp.text.count('>hintblock<') == 1
|
|
assert 'wcs-block-add-clicked' in resp
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.text.count('>Test<') == 3
|
|
assert resp.text.count('>hintblock<') == 1
|
|
assert resp.pyquery('.list-add').attr['style'] == 'display: none'
|
|
|
|
# fill items (1st and 3rd row)
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp.form['f1$element2$f123'] = 'foo2'
|
|
resp.form['f1$element2$f234'] = 'bar2'
|
|
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
assert resp.form['f1$element0$f123'].value == 'foo'
|
|
assert resp.form['f1$element0$f234'].value == 'bar'
|
|
assert resp.form['f1$element1$f123'].value == 'foo2'
|
|
assert resp.form['f1$element1$f234'].value == 'bar2'
|
|
|
|
resp = resp.form.submit('previous') # -> 2nd page
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
assert 'wcs-block-add-clicked' not in resp
|
|
assert 'readonly' not in resp.form['f1$element0$f123'].attrs
|
|
assert resp.form['f1$element0$f123'].value == 'foo'
|
|
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> submit
|
|
resp = resp.follow()
|
|
assert '>foo<' in resp
|
|
assert '>bar<' in resp
|
|
assert '>foo2<' in resp
|
|
assert '>bar2<' in resp
|
|
|
|
|
|
def test_block_repeated_over_limit(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.BlockField(id='1', label='test', type='block:foobar', max_items=3),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert resp.text.count('>Test<') == 1
|
|
assert 'Add another' in resp
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.text.count('>Test<') == 2
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.text.count('>Test<') == 3
|
|
assert resp.pyquery('.list-add').attr['style'] == 'display: none'
|
|
|
|
# fill items
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp.form['f1$element1$f123'] = 'foo1'
|
|
resp.form['f1$element1$f234'] = 'bar1'
|
|
resp.form['f1$element2$f123'] = 'foo2'
|
|
resp.form['f1$element2$f234'] = 'bar2'
|
|
|
|
# (modify formdef to only allow 2)
|
|
formdef.fields[1].max_items = 2
|
|
formdef.store()
|
|
|
|
# submit form
|
|
resp = resp.form.submit('submit')
|
|
assert 'Too many elements (maximum: 2)' in resp
|
|
|
|
|
|
def test_block_repeated_files(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.FileField(id='234', required=True, label='Test2', type='file'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.BlockField(id='1', label='test', type='block:foobar', max_items=3),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert resp.text.count('>Test<') == 1
|
|
assert 'Add another' in resp
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.text.count('>Test<') == 2
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.text.count('>Test<') == 3
|
|
assert resp.pyquery('.list-add').attr['style'] == 'display: none'
|
|
|
|
# fill items (1st and 3rd row)
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234$file'] = Upload('test1.txt', b'foobar1', 'text/plain')
|
|
resp.form['f1$element2$f123'] = 'foo2'
|
|
resp.form['f1$element2$f234$file'] = Upload('test2.txt', b'foobar2', 'text/plain')
|
|
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
assert resp.form['f1$element0$f123'].value == 'foo'
|
|
assert 'test1.txt' in resp
|
|
assert resp.form['f1$element1$f123'].value == 'foo2'
|
|
assert 'test2.txt' in resp
|
|
|
|
resp = resp.form.submit('previous') # -> 2nd page
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> submit
|
|
resp = resp.follow()
|
|
assert '>foo<' in resp
|
|
assert 'test1.txt' in resp
|
|
assert '>foo2<' in resp
|
|
assert 'test2.txt' in resp
|
|
|
|
|
|
@pytest.mark.parametrize('removed_line', [0, 1, 2])
|
|
def test_block_repeated_remove_line(pub, blocks_feature, removed_line):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.BlockField(
|
|
id='1', label='test', type='block:foobar', max_items=5, hint='hintblock', remove_button=True
|
|
),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert resp.text.count('>Test<') == 1
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.text.count('>Test<') == 2
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.text.count('>Test<') == 3
|
|
|
|
# fill items on three rows
|
|
resp.form['f1$element0$f123'] = 'foo1'
|
|
resp.form['f1$element0$f234'] = 'bar1'
|
|
resp.form['f1$element1$f123'] = 'foo2'
|
|
resp.form['f1$element1$f234'] = 'bar2'
|
|
resp.form['f1$element2$f123'] = 'foo3'
|
|
resp.form['f1$element2$f234'] = 'bar3'
|
|
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
assert resp.form['f1$element0$f123'].value == 'foo1'
|
|
assert resp.form['f1$element0$f234'].value == 'bar1'
|
|
assert resp.form['f1$element1$f123'].value == 'foo2'
|
|
assert resp.form['f1$element1$f234'].value == 'bar2'
|
|
assert resp.form['f1$element2$f123'].value == 'foo3'
|
|
assert resp.form['f1$element2$f234'].value == 'bar3'
|
|
|
|
resp = resp.form.submit('previous') # -> 2nd page
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
# simulate javascript removing of block elements from DOM
|
|
resp.form.field_order.remove(
|
|
('f1$element%s$f123' % removed_line, resp.form.fields['f1$element%s$f123' % removed_line][0])
|
|
)
|
|
del resp.form.fields['f1$element%s$f123' % removed_line]
|
|
resp.form.field_order.remove(
|
|
('f1$element%s$f234' % removed_line, resp.form.fields['f1$element%s$f234' % removed_line][0])
|
|
)
|
|
del resp.form.fields['f1$element%s$f234' % removed_line]
|
|
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
values = ['1', '2', '3']
|
|
del values[removed_line]
|
|
assert resp.form['f1$element0$f123'].value == 'foo%s' % values[0]
|
|
assert resp.form['f1$element0$f234'].value == 'bar%s' % values[0]
|
|
assert resp.form['f1$element1$f123'].value == 'foo%s' % values[1]
|
|
assert resp.form['f1$element1$f234'].value == 'bar%s' % values[1]
|
|
assert 'f1$element2$f123' not in resp.form.fields
|
|
assert 'f1$element2$f234' not in resp.form.fields
|
|
|
|
resp = resp.form.submit('submit') # -> submit
|
|
assert len(formdef.data_class().select()[0].data['1']['data']) == 2
|
|
|
|
|
|
@pytest.mark.parametrize('block_name', ['foobar', 'Foo bar'])
|
|
def test_block_digest(pub, blocks_feature, block_name):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = block_name
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string', varname='foo'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string', varname='bar'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:%s' % block.slug, max_items=3),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('f1$add_element')
|
|
resp.form['f1$element1$f123'] = 'foo2'
|
|
resp.form['f1$element1$f234'] = 'bar2'
|
|
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> submit
|
|
|
|
assert formdef.data_class().select()[0].data['1']['data'] == [
|
|
{'123': 'foo', '234': 'bar'},
|
|
{'123': 'foo2', '234': 'bar2'},
|
|
]
|
|
# by default it gets the type of object
|
|
assert formdef.data_class().select()[0].data['1_display'] == '%s, %s' % (block.name, block.name)
|
|
|
|
# set a digest template
|
|
formdef.data_class().wipe()
|
|
|
|
block.digest_template = 'X{{%s_var_foo}}Y' % block.slug.replace('-', '_')
|
|
block.store()
|
|
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('f1$add_element')
|
|
resp.form['f1$element1$f123'] = 'foo2'
|
|
resp.form['f1$element1$f234'] = 'bar2'
|
|
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> submit
|
|
assert formdef.data_class().select()[0].data['1']['data'] == [
|
|
{'123': 'foo', '234': 'bar'},
|
|
{'123': 'foo2', '234': 'bar2'},
|
|
]
|
|
assert formdef.data_class().select()[0].data['1_display'] == 'XfooY, Xfoo2Y'
|
|
|
|
|
|
def test_block_digest_item(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
NamedDataSource.wipe()
|
|
|
|
# add a named data source
|
|
data_source = NamedDataSource(name='foobar')
|
|
data_source.data_source = {
|
|
'type': 'formula',
|
|
'value': repr([{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}]),
|
|
}
|
|
data_source.store()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string', varname='foo'),
|
|
fields.ItemField(
|
|
id='234', required=True, label='Test2', type='item', varname='bar', data_source={'type': 'foobar'}
|
|
),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar', max_items=3),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = '1'
|
|
resp = resp.form.submit('f1$add_element')
|
|
resp.form['f1$element1$f123'] = 'foo2'
|
|
resp.form['f1$element1$f234'] = '2'
|
|
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> submit
|
|
|
|
assert formdef.data_class().select()[0].data['1']['data'] == [
|
|
{'123': 'foo', '234': '1', '234_display': 'un'},
|
|
{'123': 'foo2', '234': '2', '234_display': 'deux'},
|
|
]
|
|
# by default it gets the type of object
|
|
assert formdef.data_class().select()[0].data['1_display'] == 'foobar, foobar'
|
|
|
|
# set a digest template
|
|
formdef.data_class().wipe()
|
|
|
|
block.digest_template = 'X{{foobar_var_bar}}Y'
|
|
block.store()
|
|
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = '1'
|
|
resp = resp.form.submit('f1$add_element')
|
|
resp.form['f1$element1$f123'] = 'foo2'
|
|
resp.form['f1$element1$f234'] = '2'
|
|
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> submit
|
|
assert formdef.data_class().select()[0].data['1']['data'] == [
|
|
{'123': 'foo', '234': '1', '234_display': 'un'},
|
|
{'123': 'foo2', '234': '2', '234_display': 'deux'},
|
|
]
|
|
assert formdef.data_class().select()[0].data['1_display'] == 'XunY, XdeuxY'
|
|
|
|
|
|
def test_block_post_condition_on_2nd_page(pub, blocks_feature):
|
|
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 = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.PageField(
|
|
id='1',
|
|
label='2nd page',
|
|
type='page',
|
|
post_conditions=[
|
|
{
|
|
'condition': {'type': 'django', 'value': 'form_var_blockfoo|getlist:"foo"|sum == 5'},
|
|
'error_message': 'You shall not pass.',
|
|
}
|
|
],
|
|
),
|
|
fields.BlockField(id='2', label='test', type='block:foobar', max_items=3, varname='blockfoo'),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp = resp.form.submit('submit') # -> second page
|
|
resp.form['f2$element0$f123'] = 2
|
|
resp = resp.form.submit('f2$add_element')
|
|
resp.form['f2$element1$f123'] = 3
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
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 io.StringIO(json.dumps({'data': payload}))
|
|
|
|
mock_urlopen.side_effect = data_source
|
|
|
|
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'
|
|
|
|
|
|
def test_block_used_in_later_prefill(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Amount', type='string', varname='amount'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.PageField(id='0', label='1st page', type='page'),
|
|
fields.BlockField(
|
|
id='1', label='test', type='block:foobar', varname='data', max_items=3, hint='hintblock'
|
|
),
|
|
fields.PageField(id='2', label='2nd page', type='page'),
|
|
fields.StringField(
|
|
id='3', label='sum', prefill={'type': 'string', 'value': '{{form_var_data|getlist:"amount"|sum}}'}
|
|
),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = '5'
|
|
resp = resp.form.submit('f1$add_element')
|
|
resp.form['f1$element1$f123'] = '3'
|
|
resp = resp.form.submit('f1$add_element')
|
|
resp.form['f1$element2$f123'] = '2'
|
|
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.form['f3'].value == '10'
|
|
|
|
resp = resp.form.submit('previous') # -> 1st page
|
|
resp.form['f1$element2$f123'] = '1'
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.form['f3'].value == '9'
|
|
|
|
|
|
def test_block_add_and_locked_field(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Amount', type='string', varname='amount'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar', varname='data', max_items=3),
|
|
fields.StringField(id='2', label='foo', prefill={'type': 'string', 'value': 'Foo', 'locked': True}),
|
|
]
|
|
formdef.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
assert resp.form['f2'].value == 'Foo'
|
|
assert 'readonly' in resp.form['f2'].attrs
|
|
resp.form['f1$element0$f123'] = 'a'
|
|
resp = resp.form.submit('f1$add_element')
|
|
assert resp.form['f2'].value == 'Foo'
|
|
assert 'readonly' in resp.form['f2'].attrs
|
|
resp.form['f1$element1$f123'] = 'b'
|
|
resp = resp.form.submit('f1$add_element')
|
|
resp.form['f1$element2$f123'] = 'c'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
resp = resp.form.submit('submit') # -> submit
|
|
|
|
|
|
def test_block_subfields_display_locations(pub, blocks_feature):
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
fields.TitleField(id='234', label='Blah Title', type='title'),
|
|
fields.SubtitleField(id='345', label='Blah Subtitle', type='subtitle'),
|
|
fields.CommentField(id='456', label='Blah Comment', type='comment'),
|
|
]
|
|
block.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar'),
|
|
]
|
|
formdef.store()
|
|
|
|
# default mode
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'Blah Field'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
assert not resp.pyquery('[style="display: none"] [data-field-id="123"]')
|
|
assert resp.pyquery('[data-field-id="234"]')
|
|
assert not resp.pyquery('[style="display: none"] [data-field-id="234"]')
|
|
assert resp.pyquery('[data-field-id="345"]')
|
|
assert not resp.pyquery('[style="display: none"] [data-field-id="345"]')
|
|
|
|
resp = resp.form.submit('submit').follow() # -> submitted
|
|
assert 'Blah Field' in resp.text
|
|
assert 'Blah Title' in resp.text
|
|
assert 'Blah Subtitle' in resp.text
|
|
assert 'Blah Comment' not in resp.text
|
|
|
|
# all on validation page
|
|
for field in block.fields:
|
|
field.display_locations = ['validation']
|
|
block.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'Blah Field'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
assert not resp.pyquery('[style="display: none"] [data-field-id="123"]')
|
|
assert resp.pyquery('[data-field-id="234"]')
|
|
assert not resp.pyquery('[style="display: none"] [data-field-id="234"]')
|
|
assert resp.pyquery('[data-field-id="345"]')
|
|
assert not resp.pyquery('[style="display: none"] [data-field-id="345"]')
|
|
assert resp.pyquery('[data-field-id="456"]')
|
|
assert not resp.pyquery('[style="display: none"] [data-field-id="456"]')
|
|
|
|
# none on validation page
|
|
for field in block.fields:
|
|
field.display_locations = []
|
|
block.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'Blah Field'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
assert resp.pyquery('[style="display: none"] [data-field-id="123"]')
|
|
assert resp.pyquery('[style="display: none"] [data-field-id="234"]')
|
|
assert resp.pyquery('[style="display: none"] [data-field-id="345"]')
|
|
assert not resp.pyquery('[data-field-id="456"]')
|
|
|
|
# all on summary page
|
|
for field in block.fields:
|
|
field.display_locations = ['summary']
|
|
block.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'Blah Field'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
resp = resp.form.submit('submit').follow() # -> submitted
|
|
|
|
assert 'Blah Field' in resp.text
|
|
assert 'Blah Title' in resp.text
|
|
assert 'Blah Subtitle' in resp.text
|
|
assert 'Blah Comment' in resp.text
|
|
|
|
# none on summary page
|
|
for field in block.fields:
|
|
field.display_locations = []
|
|
block.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'Blah Field'
|
|
resp = resp.form.submit('submit') # -> validation page
|
|
assert 'Check values then click submit.' in resp.text
|
|
resp = resp.form.submit('submit').follow() # -> submitted
|
|
|
|
assert 'Blah Field' not in resp.text
|
|
assert 'Blah Title' not in resp.text
|
|
assert 'Blah Subtitle' not in resp.text
|
|
assert 'Blah Comment' not in resp.text
|
|
|
|
|
|
def test_workflow_display_form_with_block_add(pub):
|
|
user = create_user(pub)
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar2'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string'),
|
|
]
|
|
block.store()
|
|
|
|
wf = Workflow.get_default_workflow()
|
|
wf.id = '2'
|
|
wf.store()
|
|
wf = Workflow.get(wf.id)
|
|
status = wf.get_status('new')
|
|
status.items = []
|
|
display_form = FormWorkflowStatusItem()
|
|
display_form.id = '_display_form'
|
|
display_form.by = ['_submitter']
|
|
display_form.varname = 'blah'
|
|
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
|
|
display_form.formdef.fields = [
|
|
fields.StringField(id='1', label='Test', varname='str', type='string', required=True),
|
|
fields.BlockField(id='2', label='Blocks', type='block:foobar2', varname='data', max_items=3),
|
|
]
|
|
status.items.append(display_form)
|
|
display_form.parent = status
|
|
|
|
jump = JumpOnSubmitWorkflowStatusItem()
|
|
jump.id = '_jump'
|
|
jump.status = 'accepted'
|
|
status.items.append(jump)
|
|
jump.parent = status
|
|
|
|
wf.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
formdata = formdef.data_class()()
|
|
formdata.user_id = user.id
|
|
formdata.just_created()
|
|
formdata.status = 'wf-new'
|
|
formdata.store()
|
|
|
|
resp = login(get_app(pub), username='foo', password='foo').get(formdata.get_url())
|
|
resp.form['fblah_1'] = 'blah'
|
|
resp.form['fblah_2$element0$f123'] = 'foo'
|
|
resp = resp.form.submit('fblah_2$add_element')
|
|
resp.form['fblah_2$element1$f123'] = 'bar'
|
|
resp = resp.form.submit('submit')
|
|
|
|
assert formdef.data_class().get(formdata.id).workflow_data == {
|
|
'blah_var_data': 'foobar2, foobar2',
|
|
'blah_var_data_raw': {'data': [{'123': 'foo'}, {'123': 'bar'}], 'schema': {'123': 'string'}},
|
|
'blah_var_str': 'blah',
|
|
}
|