wcs/tests/admin_pages/test_block.py

539 lines
17 KiB
Python

import os
import re
import pytest
from webtest import Upload
from wcs import fields
from wcs.blocks import BlockDef
from wcs.categories import BlockCategory
from wcs.formdef import FormDef
from wcs.qommon.http_request import HTTPRequest
from wcs.workflows import Workflow
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
from .test_all import create_role, create_superuser
@pytest.fixture
def pub(request):
pub = create_temporary_pub()
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
pub.cfg['identification'] = {'methods': ['password']}
pub.cfg['language'] = {'language': 'en'}
pub.write_cfg()
return pub
def teardown_module(module):
clean_temporary_pub()
def test_block_404(pub):
create_superuser(pub)
create_role(pub)
BlockDef.wipe()
app = login(get_app(pub))
app.get('/backoffice/forms/blocks/1/', status=404)
def test_block_new(pub):
create_superuser(pub)
create_role(pub)
BlockDef.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/')
resp = resp.click('Fields blocks')
resp = resp.click('New field block')
resp.form['name'] = 'field block'
resp = resp.form.submit()
assert resp.location == 'http://example.net/backoffice/forms/blocks/1/'
resp = resp.follow()
assert '<h2>field block' in resp
assert 'There are not yet any fields' in resp
resp.form['label'] = 'foobar'
resp.form['type'] = 'string'
resp = resp.form.submit()
assert resp.location == 'http://example.net/backoffice/forms/blocks/1/'
resp = resp.follow()
resp.form['label'] = 'barfoo'
resp.form['type'] = 'string'
resp = resp.form.submit()
assert resp.location == 'http://example.net/backoffice/forms/blocks/1/'
resp = resp.follow()
assert len(BlockDef.get(1).fields) == 2
assert str(BlockDef.get(1).fields[0].id) != '1' # don't use integers
def test_block_options(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [fields.StringField(id='123', required=True, label='Test', type='string')]
block.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^settings$'))
assert 'readonly' not in resp.form['slug'].attrs
resp.form['name'] = 'foo bar'
resp = resp.form.submit('submit')
assert BlockDef.get(block.id).name == 'foo bar'
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.BlockField(id='0', label='test', type='block:%s' % block.slug),
]
formdef.store()
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^settings$'))
assert 'readonly' in resp.form['slug'].attrs
resp = resp.form.submit('cancel')
resp = resp.follow()
def test_block_options_slug(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'foo'
block.fields = []
block.store()
block2 = BlockDef()
block2.name = 'bar'
block2.fields = []
block2.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/settings' % block.id)
resp.form['slug'] = 'bar'
resp = resp.form.submit('submit')
assert 'This identifier is already used.' in resp.text
resp = app.get('/backoffice/forms/blocks/%s/settings' % block.id)
resp.form['slug'] = 'foo'
resp = resp.form.submit('submit').follow()
resp = app.get('/backoffice/forms/blocks/%s/settings' % block.id)
resp.form['slug'] = 'foo2'
resp = resp.form.submit('submit').follow()
block.refresh_from_storage()
assert block.slug == 'foo2'
def test_block_options_digest_template(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = []
block.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/settings' % block.id)
resp.form['digest_template'] = 'X{{form_var_foo}}Y'
resp = resp.form.submit('submit')
assert (
'Wrong variable &quot;form_var_…&quot; detected. Please replace it by &quot;block_var_…&quot;.'
in resp.text
)
block = BlockDef.get(block.id)
assert block.digest_template is None
resp = app.get('/backoffice/forms/blocks/%s/settings' % block.id)
resp.form['digest_template'] = 'X{{block_var_foo}}Y'
resp = resp.form.submit('submit')
block = BlockDef.get(block.id)
assert block.digest_template == 'X{{block_var_foo}}Y'
def test_block_export_import(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [fields.StringField(id='123', required=True, label='Test', type='string')]
block.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^export$'))
xml_export = resp.text
resp = app.get('/backoffice/forms/blocks/')
resp = resp.click(href='import')
resp = resp.form.submit('cancel') # shouldn't block on missing file
resp = resp.follow()
resp = resp.click(href='import')
resp = resp.form.submit()
assert 'ere were errors processing your form.' in resp
resp.form['file'] = Upload('block', xml_export.encode('utf-8'))
resp = resp.form.submit()
resp = resp.follow()
assert BlockDef.count() == 2
new_blockdef = [x for x in BlockDef.select() if str(x.id) != str(block.id)][0]
assert new_blockdef.name == 'Copy of foobar'
assert new_blockdef.slug == 'foobar_1'
assert len(new_blockdef.fields) == 1
assert new_blockdef.fields[0].id == '123'
resp = app.get('/backoffice/forms/blocks/')
resp = resp.click(href='import')
resp.form['file'] = Upload('block', xml_export.encode('utf-8'))
resp = resp.form.submit()
assert 'Copy of foobar (2)' in [x.name for x in BlockDef.select()]
# import invalid content
resp = app.get('/backoffice/forms/blocks/')
resp = resp.click(href='import')
resp.form['file'] = Upload('block', b'whatever')
resp = resp.form.submit()
assert 'Invalid File' in resp
def test_block_delete(pub):
create_superuser(pub)
BlockDef.wipe()
FormDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [fields.StringField(id='123', required=True, label='Test', type='string')]
block.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^delete$'))
assert 'You are about to irrevocably delete this block.' in resp
resp = resp.form.submit()
resp = resp.follow()
assert BlockDef.count() == 0
# in use
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [fields.StringField(id='123', required=True, label='Test', type='string')]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.BlockField(id='0', label='test', type='block:%s' % block.slug),
]
formdef.store()
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^delete$'))
assert 'This block is still used' in resp
def test_block_edit_duplicate_delete_field(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [fields.StringField(id='123', required=True, label='Test', type='string')]
block.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('123/$'))
resp.form['required'].checked = False
resp.form['varname'] = 'test'
resp = resp.form.submit('submit')
resp = resp.follow()
assert BlockDef.get(block.id).fields[0].required is False
assert BlockDef.get(block.id).fields[0].varname == 'test'
resp = resp.click(href=re.compile('123/duplicate$'))
resp = resp.follow()
assert len(BlockDef.get(block.id).fields) == 2
resp = resp.click(href='%s/delete' % BlockDef.get(block.id).fields[1].id)
resp = resp.form.submit('submit')
resp = resp.follow()
assert len(BlockDef.get(block.id).fields) == 1
def test_block_use_in_formdef(pub):
create_superuser(pub)
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 = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/fields/')
resp.forms[0]['label'] = 'a block field'
resp.forms[0]['type'] = 'block:foobar'
resp = resp.forms[0].submit().follow()
assert 'a block field' in resp.text
resp = resp.click('Edit', href='1/')
assert resp.pyquery('.field-edit--title').text() == 'a block field'
assert resp.pyquery('.field-edit--subtitle').text() == 'Block of fields - foobar'
assert resp.pyquery('.field-edit--subtitle a').attr.href.endswith(
'/backoffice/forms/blocks/%s/' % block.id
)
assert resp.form['max_items'].value == '1'
def test_block_use_in_workflow_backoffice_fields(pub):
create_superuser(pub)
FormDef.wipe()
Workflow.wipe()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [fields.StringField(id='123', required=True, label='Test', type='string')]
block.store()
workflow = Workflow(name='test')
workflow.store()
app = login(get_app(pub))
resp = app.get(workflow.get_admin_url())
resp = resp.click(href='backoffice-fields/').follow()
resp.forms[0]['label'] = 'a block field'
resp.forms[0]['type'] = 'block:foobar'
resp = resp.forms[0].submit().follow()
resp = resp.click('Edit')
assert resp.form['max_items'].value == '1'
def test_blocks_category(pub):
create_superuser(pub)
BlockCategory.wipe()
BlockDef.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/new')
assert 'category_id' not in resp.form.fields
block = BlockDef(name='foo')
block.store()
resp = app.get('/backoffice/forms/blocks/categories/')
resp = resp.click('New Category')
resp.forms[0]['name'] = 'a new category'
resp.forms[0]['description'] = 'description of the category'
resp = resp.forms[0].submit('submit')
assert BlockCategory.count() == 1
category = BlockCategory.select()[0]
assert category.name == 'a new category'
resp = app.get('/backoffice/forms/blocks/new')
assert 'category_id' in resp.form.fields
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^settings$'))
resp.forms[0]['category_id'] = str(category.id)
resp = resp.forms[0].submit('cancel').follow()
block.refresh_from_storage()
assert block.category_id is None
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^settings$'))
resp.forms[0]['category_id'] = str(category.id)
resp = resp.forms[0].submit('submit').follow()
block.refresh_from_storage()
assert str(block.category_id) == str(category.id)
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^settings$'))
assert resp.forms[0]['category_id'].value == str(category.id)
resp = app.get('/backoffice/forms/blocks/categories/')
resp = resp.click('New Category')
resp.forms[0]['name'] = 'a second category'
resp.forms[0]['description'] = 'description of the category'
resp = resp.forms[0].submit('submit')
assert BlockCategory.count() == 2
category2 = [x for x in BlockCategory.select() if x.id != category.id][0]
assert category2.name == 'a second category'
app.get('/backoffice/forms/blocks/categories/update_order?order=%s;%s;' % (category2.id, category.id))
categories = BlockCategory.select()
BlockCategory.sort_by_position(categories)
assert [x.id for x in categories] == [str(category2.id), str(category.id)]
app.get('/backoffice/forms/blocks/categories/update_order?order=%s;%s;0' % (category.id, category2.id))
categories = BlockCategory.select()
BlockCategory.sort_by_position(categories)
assert [x.id for x in categories] == [str(category.id), str(category2.id)]
resp = app.get('/backoffice/forms/blocks/categories/')
resp = resp.click('a new category')
resp = resp.click('Delete')
resp = resp.forms[0].submit()
block.refresh_from_storage()
assert not block.category_id
def test_removed_block_in_form_fields_list(pub):
create_superuser(pub)
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.BlockField(id='0', label='test', type='block:removed'),
]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/%s/fields/' % formdef.id)
assert 'Field Block (removed, missing)' in resp.text
def test_block_edit_field_warnings(pub):
create_superuser(pub)
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'ignore-hard-limits', 'false')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
BlockDef.wipe()
blockdef = BlockDef()
blockdef.name = 'block title'
blockdef.fields = [
fields.StringField(id='%d' % i, label='field %d' % i, type='string') for i in range(1, 10)
]
blockdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/' % blockdef.id)
assert 'more than 20 fields' not in resp.text
blockdef.fields.extend(
[fields.StringField(id='%d' % i, label='field %d' % i, type='string') for i in range(10, 31)]
)
blockdef.store()
resp = app.get('/backoffice/forms/blocks/%s/' % blockdef.id)
assert 'more than 30 fields' not in resp.text
assert '<div id="new-field"><h3>New Field</h3>' in resp.text
assert resp.pyquery('#fields-list a[title="Duplicate"]').length
blockdef.fields.extend(
[fields.StringField(id='%d' % i, label='field %d' % i, type='string') for i in range(21, 51)]
)
blockdef.store()
resp = app.get('/backoffice/forms/blocks/%s/' % blockdef.id)
assert 'This block of fields contains 60 fields.' in resp.text
assert '<div id="new-field"><h3>New Field</h3>' not in resp.text
assert not resp.pyquery('#fields-list a[title="Duplicate"]').length
def test_block_inspect(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.StringField(id='123', required=True, label='Test', type='string'),
fields.StringField(id='124', required=True, label='Test2', type='string'),
]
block.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click('Inspector')
assert resp.pyquery('#inspect-fields .inspect-field').length == 2
def test_block_duplicate(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'Foobar'
block.fields = [
fields.StringField(id='123', required=True, label='Test', type='string'),
fields.StringField(id='124', required=True, label='Test2', type='string'),
]
block.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^duplicate$'))
assert resp.form['name'].value == 'Foobar (copy)'
resp = resp.form.submit('cancel').follow()
assert BlockDef.count() == 1
resp = resp.click(href=re.compile('^duplicate$'))
assert resp.form['name'].value == 'Foobar (copy)'
resp = resp.form.submit('submit').follow()
assert BlockDef.count() == 2
resp = app.get('/backoffice/forms/blocks/%s/' % block.id)
resp = resp.click(href=re.compile('^duplicate$'))
assert resp.form['name'].value == 'Foobar (copy 2)'
resp.form['name'].value = 'other copy'
resp = resp.form.submit('submit').follow()
assert BlockDef.count() == 3
assert {x.name for x in BlockDef.select()} == {'Foobar', 'Foobar (copy)', 'other copy'}
assert {x.slug for x in BlockDef.select()} == {'foobar', 'foobar_copy', 'other_copy'}
block_copy = BlockDef.get_by_slug('other_copy')
assert len(block_copy.fields) == 2
def test_block_field_statistics_data_update(pub):
create_superuser(pub)
BlockDef.wipe()
block = BlockDef()
block.name = 'Foobar'
block.fields = [fields.BoolField(id='1', label='Bool', varname='bool', type='comment')]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.BlockField(id='0', label='test', type='block:%s' % block.slug),
]
formdef.store()
formdata = formdef.data_class()()
formdata.just_created()
formdata.data['0'] = {'data': [{'1': True}]}
formdata.store()
assert not formdata.statistics_data
app = login(get_app(pub))
resp = app.get('/backoffice/forms/blocks/%s/1/' % block.id)
resp.form['display_locations$element3'] = True
resp = resp.form.submit('submit').follow()
assert 'Statistics data will be collected in the background.' in resp.text
formdata.refresh_from_storage()
assert formdata.statistics_data == {'bool': [True]}