4560 lines
161 KiB
Python
4560 lines
161 KiB
Python
import datetime
|
|
import io
|
|
import json
|
|
import os
|
|
import random
|
|
import re
|
|
import time
|
|
import zipfile
|
|
from unittest import mock
|
|
|
|
import pytest
|
|
|
|
import wcs.qommon.storage as st
|
|
from wcs import fields
|
|
from wcs.api_access import ApiAccess
|
|
from wcs.blocks import BlockDef
|
|
from wcs.carddef import CardDef
|
|
from wcs.categories import Category
|
|
from wcs.formdef import FormDef
|
|
from wcs.qommon.http_request import HTTPRequest
|
|
from wcs.qommon.ident.password_accounts import PasswordAccount
|
|
from wcs.qommon.upload_storage import PicklableUpload
|
|
from wcs.roles import logged_users_role
|
|
from wcs.wf.create_formdata import Mapping
|
|
from wcs.wf.form import WorkflowFormFieldsFormDef
|
|
from wcs.workflows import Workflow, WorkflowBackofficeFieldsFormDef, WorkflowCriticalityLevel
|
|
from wcs.wscalls import NamedWsCall
|
|
|
|
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
|
|
|
|
|
|
@pytest.fixture
|
|
def pub(request, emails):
|
|
pub = create_temporary_pub(sql_mode=True)
|
|
|
|
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()
|
|
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
|
fd.write(
|
|
'''
|
|
[api-secrets]
|
|
coucou = 1234
|
|
'''
|
|
)
|
|
|
|
return pub
|
|
|
|
|
|
def create_user(pub, is_admin=False):
|
|
user1 = None
|
|
for user in pub.user_class.select():
|
|
if user.name == 'admin':
|
|
user1 = user
|
|
user1.is_admin = is_admin
|
|
user1.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
user1.store()
|
|
elif user.email == 'jean.darmette@triffouilis.fr':
|
|
pass # don't remove user created by local_user fixture
|
|
else:
|
|
user.remove_self()
|
|
if user1:
|
|
return user1
|
|
user1 = pub.user_class(name='admin')
|
|
user1.email = 'admin@localhost'
|
|
user1.is_admin = is_admin
|
|
user1.store()
|
|
|
|
account1 = PasswordAccount(id='admin')
|
|
account1.set_password('admin')
|
|
account1.user_id = user1.id
|
|
account1.store()
|
|
|
|
pub.role_class.wipe()
|
|
role = pub.role_class(name='foobar')
|
|
role.store()
|
|
|
|
user1.roles = [role.id]
|
|
user1.store()
|
|
|
|
return user1
|
|
|
|
|
|
def create_superuser(pub):
|
|
return create_user(pub, is_admin=True)
|
|
|
|
|
|
def create_environment(pub, set_receiver=True):
|
|
pub.session_manager.session_class.wipe()
|
|
Workflow.wipe()
|
|
Category.wipe()
|
|
FormDef.wipe()
|
|
BlockDef.wipe()
|
|
CardDef.wipe()
|
|
pub.custom_view_class.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
if set_receiver:
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
|
|
datasource = {'type': 'formula', 'value': repr([('A', 'aa'), ('B', 'bb'), ('C', 'cc')])}
|
|
|
|
formdef.fields = []
|
|
formdef.store() # make sure sql columns are removed
|
|
|
|
formdef.fields = [
|
|
fields.StringField(
|
|
id='1', label='1st field', type='string', display_locations=['validation', 'summary', 'listings']
|
|
),
|
|
fields.ItemField(
|
|
id='2',
|
|
label='2nd field',
|
|
type='item',
|
|
items=['foo', 'bar', 'baz'],
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.ItemField(id='3', label='3rd field', type='item', data_source=datasource, varname='foo'),
|
|
]
|
|
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
for i in range(50):
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = datetime.datetime(2015, 1, 1, 0, i).timetuple()
|
|
formdata.data = {'1': 'FOO BAR %d' % i}
|
|
if i % 4 == 0:
|
|
formdata.data['2'] = 'foo'
|
|
formdata.data['2_display'] = 'foo'
|
|
formdata.data['3'] = 'A'
|
|
formdata.data['3_display'] = 'aa'
|
|
elif i % 4 == 1:
|
|
formdata.data['2'] = 'bar'
|
|
formdata.data['2_display'] = 'bar'
|
|
formdata.data['3'] = 'B'
|
|
formdata.data['3_display'] = 'bb'
|
|
else:
|
|
formdata.data['2'] = 'baz'
|
|
formdata.data['2_display'] = 'baz'
|
|
formdata.data['3'] = 'C'
|
|
formdata.data['3_display'] = 'cc'
|
|
if i % 3 == 0:
|
|
formdata.jump_status('new')
|
|
else:
|
|
formdata.jump_status('finished')
|
|
formdata.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'1': 'XXX', '2': 'foo', '2_display': 'foo'}
|
|
formdata.status = 'draft'
|
|
formdata.store()
|
|
|
|
formdef = FormDef()
|
|
if set_receiver:
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.name = 'other form'
|
|
formdef.fields = []
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
for i in range(20):
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.receipt_time = datetime.datetime(2014, 1, 1).timetuple()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
|
|
def teardown_module(module):
|
|
clean_temporary_pub()
|
|
|
|
|
|
def test_backoffice_unlogged(pub):
|
|
create_superuser(pub)
|
|
resp = get_app(pub).get('/backoffice/', status=302)
|
|
assert resp.location == 'http://example.net/login/?next=http%3A%2F%2Fexample.net%2Fbackoffice%2F'
|
|
|
|
|
|
def test_backoffice_home(pub):
|
|
create_superuser(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/')
|
|
assert resp.location.endswith('/studio/')
|
|
resp.follow()
|
|
|
|
|
|
def test_backoffice_role_user(pub):
|
|
create_user(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/')
|
|
assert resp.location.endswith('/management/')
|
|
|
|
pub.cfg['admin-permissions'] = {'forms': [x.id for x in pub.role_class.select()]}
|
|
pub.write_cfg()
|
|
resp = app.get('/backoffice/')
|
|
assert resp.location.endswith('/studio/')
|
|
resp = resp.follow()
|
|
assert 'Forms' in resp.text
|
|
assert 'Workflows' not in resp.text
|
|
|
|
pub.cfg['admin-permissions'] = {'workflows': [x.id for x in pub.role_class.select()]}
|
|
pub.write_cfg()
|
|
resp = app.get('/backoffice/')
|
|
assert resp.location.endswith('/studio/')
|
|
resp = resp.follow()
|
|
assert 'Forms' not in resp.text
|
|
assert 'Workflows' in resp.text
|
|
|
|
# check role id int->str migration
|
|
pub.cfg['admin-permissions'] = {'workflows': [int(x.id) for x in pub.role_class.select()]}
|
|
pub.write_cfg()
|
|
resp = app.get('/backoffice/')
|
|
assert resp.location.endswith('/studio/')
|
|
resp = resp.follow()
|
|
assert 'Forms' not in resp.text
|
|
assert 'Workflows' in resp.text
|
|
|
|
|
|
def test_backoffice_forms(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub, set_receiver=False)
|
|
|
|
# 1st time with user not handling those forms
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert 'Forms in your care' not in resp.text
|
|
assert re.findall('Other Forms.*form-title', resp.text)
|
|
|
|
# 2nd time with user set as receiver of the forms
|
|
create_environment(pub, set_receiver=True)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert 'Forms in your care' in resp.text
|
|
assert '17 open on 50' in resp.text
|
|
|
|
# disable form, make sure it's still displayed
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.disabled = True
|
|
formdef.store()
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert 'form-title' in resp.text
|
|
assert '17 open on 50' in resp.text
|
|
|
|
formdef.disabled = False
|
|
formdef.store()
|
|
|
|
# add an extra status to workflow and move a few formdatas to it, they
|
|
# should then be marked as open but not waiting for actions.
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
st1 = workflow.add_status('Status1')
|
|
jump = st1.add_action('jump', id='_jump')
|
|
jump.timeout = 86400
|
|
jump.status = 'finished'
|
|
workflow.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
|
|
for i, formdata in enumerate(formdef.data_class().select(order_by='id')):
|
|
if formdata.status == 'wf-new' and i % 2:
|
|
formdata.status = 'wf-%s' % st1.id
|
|
formdata.store()
|
|
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert 'Forms in your care' in resp.text
|
|
assert '9 open on 50' in resp.text
|
|
|
|
# anonymise some formdata, they should no longer be included
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
for i, formdata in enumerate(
|
|
formdef.data_class().select([st.Equal('status', 'wf-finished')], order_by='id')
|
|
):
|
|
if i >= 20:
|
|
break
|
|
formdata.anonymise()
|
|
|
|
for i, formdata in enumerate(formdef.data_class().select([st.Equal('status', 'wf-new')], order_by='id')):
|
|
if i >= 5:
|
|
break
|
|
formdata.anonymise()
|
|
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert 'Forms in your care' in resp.text
|
|
assert '4 open on 25' in resp.text
|
|
|
|
|
|
def test_backoffice_management_css_class(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.pyquery.find('body.section-management')
|
|
|
|
|
|
def test_backoffice_form_access_forbidden(pub):
|
|
create_environment(pub, set_receiver=False)
|
|
user = create_user(pub)
|
|
formdata = FormDef.get_by_urlname('form-title').data_class().select()[0]
|
|
resp = login(get_app(pub)).get(formdata.get_backoffice_url(), status=403)
|
|
assert 'Access Forbidden' in resp.text
|
|
assert 'data-gadjo="true"' in resp.text # backoffice style
|
|
|
|
role = pub.role_class.get(user.roles[0])
|
|
role.allows_backoffice_access = False
|
|
role.store()
|
|
resp = login(get_app(pub)).get(formdata.get_backoffice_url(), status=403)
|
|
assert 'data-gadjo="true"' not in resp.text # no style
|
|
role.allows_backoffice_access = True
|
|
role.store()
|
|
|
|
|
|
def test_admin_form_page(pub):
|
|
create_superuser(pub)
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'backoffice/forms/1/' in resp
|
|
assert 'backoffice/workflows/_default/' in resp
|
|
|
|
|
|
def test_backoffice_listing(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.text.count('data-link') == 17
|
|
|
|
# check status filter <select>
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp.forms['listing-settings']['filter'] = 'all'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text.count('data-link') == 20
|
|
|
|
# check status filter <select>
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp.forms['listing-settings']['filter'] = 'done'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text.count('data-link') == 20
|
|
resp = resp.click('Next Page')
|
|
assert resp.text.count('data-link') == 13
|
|
|
|
# add an extra status to workflow and move a few formdatas to it, they
|
|
# should then be marked as open but not waiting for actions.
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
st1 = workflow.add_status('Status1')
|
|
st1.id = 'plop'
|
|
jump = st1.add_action('jump', id='_jump')
|
|
jump.timeout = 86400
|
|
jump.status = 'finished'
|
|
workflow.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
|
|
for i, formdata in enumerate(formdef.data_class().select(order_by='id')):
|
|
if formdata.status == 'wf-new' and i % 2:
|
|
formdata.status = 'wf-%s' % st1.id
|
|
formdata.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.text.count('data-link') == 9
|
|
resp.forms['listing-settings']['filter'] = 'pending'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text.count('data-link') == 17
|
|
|
|
# check status forced as endpoints are not part of the "actionable" list.
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '3'
|
|
st1 = workflow.add_status('Status1')
|
|
st1.id = 'plop'
|
|
st1.forced_endpoint = False
|
|
again = st1.add_action('choice', id='_again')
|
|
again.label = 'Again'
|
|
again.by = ['_receiver']
|
|
again.status = st1.id
|
|
workflow.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
formdef.data_class().rebuild_security()
|
|
|
|
for i, formdata in enumerate(formdef.data_class().select(order_by='id')):
|
|
if formdata.status == 'wf-new' and i % 2:
|
|
formdata.status = 'wf-%s' % st1.id
|
|
formdata.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.text.count('data-link') == 17
|
|
resp.forms['listing-settings']['filter'] = 'pending'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text.count('data-link') == 17
|
|
|
|
# mark status as an endpoint
|
|
st1.forced_endpoint = True
|
|
workflow.store()
|
|
formdef.data_class().rebuild_security()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.text.count('data-link') == 9
|
|
resp.forms['listing-settings']['filter'] = 'pending'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text.count('data-link') == 9
|
|
|
|
|
|
def test_backoffice_listing_pagination(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.text.count('data-link') == 17
|
|
|
|
resp = app.get('/backoffice/management/form-title/?limit=5')
|
|
assert resp.text.count('data-link') == 5
|
|
assert '<div id="page-links">' in resp.text
|
|
|
|
resp = resp.click(re.compile('^2$')) # second page
|
|
assert resp.text.count('data-link') == 5
|
|
assert resp.forms['listing-settings']['offset'].value == '5'
|
|
|
|
resp = resp.click(re.compile('^3$')) # third page
|
|
assert resp.text.count('data-link') == 5
|
|
assert resp.forms['listing-settings']['offset'].value == '10'
|
|
|
|
resp = resp.click(re.compile('^4$')) # fourth page
|
|
assert resp.text.count('data-link') == 2
|
|
assert resp.forms['listing-settings']['offset'].value == '15'
|
|
|
|
with pytest.raises(IndexError): # no fifth page
|
|
resp = resp.click(re.compile('^5$'))
|
|
|
|
resp = resp.click(re.compile('^10$')) # per page: 10
|
|
assert resp.text.count('data-link') == 10
|
|
|
|
resp = resp.click(re.compile('^20$')) # per page: 20
|
|
assert resp.text.count('data-link') == 17
|
|
|
|
# try an overbound offset
|
|
resp = app.get('/backoffice/management/form-title/?limit=5&offset=30')
|
|
resp = resp.follow()
|
|
assert resp.forms['listing-settings']['offset'].value == '0'
|
|
|
|
# try invalid values
|
|
resp = app.get('/backoffice/management/form-title/?limit=toto&offset=30', status=400)
|
|
resp = app.get('/backoffice/management/form-title/?limit=5&offset=toto', status=400)
|
|
|
|
|
|
def test_backoffice_listing_anonymised(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/?limit=500')
|
|
assert resp.text.count('data-link') == 17
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
for i, formdata in enumerate(formdef.data_class().select(order_by='id')):
|
|
if i % 2:
|
|
formdata.anonymise()
|
|
|
|
resp = app.get('/backoffice/management/form-title/?limit=500')
|
|
assert resp.text.count('data-link') == 9
|
|
|
|
|
|
def test_backoffice_listing_fts(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.text.count('data-link') == 17
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp.forms['listing-settings']['filter'] = 'all'
|
|
resp.forms['listing-settings']['q'] = 'foo'
|
|
resp.forms['listing-settings']['limit'] = '100'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.pyquery('tbody tr').length == 50
|
|
assert [x.text for x in resp.pyquery('tbody tr .cell-id a')] == [
|
|
'%s-%s' % (formdef.id, i) for i in range(50, 0, -1)
|
|
]
|
|
|
|
resp.forms['listing-settings']['q'] = 'baz'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.pyquery('tbody tr').length == 24
|
|
|
|
|
|
def test_backoffice_legacy_urls(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/form-title/')
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/'
|
|
resp = app.get('/backoffice/form-title/1/')
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/1/'
|
|
resp = app.get('/backoffice/form-title/listing/?bla')
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/listing/?bla'
|
|
resp = app.get('/backoffice/form-title/listing/foo?bla')
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/listing/foo?bla'
|
|
resp = app.get('/backoffice/not-form-title/', status=404)
|
|
|
|
|
|
def test_backoffice_form_category_permissions(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'Export a Spreadsheet' in resp.text
|
|
assert 'Statistics' in resp.text
|
|
|
|
cat1 = Category(name='cat1')
|
|
cat1.store()
|
|
formdef.category_id = cat1.id
|
|
formdef.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'Export a Spreadsheet' in resp.text
|
|
assert 'Statistics' in resp.text
|
|
|
|
role = pub.role_class(name='limited perms')
|
|
role.store()
|
|
cat1.export_roles = [role]
|
|
cat1.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'Export a Spreadsheet' not in resp.text
|
|
assert 'Statistics' in resp.text
|
|
|
|
cat1.statistics_roles = [role]
|
|
cat1.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'Export a Spreadsheet' not in resp.text
|
|
assert 'Statistics' not in resp.text
|
|
app.get('/backoffice/management/form-title/stats', status=403)
|
|
app.get('/backoffice/management/form-title/export-spreadsheet', status=403)
|
|
app.get('/backoffice/management/form-title/csv', status=403)
|
|
app.get('/backoffice/management/form-title/ods', status=403)
|
|
|
|
# check it's ok for admins
|
|
user.is_admin = True
|
|
user.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'Export a Spreadsheet' in resp.text
|
|
assert 'Statistics' in resp.text
|
|
app.get('/backoffice/management/form-title/stats', status=200)
|
|
app.get('/backoffice/management/form-title/export-spreadsheet', status=200)
|
|
app.get('/backoffice/management/form-title/csv', status=200)
|
|
app.get('/backoffice/management/form-title/ods', status=200)
|
|
|
|
# check it's ok for agents with roles
|
|
user.is_admin = False
|
|
user.roles.append(role.id)
|
|
user.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'Export a Spreadsheet' in resp.text
|
|
assert 'Statistics' in resp.text
|
|
app.get('/backoffice/management/form-title/stats', status=200)
|
|
app.get('/backoffice/management/form-title/export-spreadsheet', status=200)
|
|
app.get('/backoffice/management/form-title/csv', status=200)
|
|
app.get('/backoffice/management/form-title/ods', status=200)
|
|
|
|
|
|
def test_backoffice_multi_actions(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text # always there
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('FOOBAR')
|
|
jump = action.add_action('jump')
|
|
jump.status = 'finished'
|
|
trigger = action.triggers[0]
|
|
trigger.roles = ['whatever']
|
|
|
|
workflow.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text
|
|
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
workflow.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/?limit=20')
|
|
assert 'id="multi-actions"' in resp.text
|
|
ids = []
|
|
for checkbox in resp.forms[0].fields['select[]'][1:6]:
|
|
ids.append(checkbox._value)
|
|
checkbox.checked = True
|
|
resp = resp.forms[0].submit('button-action-1')
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "FOOBAR" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
assert (
|
|
resp.pyquery.find('[data-redirect-auto]').attr['href']
|
|
== '/backoffice/management/form-title/?limit=20'
|
|
)
|
|
for id in ids:
|
|
assert formdef.data_class().get(id).status == 'wf-finished'
|
|
|
|
draft_ids = [x.id for x in formdef.data_class().select() if x.status == 'draft']
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.forms[0].fields['select[]'][0]._value == '_all'
|
|
resp.forms[0].fields['select[]'][0].checked = True
|
|
resp = resp.forms[0].submit('button-action-1')
|
|
for formdata in formdef.data_class().select():
|
|
if formdata.id in draft_ids:
|
|
assert formdata.status == 'draft'
|
|
else:
|
|
assert formdata.status == 'wf-finished'
|
|
|
|
for formdata in formdef.data_class().select():
|
|
if formdata.status != 'draft':
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
# action for other role
|
|
action2 = workflow.add_global_action('OTHER ACTION')
|
|
jump = action2.add_action('jump')
|
|
jump.status = 'accepted'
|
|
trigger = action2.triggers[0]
|
|
trigger.roles = ['whatever']
|
|
workflow.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text
|
|
assert 'OTHER ACTION' not in resp.text
|
|
|
|
# action for function
|
|
trigger.roles = ['_foobar']
|
|
workflow.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text
|
|
assert 'OTHER ACTION' not in resp.text
|
|
|
|
workflow.roles['_foobar'] = 'Foobar'
|
|
workflow.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text
|
|
assert 'OTHER ACTION' in resp.text
|
|
|
|
# alter some formdata to simulate dispatch action
|
|
stable_ids = []
|
|
for checkbox in resp.forms[0].fields['select[]'][1:6]:
|
|
formdata = formdef.data_class().get(checkbox._value)
|
|
formdata.workflow_roles = {'_foobar': [formdef.workflow_roles['_receiver']]}
|
|
formdata.store()
|
|
stable_ids.append(formdata.id)
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert resp.pyquery('[data-link="%s/"] input' % stable_ids[0]).attr['data-is__foobar'] == 'true'
|
|
assert 'OTHER ACTION' in resp.text
|
|
|
|
resp.forms[0].fields['select[]'][0].checked = True # _all
|
|
resp = resp.forms[0].submit('button-action-2')
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "OTHER ACTION" on forms' in resp.text
|
|
# check only dispatched formdata have been moved by global action executed
|
|
# on all formdatas
|
|
for formdata in formdef.data_class().select():
|
|
if formdata.id in draft_ids:
|
|
assert formdata.status == 'draft'
|
|
elif formdata.id in stable_ids:
|
|
assert formdata.status == 'wf-accepted'
|
|
else:
|
|
assert formdata.status != 'wf-accepted'
|
|
|
|
|
|
def test_backoffice_multi_actions_jump(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
workflow.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'select[]' not in resp.forms['multi-actions'].fields
|
|
|
|
resp.forms['listing-settings']['filter'] = 'new'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert 'select[]' not in resp.forms['multi-actions'].fields
|
|
|
|
# add identifier to jumps
|
|
workflow.get_status('new').items[1].identifier = 'accept'
|
|
workflow.get_status('new').items[2].identifier = 'reject'
|
|
workflow.get_status('new').items[2].require_confirmation = True
|
|
workflow.store()
|
|
|
|
resp.forms['listing-settings']['filter-operator'] = 'ne'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert 'select[]' not in resp.forms['multi-actions'].fields
|
|
|
|
resp.forms['listing-settings']['filter-operator'] = 'eq'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert 'select[]' in resp.forms['multi-actions'].fields
|
|
assert len(resp.pyquery.find('#multi-actions div.buttons button')) == 2
|
|
assert len(resp.pyquery.find('#multi-actions div.buttons button[data-ask-for-confirmation]')) == 1
|
|
|
|
ids = []
|
|
for checkbox in resp.forms[0].fields['select[]'][1:6]:
|
|
ids.append(checkbox._value)
|
|
checkbox.checked = True
|
|
resp = resp.forms['multi-actions'].submit('button-action-st-accept')
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "Accept" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
for id in ids:
|
|
assert formdef.data_class().get(id).status == 'wf-accepted'
|
|
|
|
|
|
def test_backoffice_multi_actions_oldest_form(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text # always there
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('Mark as duplicates')
|
|
jump = action.add_action('jump')
|
|
jump.condition = {'type': 'django', 'value': "mass_action_index != 0"}
|
|
jump.status = 'rejected'
|
|
|
|
jump2 = action.add_action('jump')
|
|
jump2.condition = {'type': 'django', 'value': "mass_action_index == 0"}
|
|
jump2.status = 'accepted'
|
|
|
|
register_comment = workflow.possible_status[2].add_action('register-comment', id='_comment')
|
|
register_comment.comment = '<p>Original form: {{ oldest_form_number }}.</p>'
|
|
assert workflow.possible_status[2].id == 'rejected'
|
|
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
|
|
workflow.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text
|
|
ids = []
|
|
for checkbox in resp.forms[0].fields['select[]'][1:6]:
|
|
ids.append(checkbox._value)
|
|
checkbox.checked = True
|
|
resp = resp.forms[0].submit('button-action-1')
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "Mark as duplicates" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
oldest_formdata = None
|
|
for i, id in enumerate(sorted(ids, key=int)):
|
|
if i == 0:
|
|
oldest_formdata = formdef.data_class().get(id)
|
|
assert formdef.data_class().get(id).status == 'wf-accepted'
|
|
else:
|
|
assert formdef.data_class().get(id).status == 'wf-rejected'
|
|
assert (
|
|
formdef.data_class().get(id).evolution[-1].parts[0].content
|
|
== '<p>Original form: %s.</p>' % oldest_formdata.get_display_id()
|
|
)
|
|
|
|
|
|
def test_backoffice_multi_actions_using_session_user(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text # always there
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('Show user')
|
|
register_comment = action.add_action('register-comment')
|
|
register_comment.comment = 'session_user={{session_user}}'
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
|
|
workflow.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text
|
|
ids = []
|
|
for checkbox in resp.forms[0].fields['select[]'][1:6]:
|
|
ids.append(checkbox._value)
|
|
checkbox.checked = True
|
|
resp = resp.forms[0].submit('button-action-1')
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "Show user" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
for id in sorted(ids, key=int):
|
|
content = formdef.data_class().get(id).evolution[-1].parts[0].content
|
|
assert 'session_user=admin' in content
|
|
|
|
|
|
def test_backoffice_map(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
form_class = FormDef.get_by_urlname('form-title').data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert re.findall(r'<tbody.*\/tbody>', resp.text, re.DOTALL)[0].count('<tr') == 17
|
|
|
|
# check there's no link to map the sidebar
|
|
assert 'Plot on a Map' not in resp.text
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.geolocations = {'base': 'Geolocafoobar'}
|
|
formdef.store()
|
|
number31.geolocations = {'base': {'lat': 48.83, 'lon': 2.32}}
|
|
number31.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'Plot on a Map' in resp.text
|
|
resp = resp.click('Plot on a Map')
|
|
assert 'data-geojson-url' in resp.text
|
|
assert 'tiles.entrouvert.org/' in resp.text
|
|
|
|
if not pub.site_options.has_section('options'):
|
|
pub.site_options.add_section('options')
|
|
|
|
pub.site_options.set('options', 'map-tile-urltemplate', 'https://{s}.tile.example.net/{z}/{x}/{y}.png')
|
|
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
|
pub.site_options.write(fd)
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Plot on a Map')
|
|
assert 'tile.example.net/' in resp.text
|
|
|
|
|
|
def test_backoffice_geojson(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.fields.append(fields.MapField(id='4', label='4th field', type='map'))
|
|
formdef.fields.append(fields.MapField(id='5', label='5th field', type='string'))
|
|
formdef.store()
|
|
form_class = formdef.data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/geojson', status=404)
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.geolocations = {'base': 'Geolocafoobar'}
|
|
formdef.store()
|
|
number31 = formdef.data_class().get(number31.id)
|
|
number31.geolocations = {'base': {'lat': 48.83, 'lon': 2.32}}
|
|
number31.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/geojson?1=on&4=on&5=on')
|
|
assert len(resp.json['features']) == 1
|
|
assert resp.json['features'][0]['geometry']['coordinates'] == [2.32, 48.83]
|
|
assert 'status_colour' in resp.json['features'][0]['properties']
|
|
assert resp.json['features'][0]['properties']['status_name'] == 'New'
|
|
assert resp.json['features'][0]['properties']['status_colour'] == '#66FF00'
|
|
assert resp.json['features'][0]['properties']['view_label'] == 'View'
|
|
assert 'display_fields' in resp.json['features'][0]['properties']
|
|
assert len(resp.json['features'][0]['properties']['display_fields']) == 1
|
|
|
|
resp = app.get('/backoffice/management/form-title/geojson?filter=pending&filter-status=on')
|
|
assert len(resp.json['features']) == 1
|
|
|
|
resp = app.get('/backoffice/management/form-title/geojson?filter=done&filter-status=on')
|
|
assert len(resp.json['features']) == 0
|
|
|
|
|
|
def test_backoffice_handling(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
form_class = FormDef.get_by_urlname('form-title').data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert re.findall(r'<tbody.*\/tbody>', resp.text, re.DOTALL)[0].count('<tr') == 17
|
|
|
|
# check sidebar links are ok
|
|
assert 'Statistics' in resp.text
|
|
assert 'Export' in resp.text
|
|
app.get('/backoffice/management/form-title/stats', status=200)
|
|
app.get('/backoffice/management/form-title/csv', status=200)
|
|
app.get('/backoffice/management/form-title/ods', status=200)
|
|
app.get('/backoffice/management/form-title/json', status=200)
|
|
|
|
# click on a formdata
|
|
resp = resp.click(href='%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
resp.forms[0]['comment'] = 'HELLO WORLD'
|
|
resp = resp.forms[0].submit('button_accept')
|
|
resp = resp.follow()
|
|
assert FormDef.get_by_urlname('form-title').data_class().get(number31.id).status == 'wf-accepted'
|
|
assert 'HELLO WORLD' in resp.text
|
|
|
|
|
|
def test_backoffice_handling_global_action(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test global action'
|
|
formdef.fields = []
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('FOOBAR')
|
|
register_comment = action.add_action('register-comment')
|
|
register_comment.comment = 'HELLO WORLD GLOBAL ACTION'
|
|
jump = action.add_action('jump')
|
|
jump.status = 'finished'
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
|
|
workflow.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/%s/%s/' % (formdef.url_name, formdata.id))
|
|
assert 'button-action-1' in resp.form.fields
|
|
resp = resp.form.submit('button-action-1')
|
|
|
|
resp = app.get('/backoffice/management/%s/%s/' % (formdef.url_name, formdata.id))
|
|
assert 'HELLO WORLD GLOBAL ACTION' in resp.text
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-finished'
|
|
|
|
|
|
def test_backoffice_global_remove_action(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test global remove'
|
|
formdef.fields = []
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('FOOBAR')
|
|
action.add_action('remove')
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
|
|
workflow.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/%s/%s/' % (formdef.url_name, formdata.id))
|
|
assert 'remove' in resp.text
|
|
assert 'button-action-1' in resp.form.fields
|
|
resp = resp.form.submit('button-action-1')
|
|
resp = resp.follow()
|
|
assert resp.request.url == 'http://example.net/backoffice/management/test-global-remove/'
|
|
assert 'The form has been deleted.' in resp.text
|
|
|
|
|
|
def test_backoffice_global_action_jump_to_current_status(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test jump to current status'
|
|
formdef.fields = []
|
|
|
|
workflow = Workflow()
|
|
st1 = workflow.add_status('Status1')
|
|
register_comment = st1.add_action('register-comment', id='_comment')
|
|
register_comment.comment = '<p>WORKFLOW COMMENT</p>'
|
|
|
|
action = workflow.add_global_action('FOOBAR')
|
|
action.add_action('jump')
|
|
action.items[0].status = st1.id
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.perform_workflow()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/%s/%s/' % (formdef.url_name, formdata.id))
|
|
assert resp.text.count('WORKFLOW COMMENT') == 1
|
|
assert 'button-action-1' in resp.form.fields
|
|
resp = resp.form.submit('button-action-1')
|
|
resp = resp.follow()
|
|
assert resp.text.count('WORKFLOW COMMENT') == 2
|
|
|
|
|
|
def test_backoffice_submission_context(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
form_class = FormDef.get_by_urlname('form-title').data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert re.findall(r'<tbody.*\/tbody>', resp.text, re.DOTALL)[0].count('<tr') == 17
|
|
|
|
# click on a formdata
|
|
resp = resp.click(href='%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
|
|
# check there's nothing in the sidebar
|
|
assert 'Channel' not in resp.text
|
|
|
|
number31.submission_channel = 'mail'
|
|
number31.user_id = user.id
|
|
number31.submission_context = {
|
|
'mail_url': 'http://www.example.com/test.pdf',
|
|
'thumbnail_url': 'http://www.example.com/thumbnail.png',
|
|
'comments': 'test_backoffice_submission_context',
|
|
'summary_url': 'http://www.example.com/summary',
|
|
}
|
|
number31.submission_agent_id = str(user.id)
|
|
number31.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click(href='%s/' % number31.id)
|
|
assert 'Channel' in resp.text
|
|
assert 'http://www.example.com/thumbnail.png' in resp.text
|
|
assert 'http://www.example.com/test.pdf' in resp.text
|
|
assert 'Associated User' in resp.text
|
|
assert 'test_backoffice_submission_context' in resp.text
|
|
assert 'http://www.example.com/summary' in resp.text
|
|
assert 'by %s' % user.get_display_name() in resp.text
|
|
|
|
|
|
def test_backoffice_download_as_zip(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.fields.append(fields.FileField(id='4', label='file1 field', type='file'))
|
|
formdef.fields.append(fields.FileField(id='5', label='file2 field', type='file2'))
|
|
formdef.store()
|
|
number31 = [x for x in formdef.data_class().select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
number31.data['4'] = PicklableUpload('/foo/bar', content_type='text/plain')
|
|
number31.data['4'].receive([b'hello world'])
|
|
number31.data['5'] = PicklableUpload('/foo/bar', content_type='text/plain')
|
|
number31.data['5'].receive([b'hello world2'])
|
|
number31.store()
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert 'Download all files as .zip' not in resp
|
|
formdef.include_download_all_button = True
|
|
formdef.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.click('Download all files as .zip')
|
|
zip_content = io.BytesIO(resp.body)
|
|
with zipfile.ZipFile(zip_content, 'a') as zipf:
|
|
filelist = zipf.namelist()
|
|
assert set(filelist) == {'1_bar', '2_bar'}
|
|
for zipinfo in zipf.infolist():
|
|
content = zipf.read(zipinfo)
|
|
if zipinfo.filename == '1_bar':
|
|
assert content == b'hello world'
|
|
elif zipinfo.filename == '2_bar':
|
|
assert content == b'hello world2'
|
|
else:
|
|
assert False # unknown zip part
|
|
|
|
|
|
def test_backoffice_sidebar_user_template(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
form_class = FormDef.get_by_urlname('form-title').data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
number31.user_id = user.id
|
|
number31.store()
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click(href='%s/' % number31.id)
|
|
assert 'Associated User' in resp.text
|
|
assert '<p>admin</p>' in resp.text
|
|
pub.cfg['users'] = {'sidebar_template': 'XXX{{ form_user_display_name }}YYY'}
|
|
pub.write_cfg()
|
|
resp = app.get(resp.request.url)
|
|
assert '<p>XXXadminYYY</p>' in resp.text
|
|
pub.cfg['users'] = {'sidebar_template': 'XXX<b>{{ form_user_display_name }}</b>YYY'}
|
|
pub.write_cfg()
|
|
resp = app.get(resp.request.url)
|
|
assert '<p>XXX<b>admin</b>YYY</p>' in resp.text
|
|
user.name = 'adm<i>n'
|
|
user.store()
|
|
resp = app.get(resp.request.url)
|
|
assert '<p>XXX<b>adm<i>n</b>YYY</p>' in resp.text
|
|
|
|
|
|
def test_backoffice_geolocation_info(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.geolocations = {'base': 'Geolocafoobar'}
|
|
formdef.store()
|
|
form_class = FormDef.get_by_urlname('form-title').data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert re.findall(r'<tbody.*\/tbody>', resp.text, re.DOTALL)[0].count('<tr') == 17
|
|
|
|
# click on a formdata
|
|
resp = resp.click(href='%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
|
|
# check there's nothing in the sidebar
|
|
assert 'Geolocation' not in resp.text
|
|
|
|
number31.geolocations = {'base': {'lat': 48.83, 'lon': 2.32}}
|
|
number31.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click(href='%s/' % number31.id)
|
|
assert 'Geolocafoobar' in resp.text
|
|
assert 'class="qommon-map"' in resp.text
|
|
assert 'data-init-lng="2.32"' in resp.text
|
|
assert 'data-init-lat="48.83' in resp.text
|
|
|
|
|
|
def test_backoffice_info_text(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='info texts')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
commentable = st1.add_action('commentable', id='_commentable')
|
|
commentable.by = ['_submitter', '_receiver']
|
|
commentable.button_label = 'CLICK ME!'
|
|
|
|
commentable2 = st1.add_action('commentable', id='_commentable2')
|
|
commentable2.by = ['_submitter']
|
|
commentable2.button_label = 'CLICK ME2!'
|
|
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert 'CLICK ME!' in resp.text
|
|
assert 'CLICK ME2!' not in resp.text
|
|
assert 'backoffice-description' not in resp.text
|
|
|
|
# add an info text to the status
|
|
st1.backoffice_info_text = '<p>Foo</p>'
|
|
workflow.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert 'backoffice-description' in resp.text
|
|
assert '<p>Foo</p>' in resp.text
|
|
|
|
# add an info text to the button
|
|
commentable.backoffice_info_text = '<p>Bar</p>'
|
|
workflow.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert 'backoffice-description' in resp.text
|
|
assert '<p>Foo</p>' in resp.text
|
|
assert '<p>Bar</p>' in resp.text
|
|
|
|
# info text is not visible if form is locked
|
|
second_user = pub.user_class(name='foobar')
|
|
second_user.roles = pub.role_class.keys()
|
|
second_user.store()
|
|
account = PasswordAccount(id='foobar')
|
|
account.set_password('foobar')
|
|
account.user_id = second_user.id
|
|
account.store()
|
|
app2 = login(get_app(pub), username='foobar', password='foobar')
|
|
resp = app2.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert 'Be warned forms of this user are also being looked' in resp.text
|
|
assert 'backoffice-description' not in resp.text
|
|
assert 'CLICK ME!' not in resp.text
|
|
assert 'CLICK ME2!' not in resp.text
|
|
|
|
# remove info text from the status
|
|
st1.backoffice_info_text = None
|
|
workflow.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert 'backoffice-description' in resp.text
|
|
assert '<p>Foo</p>' not in resp.text
|
|
assert '<p>Bar</p>' in resp.text
|
|
|
|
# add info text to second button
|
|
commentable2.backoffice_info_text = '<p>Baz</p>'
|
|
workflow.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert 'backoffice-description' in resp.text
|
|
assert '<p>Foo</p>' not in resp.text
|
|
assert '<p>Bar</p>' in resp.text
|
|
assert '<p>Baz</p>' not in resp.text
|
|
|
|
# remove info text from first button
|
|
commentable.backoffice_info_text = None
|
|
workflow.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert 'backoffice-description' not in resp.text
|
|
|
|
|
|
def test_backoffice_handling_post_dispatch(pub):
|
|
# check a formdata that has been dispatched to another role is accessible
|
|
# by an user with that role.
|
|
user1 = create_user(pub)
|
|
role = pub.role_class(name='foobaz')
|
|
role.store()
|
|
user1.roles = [role.id]
|
|
user1.store()
|
|
create_environment(pub)
|
|
form_class = FormDef.get_by_urlname('form-title').data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
app = login(get_app(pub))
|
|
|
|
# check there's no access at the moment
|
|
resp = app.get('/backoffice/management/').follow()
|
|
assert 'form-title/' not in resp.text
|
|
resp = app.get('/backoffice/management/form-title/', status=403)
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id, status=403)
|
|
|
|
# emulate a dispatch (setting formdata.workflow_roles), receiver of that
|
|
# formdata is now the local role we gave to the user.
|
|
formdata31 = form_class.get(number31.id)
|
|
formdata31.workflow_roles = {'_receiver': [role.id]}
|
|
formdata31.store()
|
|
|
|
# check listing is accessible, with a single item
|
|
resp = app.get('/backoffice/management/').follow()
|
|
assert 'form-title/' in resp.text
|
|
resp = app.get('/backoffice/management/form-title/', status=200)
|
|
assert re.findall(r'<tbody.*\/tbody>', resp.text, re.DOTALL)[0].count('<tr') == 1
|
|
|
|
# check statistics and exports are also available
|
|
assert 'Statistics' in resp.text
|
|
assert 'Export' in resp.text
|
|
app.get('/backoffice/management/form-title/stats', status=200)
|
|
app.get('/backoffice/management/form-title/csv', status=200)
|
|
app.get('/backoffice/management/form-title/ods', status=200)
|
|
app.get('/backoffice/management/form-title/json', status=200)
|
|
|
|
# check formdata is accessible, and that it's possible to perform an action
|
|
# on it.
|
|
resp = resp.click(href='%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
resp.forms[0]['comment'] = 'HELLO WORLD'
|
|
resp = resp.forms[0].submit('button_accept')
|
|
resp = resp.follow()
|
|
assert FormDef.get_by_urlname('form-title').data_class().get(number31.id).status == 'wf-accepted'
|
|
assert 'HELLO WORLD' in resp.text
|
|
|
|
|
|
def test_backoffice_wscall_failure_display(http_requests, pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wscall')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wscall = st1.add_action('webservice_call', id='_wscall')
|
|
wscall.varname = 'xxx'
|
|
wscall.url = 'http://remote.example.net/xml'
|
|
wscall.action_on_bad_data = ':stop'
|
|
wscall.record_errors = True
|
|
|
|
again = st1.add_action('choice', id='_again')
|
|
again.label = 'Again'
|
|
again.by = ['_receiver']
|
|
again.status = st1.id
|
|
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert 'Again' in resp.text
|
|
resp = resp.forms[0].submit('button_again')
|
|
resp = resp.follow()
|
|
assert 'Error during webservice call' in resp.text
|
|
|
|
number31.user_id = user.id # change ownership to stay in frontoffice
|
|
number31.store()
|
|
# the failure message shouldn't be displayed in the frontoffice
|
|
resp = app.get('/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert 'Error during webservice call' not in resp.text
|
|
|
|
|
|
@pytest.mark.parametrize('notify_on_errors', [True, False])
|
|
@pytest.mark.parametrize('record_on_errors', [True, False])
|
|
def test_backoffice_wscall_on_error(http_requests, pub, emails, notify_on_errors, record_on_errors):
|
|
pub.cfg['debug'] = {'error_email': 'errors@localhost.invalid'}
|
|
pub.cfg['emails'] = {'from': 'from@localhost.invalid'}
|
|
pub.write_cfg()
|
|
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wscall')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wscall = st1.add_action('webservice_call', id='_wscall')
|
|
wscall.varname = 'xxx'
|
|
wscall.url = 'http://remote.example.net/xml'
|
|
wscall.action_on_bad_data = ':stop'
|
|
wscall.notify_on_errors = notify_on_errors
|
|
wscall.record_on_errors = record_on_errors
|
|
wscall.record_errors = True
|
|
|
|
again = st1.add_action('choice', id='_again')
|
|
again.label = 'Again'
|
|
again.by = ['_receiver']
|
|
again.status = st1.id
|
|
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert 'Again' in resp.text
|
|
resp = resp.forms[0].submit('button_again')
|
|
resp = resp.follow()
|
|
assert 'Error during webservice call' in resp.text
|
|
|
|
# check email box
|
|
if notify_on_errors:
|
|
assert emails.count() == 1
|
|
error_email = emails.get(
|
|
'[ERROR] [WSCALL] json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)'
|
|
)
|
|
assert '/form-title/%s/' % number31.id in error_email['payload']
|
|
assert error_email['from'] == 'from@localhost.invalid'
|
|
assert error_email['email_rcpt'] == ['errors@localhost.invalid']
|
|
if record_on_errors:
|
|
assert error_email['msg']['References']
|
|
else:
|
|
assert emails.count() == 0
|
|
|
|
# check pub.loggederror_class
|
|
if record_on_errors:
|
|
assert pub.loggederror_class.count() == 1
|
|
else:
|
|
assert pub.loggederror_class.count() == 0
|
|
|
|
|
|
def test_backoffice_wscall_attachment(http_requests, pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wscall')
|
|
workflow.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(workflow)
|
|
workflow.backoffice_fields_formdef.fields = [
|
|
fields.FileField(id='bo1', label='bo field 1', type='file'),
|
|
]
|
|
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wscall = st1.add_action('webservice_call', id='_wscall')
|
|
wscall.varname = 'xxx'
|
|
wscall.response_type = 'attachment'
|
|
wscall.backoffice_filefield_id = 'bo1'
|
|
wscall.url = 'http://remote.example.net/xml'
|
|
wscall.action_on_bad_data = ':stop'
|
|
wscall.record_errors = True
|
|
|
|
again = st1.add_action('choice', id='_again')
|
|
again.label = 'Again'
|
|
again.by = ['_receiver']
|
|
again.status = st1.id
|
|
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert 'Again' in resp.text
|
|
resp = resp.forms[0].submit('button_again')
|
|
resp = resp.follow()
|
|
|
|
# get the two generated files from backoffice: in backoffice fields
|
|
# (wscall.backoffice_filefield_id), and in history
|
|
for index in (0, 1):
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.click('xxx.xml', index=index)
|
|
assert resp.location.endswith('/xxx.xml')
|
|
resp = resp.follow()
|
|
assert resp.content_type == 'text/xml'
|
|
assert resp.text == '<?xml version="1.0"><foo/>'
|
|
|
|
formdata = formdef.data_class().get(number31.id)
|
|
assert formdata.evolution[-1].parts[0].orig_filename == 'xxx.xml'
|
|
assert formdata.evolution[-1].parts[0].content_type == 'text/xml'
|
|
assert formdata.get_substitution_variables()['attachments'].xxx.filename == 'xxx.xml'
|
|
resp = app.get(formdata.get_substitution_variables()['attachments'].xxx.url)
|
|
resp = resp.follow()
|
|
assert resp.text == '<?xml version="1.0"><foo/>'
|
|
|
|
|
|
def test_backoffice_wfedit(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
number31.submission_channel = 'mail'
|
|
number31.submission_context = {
|
|
'mail_url': 'http://www.example.com/test.pdf',
|
|
}
|
|
number31.store()
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert len(form_class().get(number31.id).evolution) == 2 # (just submitted, new)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert 'http://www.example.com/test.pdf' in resp.text # make sure sidebar has details
|
|
assert 'Tracking Code' not in resp.text # make sure it doesn't display a tracking code
|
|
assert resp.form['f1'].value == number31.data['1']
|
|
assert resp.form['f2'].value == number31.data['2']
|
|
assert resp.form['f3'].value == number31.data['3']
|
|
assert 'value="Save Changes"' in resp.text
|
|
resp.form['f2'].value = 'bar'
|
|
resp = resp.form.submit('submit')
|
|
resp = resp.follow()
|
|
assert form_class().get(number31.id).data['2'] == 'bar'
|
|
assert len(form_class().get(number31.id).evolution) == 3
|
|
assert form_class().get(number31.id).evolution[-1].who == str(user.id)
|
|
number31.store()
|
|
|
|
|
|
def test_backoffice_wfedit_disabled(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
number31.submission_context = {
|
|
'mail_url': 'http://www.example.com/test.pdf',
|
|
}
|
|
number31.store()
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
formdef.disabled = True
|
|
formdef.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
resp.form['f2'].value = 'bar'
|
|
resp = resp.form.submit('submit')
|
|
resp = resp.follow()
|
|
assert form_class().get(number31.id).data['2'] == 'bar'
|
|
|
|
|
|
def test_backoffice_wfedit_submission(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.backoffice_submission_roles = user.roles[:]
|
|
formdef.enable_tracking_codes = True
|
|
|
|
formdef.fields.insert(0, fields.PageField(id='0', label='1st page', type='page'))
|
|
formdef.fields.append(fields.PageField(id='4', label='2nd page', type='page'))
|
|
|
|
formdef.store()
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
number31.backoffice_submission = True
|
|
number31.store()
|
|
formdata_count = form_class.count()
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert resp.form['f1'].value == number31.data['1']
|
|
assert resp.form['f2'].value == number31.data['2']
|
|
assert resp.form['f3'].value == number31.data['3']
|
|
resp.form['f2'].value = 'bar'
|
|
resp = resp.form.submit('submit')
|
|
assert 'value="Save Changes"' in resp.text
|
|
resp = resp.form.submit('submit')
|
|
resp = resp.follow()
|
|
assert form_class().get(number31.id).data['2'] == 'bar'
|
|
number31.store()
|
|
assert formdata_count == form_class.count()
|
|
|
|
|
|
def test_backoffice_wfedit_and_required_comment(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
commentable = st1.add_action('commentable', id='_commentable')
|
|
commentable.by = [user.roles[0]]
|
|
commentable.button_label = 'CLICK ME!'
|
|
commentable.required = True
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
# check a click goes to edition, not blocked by required comment field.
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
resp.form['f2'].value = 'bar'
|
|
|
|
|
|
def test_backoffice_wfedit_and_backoffice_fields(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
workflow.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(workflow)
|
|
workflow.backoffice_fields_formdef.fields = [
|
|
fields.StringField(
|
|
id='bo1', label='1st backoffice field', type='string', varname='backoffice_blah', required=False
|
|
),
|
|
]
|
|
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
number31 = form_class().get(number31.id)
|
|
number31.data['bo1'] = 'plop'
|
|
number31.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
resp.form['f2'].value = 'bar'
|
|
resp = resp.form.submit('submit')
|
|
resp = resp.follow()
|
|
assert form_class().get(number31.id).data['bo1'] == 'plop'
|
|
|
|
|
|
def test_backoffice_wfedit_and_data_source_with_user_info(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
formdef.fields[2].data_source = {
|
|
'type': 'json',
|
|
'value': 'https://www.example.invalid/?name_id={% firstof form_user_display_name "XXX" %}',
|
|
}
|
|
formdef.store()
|
|
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
number31 = form_class().get(number31.id)
|
|
number31.user_id = user.id
|
|
number31.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
|
|
data = {'data': [{'id': 'A', 'text': 'hello'}, {'id': 'B', 'text': 'world'}]}
|
|
|
|
def side_effect(url, *args):
|
|
assert '?name_id=admin' in url
|
|
return io.StringIO(json.dumps(data))
|
|
|
|
urlopen.side_effect = side_effect
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert urlopen.call_count == 1
|
|
resp.form['f3'].value = 'A'
|
|
resp = resp.form.submit('submit')
|
|
assert urlopen.call_count == 2
|
|
resp = resp.follow()
|
|
|
|
|
|
def test_backoffice_wfedit_and_workflow_data(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
formdef.fields[2].data_source = {
|
|
'type': 'json',
|
|
'value': 'https://www.example.invalid/?test={% firstof some_workflow_data "XXX" %}',
|
|
}
|
|
formdef.store()
|
|
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
number31 = form_class().get(number31.id)
|
|
number31.workflow_data = {'some_workflow_data': 'foobar'}
|
|
number31.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
|
|
data = {'data': [{'id': 'A', 'text': 'hello'}, {'id': 'B', 'text': 'world'}]}
|
|
|
|
def side_effect(url, *args):
|
|
assert '?test=foobar' in url
|
|
return io.StringIO(json.dumps(data))
|
|
|
|
urlopen.side_effect = side_effect
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert urlopen.call_count == 1
|
|
resp.form['f3'].value = 'A'
|
|
resp = resp.form.submit('submit')
|
|
assert urlopen.call_count == 2
|
|
resp = resp.follow()
|
|
|
|
|
|
def test_backoffice_wfedit_and_data_source_with_field_info(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
|
|
formdef.fields[0].varname = 'bar'
|
|
formdef.fields[2].data_source = {
|
|
'type': 'json',
|
|
'value': 'https://www.example.invalid/?xxx={{ form_var_bar }}',
|
|
}
|
|
formdef.store()
|
|
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
number31 = form_class().get(number31.id)
|
|
number31.data['3'] = 'EE'
|
|
number31.data['3_display'] = 'EE'
|
|
number31.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
|
|
data = {'data': [{'id': 'DD', 'text': 'DD'}, {'id': 'EE', 'text': 'EE'}]}
|
|
|
|
def side_effect(url, *args):
|
|
assert '?xxx=FOO BAR 30' in url
|
|
return io.StringIO(json.dumps(data))
|
|
|
|
urlopen.side_effect = side_effect
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert urlopen.call_count == 1
|
|
assert 'invalid value' not in resp
|
|
assert resp.form['f3'].value == 'EE'
|
|
resp.form['f3'].value = 'DD'
|
|
resp = resp.form.submit('submit')
|
|
assert urlopen.call_count == 2
|
|
resp = resp.follow()
|
|
|
|
|
|
def test_backoffice_wfedit_and_user_selection(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
number31.store()
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert 'Associated User' not in resp
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
|
|
assert resp.pyquery('.submit-user-selection')
|
|
resp.form['user_id'] = str(user.id) # happens via javascript
|
|
resp = resp.form.submit('submit')
|
|
resp = resp.follow()
|
|
assert 'Associated User' in resp
|
|
assert formdef.data_class().get(number31.id).user_id == str(user.id)
|
|
|
|
|
|
def test_backoffice_wfedit_and_user_selection_multi_page(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.fields.insert(0, fields.PageField(id='0', label='1st page', type='page'))
|
|
formdef.fields.append(fields.PageField(id='4', label='2nd page', type='page'))
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
number31.store()
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert 'Associated User' not in resp
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
|
|
assert resp.pyquery('.submit-user-selection')
|
|
resp.form['user_id'] = str(user.id) # happens via javascript
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.pyquery('.submit-user-selection')
|
|
resp = resp.form.submit('submit') # -> save changes
|
|
resp = resp.follow()
|
|
assert 'Associated User' in resp
|
|
assert formdef.data_class().get(number31.id).user_id == str(user.id)
|
|
|
|
number31.store() # save and lose associated user id
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
assert 'Associated User' not in resp
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
|
|
assert resp.pyquery('.submit-user-selection')
|
|
resp = resp.form.submit('submit') # -> 2nd page
|
|
assert resp.pyquery('.submit-user-selection')
|
|
resp.form['user_id'] = str(user.id) # happens via javascript
|
|
resp = resp.form.submit('submit') # -> save changes
|
|
resp = resp.follow()
|
|
assert 'Associated User' in resp
|
|
assert formdef.data_class().get(number31.id).user_id == str(user.id)
|
|
|
|
|
|
def test_backoffice_wfedit_and_live_condition(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.fields[0].varname = 'foo'
|
|
formdef.fields[1].condition = {'type': 'django', 'value': 'form_var_foo == "test"'}
|
|
form_class = formdef.data_class()
|
|
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
|
|
# attach a custom workflow
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1', number31.status.split('-')[1])
|
|
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit').follow()
|
|
live_url = resp.html.find('form').attrs['data-live-url']
|
|
live_resp = app.post(live_url, params=resp.form.submit_fields())
|
|
assert live_resp.json['result']['1']['visible']
|
|
assert not live_resp.json['result']['2']['visible']
|
|
|
|
resp.form['f1'].value = 'test'
|
|
live_resp = app.post(live_url, params=resp.form.submit_fields())
|
|
assert live_resp.json['result']['1']['visible']
|
|
assert live_resp.json['result']['2']['visible']
|
|
|
|
|
|
def test_global_listing(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/').follow()
|
|
assert 'Global View' in resp.text
|
|
resp = resp.click('Global View')
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 20
|
|
assert 'Map View' not in resp.text
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=500')
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 37 # 17 formdef1 + 20 formdef2
|
|
|
|
resp = app.get('/backoffice/management/listing?offset=20&limit=20')
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 17
|
|
|
|
# try an overbound offset
|
|
resp = app.get('/backoffice/management/listing?offset=40&limit=20')
|
|
resp = resp.follow()
|
|
assert resp.forms['listing-settings']['offset'].value == '0'
|
|
|
|
resp = app.get('/backoffice/management/listing')
|
|
resp.forms['listing-settings']['end'] = '2014-02-01'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 20
|
|
assert 'http://example.net/backoffice/management/other-form/' in resp.text
|
|
assert 'http://example.net/backoffice/management/form-title/' not in resp.text
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
last_update_time = formdef.data_class().select(lambda x: not x.is_draft())[0].last_update_time
|
|
# check created and last modified columns
|
|
assert '>2014-01-01 00:00<' in resp.text
|
|
assert time.strftime('>%Y-%m-%d', last_update_time) in resp.text
|
|
|
|
# check digest is included
|
|
formdata = formdef.data_class().get(
|
|
re.findall(r'data-link="(.*?)"', app.get('/backoffice/management/listing').text)[0].split('/')[-2]
|
|
)
|
|
formdata.formdef.digest_templates = {'default': 'digest of number <{{form_number}}>'}
|
|
formdata.store()
|
|
assert formdata.get(formdata.id).digests['default']
|
|
resp = app.get('/backoffice/management/listing')
|
|
assert formdata.get_url(backoffice=True) in resp.text
|
|
assert 'digest of number <%s>' % formdata.id_display in resp.text
|
|
|
|
# check a Channel column is added when welco is available
|
|
assert 'Channel' not in resp.text
|
|
|
|
if not pub.site_options.has_section('variables'):
|
|
pub.site_options.add_section('variables')
|
|
pub.site_options.set('variables', 'welco_url', 'xxx')
|
|
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
|
pub.site_options.write(fd)
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=500')
|
|
formdata = formdef.data_class().select(lambda x: x.status == 'wf-new')[0]
|
|
formdata.submission_channel = 'mail'
|
|
formdata.store()
|
|
assert 'Channel' in resp.text
|
|
assert '>Web<' in resp.text
|
|
resp.forms['listing-settings']['submission_channel'] = 'web'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 36
|
|
resp.forms['listing-settings']['submission_channel'] = 'mail'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 1
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=500')
|
|
resp.forms['listing-settings']['q'] = 'foo'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 17
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=500')
|
|
resp.forms['listing-settings']['status'] = 'waiting'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 37
|
|
resp.forms['listing-settings']['status'] = 'open'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 37
|
|
resp.forms['listing-settings']['status'] = 'all'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 70
|
|
resp.forms['listing-settings']['status'] = 'done'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 33
|
|
|
|
# change role handling a formdef, make sure they do not appear anylonger in
|
|
# the all/done views.
|
|
role = pub.role_class(name='whatever')
|
|
role.store()
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_roles = {'_receiver': role.id}
|
|
formdef.store()
|
|
formdef.data_class().rebuild_security()
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=500')
|
|
resp.forms['listing-settings']['status'] = 'waiting'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 20
|
|
assert 'form-title' not in resp.text
|
|
resp.forms['listing-settings']['status'] = 'open'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 20
|
|
assert 'form-title' not in resp.text
|
|
resp.forms['listing-settings']['status'] = 'all'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 20
|
|
assert 'form-title' not in resp.text
|
|
resp.forms['listing-settings']['status'] = 'done'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 0
|
|
assert 'form-title' not in resp.text
|
|
|
|
|
|
def test_global_listing_parameters_from_query_string(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/listing')
|
|
assert resp.forms['listing-settings']['status'].value == 'waiting'
|
|
assert resp.forms['listing-settings']['limit'].value == '20'
|
|
|
|
resp = app.get('/backoffice/management/listing?status=done')
|
|
assert resp.forms['listing-settings']['status'].value == 'done'
|
|
assert resp.forms['listing-settings']['limit'].value == '20'
|
|
|
|
resp = app.get('/backoffice/management/listing?status=done&limit=50')
|
|
assert resp.forms['listing-settings']['status'].value == 'done'
|
|
assert resp.forms['listing-settings']['limit'].value == '50'
|
|
|
|
resp = app.get('/backoffice/management/listing?status=done&limit=50&q=test')
|
|
assert resp.forms['listing-settings']['status'].value == 'done'
|
|
assert resp.forms['listing-settings']['limit'].value == '50'
|
|
assert resp.forms['listing-settings']['q'].value == 'test'
|
|
|
|
|
|
def test_global_listing_user_label(pub):
|
|
create_user(pub)
|
|
FormDef.wipe()
|
|
|
|
from wcs.admin.settings import UserFieldsFormDef
|
|
|
|
user_formdef = UserFieldsFormDef(pub)
|
|
user_formdef.fields.append(fields.StringField(id='3', label='first_name', type='string'))
|
|
user_formdef.fields.append(fields.StringField(id='4', label='last_name', type='string'))
|
|
user_formdef.store()
|
|
pub.cfg['users']['field_name'] = ['3', '4']
|
|
pub.write_cfg()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'foobar'
|
|
formdef.url_name = 'foobar'
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.fields = [
|
|
fields.StringField(id='1', label='first_name', prefill={'type': 'user', 'value': '3'}),
|
|
fields.StringField(id='2', label='last_name', prefill={'type': 'user', 'value': '4'}),
|
|
]
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'1': 'blah', '2': 'xxx'}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.jump_status('new')
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/').follow()
|
|
resp = resp.click('Global View')
|
|
assert '<td class="cell-user">blah xxx</td>' in resp.text
|
|
|
|
|
|
def test_management_views_with_no_formdefs(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
FormDef.wipe()
|
|
|
|
from wcs.sql import drop_global_views, get_connection_and_cursor
|
|
|
|
conn, cur = get_connection_and_cursor()
|
|
drop_global_views(conn, cur)
|
|
conn.commit()
|
|
cur.close()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert 'This site is currently empty.' in resp.text
|
|
resp = app.get('/backoffice/management/listing')
|
|
assert 'This site is currently empty.' in resp.text
|
|
|
|
|
|
def test_category_in_global_listing(pub):
|
|
FormDef.wipe()
|
|
Category.wipe()
|
|
|
|
create_user(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form-3'
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/listing?limit=500')
|
|
assert 'category_ids$element0' not in resp.forms['listing-settings'].fields
|
|
|
|
cat1 = Category(name='cat1')
|
|
cat1.position = 1
|
|
cat1.store()
|
|
formdef = FormDef()
|
|
formdef.name = 'form-1'
|
|
formdef.category_id = cat1.id
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
cat2 = Category(name='cat2')
|
|
cat1.position = 2
|
|
cat2.store()
|
|
formdef = FormDef()
|
|
formdef.name = 'form-2'
|
|
formdef.category_id = cat2.id
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
resp = app.get('/backoffice/management/listing')
|
|
assert 'category_ids$element0' in resp.forms['listing-settings'].fields
|
|
assert 'management/form-1/' in resp.text
|
|
assert 'management/form-2/' in resp.text
|
|
assert 'management/form-3/' in resp.text
|
|
|
|
resp.forms['listing-settings']['category_ids$element0'] = cat1.id
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert 'management/form-1/' in resp.text
|
|
assert 'management/form-2/' not in resp.text
|
|
assert 'management/form-3/' not in resp.text
|
|
|
|
resp.forms['listing-settings']['category_ids$element0'] = cat2.id
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert 'management/form-1/' not in resp.text
|
|
assert 'management/form-2/' in resp.text
|
|
assert 'management/form-3/' not in resp.text
|
|
|
|
resp = resp.forms['listing-settings'].submit('category_ids$add_element')
|
|
resp.forms['listing-settings']['category_ids$element0'] = cat1.id
|
|
resp.forms['listing-settings']['category_ids$element1'] = cat2.id
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert 'management/form-1/' in resp.text
|
|
assert 'management/form-2/' in resp.text
|
|
assert 'management/form-3/' not in resp.text
|
|
|
|
resp = app.get('/backoffice/management/listing?category_slugs=cat1')
|
|
assert resp.forms['listing-settings']['category_ids$element0'].value == cat1.id
|
|
assert 'category_ids$element1' not in resp.forms['listing-settings'].fields
|
|
assert 'management/form-1/' in resp.text
|
|
assert 'management/form-2/' not in resp.text
|
|
assert 'management/form-3/' not in resp.text
|
|
|
|
resp = app.get('/backoffice/management/listing?category_slugs=cat1,cat2')
|
|
assert resp.forms['listing-settings']['category_ids$element0'].value == cat1.id
|
|
assert resp.forms['listing-settings']['category_ids$element1'].value == cat2.id
|
|
assert 'management/form-1/' in resp.text
|
|
assert 'management/form-2/' in resp.text
|
|
assert 'management/form-3/' not in resp.text
|
|
|
|
|
|
def test_datetime_in_global_listing(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/listing?limit=500')
|
|
resp.forms['listing-settings']['end'] = '01/01/2010'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 0
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=500')
|
|
resp.forms['listing-settings']['start'] = '01/01/2010'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 37
|
|
|
|
resp.forms['listing-settings']['start'] = '01/01/2016'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 0
|
|
|
|
resp.forms['listing-settings']['start'] = '01/01/16'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 0
|
|
|
|
resp.forms['listing-settings']['start'] = '01/01/10'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 37
|
|
|
|
resp.forms['listing-settings']['end'] = '01/01/10'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 0
|
|
|
|
# check invalid values are simply ignored
|
|
resp.forms['listing-settings']['end'] = 'whatever'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 37
|
|
|
|
|
|
def test_global_listing_anonymised(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/listing?limit=500&status=all')
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 70
|
|
|
|
formdef = FormDef.get_by_urlname('other-form')
|
|
for formdata in formdef.data_class().select():
|
|
formdata.anonymise()
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=500&status=all')
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 50
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=500&status=open')
|
|
assert resp.text[resp.text.index('<tbody') :].count('<tr') == 17
|
|
|
|
|
|
def test_global_listing_geojson(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.geolocations = {'base': 'Geolocafoobar'}
|
|
formdef.store()
|
|
for formdata in formdef.data_class().select():
|
|
formdata.geolocations = {'base': {'lat': 48.83, 'lon': 2.32}}
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/geojson')
|
|
assert len(resp.json['features']) == 17
|
|
assert resp.json['features'][0]['geometry']['coordinates'] == [2.32, 48.83]
|
|
for feature in resp.json['features']:
|
|
assert feature['properties']['status_colour'] == '#66FF00'
|
|
assert feature['properties']['view_label'] == 'View'
|
|
assert feature['properties']['status_name'] == 'New'
|
|
assert feature['properties']['display_fields']
|
|
assert feature['properties']['display_fields'][0]['label'] == 'Name'
|
|
assert feature['properties']['display_fields'][0]['value'].startswith('form title #')
|
|
|
|
resp = app.get('/backoffice/management/geojson?q=aa')
|
|
assert len(resp.json['features']) == 5
|
|
resp = app.get('/backoffice/management/geojson?q=bb')
|
|
assert len(resp.json['features']) == 4
|
|
resp = app.get('/backoffice/management/geojson?q=cc')
|
|
assert len(resp.json['features']) == 8
|
|
|
|
|
|
def test_global_map(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.geolocations = {'base': 'Geolocafoobar'}
|
|
formdef.store()
|
|
for formdata in formdef.data_class().select():
|
|
formdata.geolocations = {'base': {'lat': 48.83, 'lon': 2.32}}
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/listing')
|
|
assert 'Map View' in resp.text
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert 'Map View' in resp.text
|
|
resp = resp.click('Map View')
|
|
assert re.findall(r'data-geojson-url="(.*?)"', resp.text) == [
|
|
'http://example.net/backoffice/management/geojson?'
|
|
]
|
|
|
|
resp = app.get('/backoffice/management/map?q=test')
|
|
assert re.findall(r'data-geojson-url="(.*?)"', resp.text) == [
|
|
'http://example.net/backoffice/management/geojson?q=test'
|
|
]
|
|
|
|
|
|
def test_formdata_lookup(pub):
|
|
create_user(pub)
|
|
create_environment(pub, set_receiver=False)
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.enable_tracking_codes = True
|
|
formdef.store()
|
|
formdata, formdata2 = formdef.data_class().select(order_by='id')[:2]
|
|
code = pub.tracking_code_class()
|
|
code.formdata = formdata
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/').follow()
|
|
assert 'id="lookup-box"' in resp.text
|
|
resp.forms[0]['query'] = formdata.tracking_code
|
|
resp = resp.forms[0].submit()
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/%s/' % formdata.id
|
|
resp = resp.follow()
|
|
assert 'The form has been recorded' in resp.text
|
|
assert 'This form has been accessed via its tracking code' in resp.text
|
|
|
|
# check there's no access to other formdata
|
|
app.get('http://example.net/backoffice/management/form-title/%s/' % formdata2.id, status=403)
|
|
|
|
resp = app.get('/backoffice/management/').follow()
|
|
resp.forms[0]['query'] = 'AAAAAAAA'
|
|
resp = resp.forms[0].submit()
|
|
assert resp.location == 'http://example.net/backoffice/management/'
|
|
resp = resp.follow().follow()
|
|
assert 'No such tracking code or identifier.' in resp.text
|
|
|
|
# check looking up a formdata id
|
|
resp.form['query'] = formdata.get_display_id()
|
|
resp = resp.form.submit()
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/%s/' % formdata.id
|
|
|
|
# check looking up on a custom display_id
|
|
formdata.id_display = '999999'
|
|
formdata.store()
|
|
assert formdata.get_display_id() == '999999'
|
|
resp = app.get('/backoffice/management/').follow()
|
|
resp.form['query'] = formdata.get_display_id()
|
|
resp = resp.form.submit()
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/%s/' % formdata.id
|
|
|
|
# try it from the global listing
|
|
resp = app.get('/backoffice/management/listing')
|
|
assert 'id="lookup-box"' in resp.text
|
|
resp.forms[0]['query'] = formdata.tracking_code
|
|
resp = resp.forms[0].submit()
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/%s/' % formdata.id
|
|
resp = resp.follow()
|
|
assert 'The form has been recorded' in resp.text
|
|
|
|
resp = app.get('/backoffice/management/listing')
|
|
resp.forms[0]['query'] = 'AAAAAAAA'
|
|
resp = resp.forms[0].submit()
|
|
assert resp.location == 'http://example.net/backoffice/management/listing'
|
|
resp = resp.follow()
|
|
assert 'No such tracking code or identifier.' in resp.text
|
|
|
|
|
|
def test_backoffice_sidebar_user_context(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
form_class = FormDef.get_by_urlname('form-title').data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert re.findall(r'<tbody.*\/tbody>', resp.text, re.DOTALL)[0].count('<tr') == 17
|
|
|
|
# click on a formdata
|
|
resp = resp.click(href='%s/' % number31.id)
|
|
assert (' with the number %s.' % number31.get_display_id()) in resp.text
|
|
|
|
# check there's nothing in the sidebar
|
|
assert '/user-pending-forms' not in resp.text
|
|
|
|
number31.formdef.digest_templates = {'default': 'digest of number {{form_number}}'}
|
|
number31.user_id = user.id
|
|
number31.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert '/user-pending-forms' in resp.text
|
|
user_pending_form_url = re.findall('data-async-url="(.*/user-pending-forms)"', resp.text)[0]
|
|
partial_resp = app.get(user_pending_form_url)
|
|
assert number31.get_url(backoffice=True) not in partial_resp.text
|
|
assert number31.digests['default'] in partial_resp.text
|
|
assert '<span class="formname">%s</span>' % number31.formdef.name in partial_resp.text
|
|
|
|
# another item with status = new
|
|
number34 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 33'][0]
|
|
number34.user_id = user.id
|
|
number34.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert '/user-pending-forms' in resp.text
|
|
user_pending_form_url = re.findall('data-async-url="(.*/user-pending-forms)"', resp.text)[0]
|
|
partial_resp = app.get(user_pending_form_url)
|
|
assert number31.get_url(backoffice=True) not in partial_resp.text
|
|
assert number34.get_url(backoffice=True) in partial_resp.text
|
|
|
|
cat1 = Category(name='cat1')
|
|
cat1.store()
|
|
|
|
formdef = FormDef.get_by_urlname('other-form')
|
|
formdef.category_id = cat1.id
|
|
formdef.store()
|
|
other_formdata = formdef.data_class().select()[0]
|
|
other_formdata.user_id = user.id
|
|
other_formdata.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert '/user-pending-forms' in resp.text
|
|
user_pending_form_url = re.findall('data-async-url="(.*/user-pending-forms)"', resp.text)[0]
|
|
partial_resp = app.get(user_pending_form_url)
|
|
assert number34.get_url(backoffice=True) in partial_resp.text
|
|
assert other_formdata.get_url(backoffice=True) in partial_resp.text
|
|
# categories are displayed, and current formdata category is on top
|
|
assert '>cat1<' in partial_resp.text
|
|
assert '>Misc<' in partial_resp.text
|
|
assert partial_resp.text.index('>Misc<') < partial_resp.text.index('>cat1<')
|
|
|
|
|
|
def test_backoffice_sidebar_lateral_block(pub):
|
|
create_user(pub)
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
|
|
wf = Workflow(name='WF')
|
|
wf.add_status('Status1')
|
|
wf.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.StringField(id='0', label='string', varname='string'),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.workflow = wf
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.data = {'0': 'bouh'}
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
assert '/lateral-block' not in resp.text
|
|
|
|
formdef.lateral_template = 'XX{{ form_var_string }}XX'
|
|
formdef.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
assert '/lateral-block' in resp.text
|
|
|
|
lateral_block_url = re.findall('data-async-url="(.*/lateral-block)"', resp.text)[0]
|
|
partial_resp = app.get(lateral_block_url)
|
|
assert partial_resp.text == '<div class="lateral-block">XXbouhXX</div>'
|
|
|
|
|
|
def test_count_open(pub):
|
|
create_user(pub)
|
|
|
|
FormDef.wipe()
|
|
resp = login(get_app(pub)).get('/backoffice/management/count')
|
|
assert resp.json['count'] == 0
|
|
|
|
create_environment(pub)
|
|
resp = login(get_app(pub)).get('/backoffice/management/count')
|
|
assert resp.json['count'] == 37
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_roles = {'_receiver': 2} # role the user doesn't have
|
|
formdef.store()
|
|
formdef.data_class().rebuild_security()
|
|
resp = login(get_app(pub)).get('/backoffice/management/count')
|
|
assert resp.json['count'] == 20
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_roles = {'_receiver': 2, '_foobar': 1}
|
|
formdef.store()
|
|
formdef.data_class().rebuild_security()
|
|
resp = login(get_app(pub)).get('/backoffice/management/count')
|
|
assert resp.json['count'] == 20
|
|
resp = login(get_app(pub)).get('/backoffice/management/count?waiting=yes')
|
|
assert resp.json['count'] == 20
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.roles['_foobar'] = 'Foobar'
|
|
workflow.id = '2'
|
|
workflow.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.workflow_roles = {'_receiver': 2, '_foobar': '1'}
|
|
formdef.store()
|
|
formdef.data_class().rebuild_security()
|
|
resp = login(get_app(pub)).get('/backoffice/management/count?waiting=no')
|
|
assert resp.json['count'] == 37
|
|
resp = login(get_app(pub)).get('/backoffice/management/count?waiting=yes')
|
|
assert resp.json['count'] == 20
|
|
resp = login(get_app(pub)).get('/backoffice/management/count')
|
|
assert resp.json['count'] == 20
|
|
|
|
# check the callback parameter is ignored, that we still get the default
|
|
# criterias when it's set.
|
|
resp = login(get_app(pub)).get('/backoffice/management/count?callback=toto')
|
|
assert "20" in resp.text
|
|
|
|
|
|
def test_count_backoffice_drafts(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.backoffice_submission_roles = user.roles[:]
|
|
formdef.store()
|
|
|
|
resp = login(get_app(pub)).get('/backoffice/submission/count')
|
|
assert resp.json['count'] == 0
|
|
|
|
formdata1, formdata2, formdata3 = formdef.data_class().select()[:3]
|
|
for formdata in (formdata1, formdata2, formdata3):
|
|
formdata.status = 'draft'
|
|
formdata.store()
|
|
|
|
resp = login(get_app(pub)).get('/backoffice/submission/count')
|
|
assert resp.json['count'] == 0
|
|
|
|
for formdata in (formdata1, formdata2, formdata3):
|
|
formdata.backoffice_submission = True
|
|
formdata.store()
|
|
|
|
resp = login(get_app(pub)).get('/backoffice/submission/count')
|
|
assert resp.json['count'] == 3
|
|
|
|
formdata1.data = {}
|
|
formdata1.store()
|
|
|
|
resp = login(get_app(pub)).get('/backoffice/submission/count?mode=empty')
|
|
assert resp.json['count'] == 1
|
|
resp = login(get_app(pub)).get('/backoffice/submission/count?mode=existing')
|
|
assert resp.json['count'] == 2
|
|
|
|
|
|
def test_menu_json(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
resp = login(get_app(pub)).get('/backoffice/menu.json')
|
|
menu_json_str = resp.text
|
|
assert len(resp.json) == 1
|
|
assert resp.json[0]['slug'] == 'management'
|
|
assert resp.headers['content-type'] == 'application/json'
|
|
|
|
resp = login(get_app(pub)).get('/backoffice/menu.json?jsonpCallback=foo')
|
|
assert resp.text == 'foo(%s);' % menu_json_str
|
|
assert resp.headers['content-type'] == 'application/javascript'
|
|
|
|
|
|
def test_backoffice_resume_folded(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
form_class = FormDef.get_by_urlname('form-title').data_class()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
app = login(get_app(pub))
|
|
|
|
# first access: summary is not folded
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
assert '<div class="section foldable" id="summary">' in resp.text
|
|
# do something: summary is folded
|
|
resp = resp.form.submit('button_commentable')
|
|
resp = resp.follow()
|
|
assert '<div class="section foldable folded" id="summary">' in resp.text
|
|
|
|
|
|
def test_backoffice_backoffice_submission_in_listings(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
first_link = re.findall(r'data-link="(\d+)/?"', resp.text)[0]
|
|
assert 'backoffice-submission' not in resp.text
|
|
|
|
formdata = FormDef.get_by_urlname('form-title').data_class().get(first_link)
|
|
formdata.backoffice_submission = True
|
|
formdata.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'backoffice-submission' in resp.text
|
|
|
|
|
|
def test_backoffice_backoffice_submission_in_global_listing(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/listing?limit=100')
|
|
assert 'backoffice-submission' not in resp.text
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdata = formdef.data_class().get(
|
|
re.findall(r'data-link="(.*?)"', app.get('/backoffice/management/listing').text)[0].split('/')[-2]
|
|
)
|
|
formdata.backoffice_submission = True
|
|
formdata.store()
|
|
|
|
resp = app.get('/backoffice/management/listing?limit=100')
|
|
assert 'backoffice-submission' in resp.text
|
|
|
|
|
|
def test_backoffice_advisory_lock(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
|
|
second_user = pub.user_class(name='foobar')
|
|
second_user.roles = pub.role_class.keys()
|
|
second_user.store()
|
|
account = PasswordAccount(id='foobar')
|
|
account.set_password('foobar')
|
|
account.user_id = second_user.id
|
|
account.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
first_link = re.findall(r'data-link="(\d+/)?"', resp.text)[0]
|
|
assert 'advisory-lock' not in resp.text
|
|
|
|
app2 = login(get_app(pub), username='foobar', password='foobar')
|
|
resp = app2.get('/backoffice/management/form-title/')
|
|
assert 'advisory-lock' not in resp.text
|
|
|
|
resp = app.get('/backoffice/management/form-title/' + first_link)
|
|
resp = app2.get('/backoffice/management/form-title/')
|
|
assert 'advisory-lock' in resp.text
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'advisory-lock' not in resp.text
|
|
|
|
# check global view
|
|
resp = app2.get('/backoffice/management/listing?limit=100')
|
|
assert 'advisory-lock' in resp.text
|
|
resp = app.get('/backoffice/management/listing?limit=100')
|
|
assert 'advisory-lock' not in resp.text
|
|
|
|
resp = app.get('/backoffice/management/form-title/' + first_link)
|
|
assert 'Be warned forms of this user are also being looked' not in resp.text
|
|
assert 'button_commentable' in resp.text
|
|
assert len(resp.forms)
|
|
resp = app2.get('/backoffice/management/form-title/' + first_link)
|
|
assert 'Be warned forms of this user are also being looked' in resp.text
|
|
assert 'button_commentable' not in resp.text
|
|
assert len(resp.forms) == 0
|
|
# revisit with first user, no change
|
|
resp = app.get('/backoffice/management/form-title/' + first_link)
|
|
assert 'Be warned forms of this user are also being looked' not in resp.text
|
|
assert 'button_commentable' in resp.text
|
|
# back to second
|
|
resp = app2.get('/backoffice/management/form-title/' + first_link)
|
|
assert 'Be warned forms of this user are also being looked' in resp.text
|
|
assert 'button_commentable' not in resp.text
|
|
resp = resp.click('(unlock actions)')
|
|
resp = resp.follow()
|
|
assert 'Be warned forms of this user are also being looked' in resp.text
|
|
assert 'button_commentable' in resp.text
|
|
assert '(unlock actions)' not in resp.text
|
|
assert len(resp.forms)
|
|
|
|
# submit action form
|
|
resp.form['comment'] = 'HELLO'
|
|
resp = resp.form.submit('button_commentable')
|
|
# locks are reset after an action
|
|
assert 'advisory-lock' not in app2.get('/backoffice/management/form-title/')
|
|
assert 'advisory-lock' not in app.get('/backoffice/management/form-title/')
|
|
# but as the current user is redirected to the form, a lock will be
|
|
# acquired (unless the user didn't have actions anymore, but it's not the
|
|
# case here)
|
|
resp = resp.follow()
|
|
assert 'advisory-lock' not in app2.get('/backoffice/management/form-title/')
|
|
assert 'advisory-lock' in app.get('/backoffice/management/form-title/')
|
|
|
|
# don't lock a form on removed users
|
|
second_user.remove_self()
|
|
assert 'advisory-lock' in app.get('/backoffice/management/form-title/') # still marked in listing
|
|
resp = app.get('/backoffice/management/form-title/' + first_link)
|
|
assert 'Be warned forms of this user are also being looked' not in resp.text # but not on view
|
|
assert resp.forms['wf-actions'] # and the action form is available
|
|
|
|
|
|
def test_backoffice_advisory_lock_related_formdatas(pub):
|
|
pub.session_manager.session_class.wipe()
|
|
user = create_superuser(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdatas = formdef.data_class().select(lambda x: x.status == 'wf-new')
|
|
|
|
second_user = pub.user_class(name='foobar')
|
|
second_user.roles = pub.role_class.keys()
|
|
second_user.store()
|
|
account = PasswordAccount(id='foobar')
|
|
account.set_password('foobar')
|
|
account.user_id = second_user.id
|
|
account.store()
|
|
|
|
third_user = pub.user_class(name='user')
|
|
third_user.store()
|
|
|
|
for formdata in formdatas[:2]:
|
|
formdata.user_id = third_user.id
|
|
formdata.store()
|
|
|
|
second_formdef = FormDef.get_by_urlname('other-form')
|
|
second_formdef.workflow_roles = {}
|
|
second_formdef.store()
|
|
other_formdatas = second_formdef.data_class().select(lambda x: x.status == 'wf-new')
|
|
other_formdatas[0].user_id = third_user.id
|
|
other_formdatas[0].store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdatas[0].id)
|
|
assert 'Be warned forms of this user are also being looked' not in resp.text
|
|
app.get(re.findall('data-async-url="(.*/user-pending-forms)"', resp.text)[0])
|
|
|
|
app2 = login(get_app(pub), username='foobar', password='foobar')
|
|
resp2 = app2.get('/backoffice/management/form-title/%s/' % formdatas[0].id)
|
|
assert 'Be warned forms of this user are also being looked' in resp2.text
|
|
app2.get(re.findall('data-async-url="(.*/user-pending-forms)"', resp.text)[0])
|
|
|
|
# another by the same user
|
|
resp2 = app2.get('/backoffice/management/form-title/%s/' % formdatas[1].id)
|
|
assert 'Be warned forms of this user are also being looked' in resp2.text
|
|
app2.get(re.findall('data-async-url="(.*/user-pending-forms)"', resp.text)[0])
|
|
|
|
# another by another user
|
|
resp2 = app2.get('/backoffice/management/form-title/%s/' % formdatas[3].id)
|
|
assert 'Be warned forms of this user are also being looked' not in resp2.text
|
|
app2.get(re.findall('data-async-url="(.*/user-pending-forms)"', resp.text)[0])
|
|
|
|
# check another formdef is only marked as visited if the user has potential
|
|
# actions on it.
|
|
session = pub.session_manager.session_class.select(lambda x: x.user == user.id)[0]
|
|
second_formdef.workflow_roles = {'_receiver': 1}
|
|
second_formdef.store()
|
|
other_formdata = second_formdef.data_class().get(other_formdatas[0].id)
|
|
other_formdata.store() # update concerned_roles
|
|
|
|
assert 'formdata-other-form-%d' % other_formdata.id not in session.visiting_objects.keys()
|
|
session.visiting_objects = {}
|
|
session.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdatas[0].id)
|
|
app.get(re.findall('data-async-url="(.*/user-pending-forms)"', resp.text)[0])
|
|
session = pub.session_manager.session_class.select(lambda x: x.user == user.id)[0]
|
|
assert 'formdef-other-form-%d' % other_formdata.id in session.visiting_objects.keys()
|
|
|
|
|
|
def test_backoffice_resubmit(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow(name='resubmit')
|
|
st1 = wf.add_status('Status1')
|
|
st2 = wf.add_status('Status2')
|
|
|
|
resubmit = st1.add_action('resubmit', id='_resubmit')
|
|
resubmit.by = [user.roles[0]]
|
|
|
|
jump = st1.add_action('jumponsubmit', id='_jump')
|
|
jump.status = st2.id
|
|
|
|
register_comment = st2.add_action('register-comment', id='_register')
|
|
register_comment.comment = '<p><a href="[resubmit_formdata_backoffice_url]">resubmitted</a></p>'
|
|
|
|
wf.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.fields[0].varname = 'foo'
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
|
|
formdef2 = FormDef()
|
|
formdef2.name = 'form title bis'
|
|
formdef2.backoffice_submission_roles = user.roles[:]
|
|
formdef2.fields = [fields.StringField(id='2', label='1st field', type='string', varname='foo')]
|
|
formdef2.store()
|
|
formdef2.data_class().wipe()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.data = {'1': 'XXX'}
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
resp.form['resubmit'].value = formdef2.id
|
|
resp = resp.form.submit('button_resubmit')
|
|
resp = resp.follow()
|
|
assert 'resubmitted' in resp.text
|
|
assert formdef2.data_class().select()[0].status == 'draft'
|
|
assert formdef2.data_class().select()[0].data == {'2': 'XXX'}
|
|
resp = resp.click('resubmitted')
|
|
resp = resp.follow()
|
|
resp = resp.follow()
|
|
assert resp.form['f2'].value == 'XXX'
|
|
assert 'Original form' in resp.text
|
|
assert formdata.get_url(backoffice=True) in resp.text
|
|
|
|
|
|
def test_backoffice_workflow_display_form(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow.get_default_workflow()
|
|
wf.id = '2'
|
|
wf.store()
|
|
wf = Workflow.get(wf.id)
|
|
status = wf.get_status('new')
|
|
status.items = []
|
|
display_form = status.add_action('form', id='_display_form')
|
|
display_form.by = [user.roles[0]]
|
|
display_form.varname = 'blah'
|
|
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
|
|
display_form.formdef.fields.append(
|
|
fields.StringField(id='1', label='Test', varname='str', type='string', required=True)
|
|
)
|
|
display_form.formdef.fields.append(
|
|
# mimick special case: https://dev.entrouvert.org/issues/14691
|
|
# item field displayed as radio buttons, with prefill of a value
|
|
# that doesn't exist.
|
|
fields.ItemField(
|
|
id='2',
|
|
label='Test2',
|
|
type='item',
|
|
prefill={'type': 'string', 'value': ''},
|
|
display_mode='radio',
|
|
varname='radio',
|
|
items=['a', 'b', 'c'],
|
|
required=True,
|
|
)
|
|
)
|
|
|
|
jump = status.add_action('jumponsubmit', id='_jump')
|
|
jump.status = 'accepted'
|
|
|
|
wf.store()
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
|
|
for formdata in formdef.data_class().select():
|
|
if formdata.status == 'wf-new':
|
|
break
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'fblah_1' in resp.form.fields
|
|
resp.form['fblah_1'] = 'blah'
|
|
# don't fill required radio button
|
|
resp = resp.form.submit('submit')
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-new'
|
|
assert 'There were errors processing your form.' in resp.text
|
|
resp.form['fblah_2'] = 'c'
|
|
resp = resp.form.submit('submit')
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-accepted'
|
|
assert formdef.data_class().get(formdata.id).workflow_data == {
|
|
'blah_var_str': 'blah',
|
|
'blah_var_radio': 'c',
|
|
'blah_var_radio_raw': 'c',
|
|
'blah_var_radio_structured': None,
|
|
'blah_var_radio_structured_raw': None,
|
|
}
|
|
|
|
|
|
def test_backoffice_workflow_form_with_conditions(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow.get_default_workflow()
|
|
wf.id = '2'
|
|
wf.store()
|
|
wf = Workflow.get(wf.id)
|
|
status = wf.get_status('new')
|
|
display_form = status.add_action('form', id='_display_form')
|
|
display_form.by = [user.roles[0]]
|
|
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.StringField(id='2', label='Test2', varname='str2', type='string', required=True),
|
|
]
|
|
|
|
wf.store()
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_id = wf.id
|
|
formdef.fields[0].varname = 'plop'
|
|
formdef.store()
|
|
|
|
for formdata in formdef.data_class().select():
|
|
if formdata.status == 'wf-new':
|
|
break
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'fblah_1' in resp.form.fields
|
|
assert 'fblah_2' in resp.form.fields
|
|
|
|
# check with static condition
|
|
display_form.formdef.fields = [
|
|
fields.StringField(id='1', label='Test', varname='str', type='string', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
type='string',
|
|
required=True,
|
|
condition={'type': 'django', 'value': '0'},
|
|
),
|
|
]
|
|
wf.store()
|
|
|
|
resp = login(get_app(pub)).get(formdata.get_url(backoffice=True))
|
|
assert 'fblah_1' in resp.form.fields
|
|
assert 'fblah_2' not in resp.form.fields
|
|
|
|
# check condition based on formdata
|
|
display_form.formdef.fields = [
|
|
fields.StringField(id='1', label='Test', varname='str', type='string', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
type='string',
|
|
required=True,
|
|
condition={'type': 'django', 'value': 'form_var_plop'},
|
|
),
|
|
]
|
|
wf.store()
|
|
|
|
resp = login(get_app(pub)).get(formdata.get_url(backoffice=True))
|
|
assert 'fblah_1' in resp.form.fields
|
|
assert 'fblah_2' in resp.form.fields
|
|
|
|
display_form.formdef.fields = [
|
|
fields.StringField(id='1', label='Test', varname='str', type='string', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
type='string',
|
|
required=True,
|
|
condition={'type': 'django', 'value': 'form_var_plop != "xxx"'},
|
|
),
|
|
]
|
|
wf.store()
|
|
|
|
resp = login(get_app(pub)).get(formdata.get_url(backoffice=True))
|
|
assert 'fblah_1' in resp.form.fields
|
|
assert 'fblah_2' in resp.form.fields
|
|
|
|
for variable_name in (
|
|
'blah_var_str',
|
|
'form_workflow_data_blah_var_str',
|
|
'form_workflow_form_blah_var_str',
|
|
):
|
|
# check with live conditions
|
|
display_form.formdef.fields = [
|
|
fields.StringField(id='1', label='Test', varname='str', type='string', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
type='string',
|
|
required=True,
|
|
condition={'type': 'django', 'value': '%s == "xxx"' % variable_name},
|
|
),
|
|
]
|
|
wf.store()
|
|
|
|
resp = login(get_app(pub)).get(formdata.get_url(backoffice=True))
|
|
assert 'fblah_1' in resp.form.fields
|
|
assert 'fblah_2' in resp.form.fields
|
|
assert resp.html.find('div', {'data-field-id': 'blah_1'}).attrs['data-live-source'] == 'true'
|
|
assert resp.html.find('div', {'data-field-id': 'blah_2'}).attrs.get('style') == 'display: none'
|
|
live_url = resp.html.find('form').attrs['data-live-url']
|
|
assert '/backoffice/' in live_url
|
|
resp.form['fblah_1'] = ''
|
|
live_resp = app.post(live_url, params=resp.form.submit_fields())
|
|
assert live_resp.json['result']['blah_1']['visible']
|
|
assert not live_resp.json['result']['blah_2']['visible']
|
|
|
|
resp.form['fblah_1'] = 'xxx'
|
|
live_resp = app.post(live_url, params=resp.form.submit_fields())
|
|
assert live_resp.json['result']['blah_1']['visible']
|
|
assert live_resp.json['result']['blah_2']['visible']
|
|
|
|
# check submit doesn't work
|
|
resp = resp.form.submit('submit')
|
|
assert 'There were errors processing your form.' in resp.text
|
|
|
|
resp.form['fblah_1'] = 'xxx2'
|
|
live_resp = app.post(live_url, params=resp.form.submit_fields())
|
|
assert live_resp.json['result']['blah_1']['visible']
|
|
assert not live_resp.json['result']['blah_2']['visible']
|
|
|
|
# check submit does work when second field is hidden
|
|
resp = resp.form.submit('submit').follow()
|
|
|
|
assert formdef.data_class().get(formdata.id).workflow_data == {
|
|
'blah_var_str': 'xxx2',
|
|
'blah_var_str2': None,
|
|
}
|
|
|
|
|
|
def test_backoffice_workflow_form_with_live_data_source(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow.get_default_workflow()
|
|
wf.id = '2'
|
|
wf.store()
|
|
wf = Workflow.get(wf.id)
|
|
status = wf.get_status('new')
|
|
display_form = status.add_action('form', id='_display_form')
|
|
display_form.by = [user.roles[0]]
|
|
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.ItemField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
type='item',
|
|
required=True,
|
|
data_source={'type': 'json', 'value': 'https://www.example.invalid/{{ blah_var_str }}'},
|
|
),
|
|
]
|
|
|
|
wf.store()
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_id = wf.id
|
|
formdef.fields[0].varname = 'plop'
|
|
formdef.store()
|
|
|
|
for formdata in formdef.data_class().select():
|
|
if formdata.status == 'wf-new':
|
|
break
|
|
|
|
app = get_app(pub)
|
|
|
|
with mock.patch('wcs.qommon.misc.urlopen') as urlopen:
|
|
data1 = {'data': [{'id': 'A', 'text': 'hello'}, {'id': 'B', 'text': 'world'}]}
|
|
data2 = {'data': [{'id': 'C', 'text': 'hello'}, {'id': 'D', 'text': 'world'}]}
|
|
|
|
def side_effect(url, *args):
|
|
if 'toto' not in url:
|
|
return io.StringIO(json.dumps(data1))
|
|
else:
|
|
return io.StringIO(json.dumps(data2))
|
|
|
|
urlopen.side_effect = side_effect
|
|
|
|
resp = login(app).get(formdata.get_url(backoffice=True))
|
|
assert 'fblah_1' in resp.form.fields
|
|
assert 'fblah_2' in resp.form.fields
|
|
assert resp.form.fields['fblah_2'][0].options == [('A', False, 'hello'), ('B', False, 'world')]
|
|
|
|
live_url = resp.html.find('form').attrs['data-live-url']
|
|
resp.form['fblah_1'] = 'toto'
|
|
live_resp = app.post(live_url + '?modified_field_id=blah_1', params=resp.form.submit_fields())
|
|
assert live_resp.json['result']['blah_2']['items'] == [
|
|
{'text': 'hello', 'id': 'C'},
|
|
{'text': 'world', 'id': 'D'},
|
|
]
|
|
|
|
|
|
def test_backoffice_workflow_display_form_with_block_add(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
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')
|
|
display_form = status.add_action('form', id='_display_form')
|
|
display_form.by = [user.roles[0]]
|
|
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:foobar', varname='data', max_items=3),
|
|
]
|
|
|
|
jump = status.add_action('jumponsubmit', id='_jump')
|
|
jump.status = 'accepted'
|
|
|
|
wf.store()
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
|
|
for formdata in formdef.data_class().select():
|
|
if formdata.status == 'wf-new':
|
|
break
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
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': 'foobar, foobar',
|
|
'blah_var_data_raw': {'data': [{'123': 'foo'}, {'123': 'bar'}], 'schema': {'123': 'string'}},
|
|
'blah_var_str': 'blah',
|
|
}
|
|
|
|
|
|
def test_backoffice_workflow_form_with_other_buttons(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow.get_default_workflow()
|
|
wf.id = '2'
|
|
wf.store()
|
|
wf = Workflow.get(wf.id)
|
|
status = wf.get_status('new')
|
|
status.items = []
|
|
display_form = status.add_action('form', id='_display_form')
|
|
display_form.by = [user.roles[0]]
|
|
display_form.varname = 'blah'
|
|
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
|
|
display_form.formdef.fields.append(
|
|
fields.StringField(id='1', label='Test', varname='str', type='string', required=True)
|
|
)
|
|
choice_ok = status.add_action('choice', id='_ok')
|
|
choice_ok.label = 'OK'
|
|
choice_ok.status = 'accepted'
|
|
choice_ok.by = [user.roles[0]]
|
|
|
|
choice_ko = status.add_action('choice', id='_ko')
|
|
choice_ko.label = 'KO'
|
|
choice_ko.status = 'accepted'
|
|
choice_ko.ignore_form_errors = True
|
|
choice_ko.by = [user.roles[0]]
|
|
|
|
jump = status.add_action('jumponsubmit', id='_jump')
|
|
jump.status = 'accepted'
|
|
|
|
wf.store()
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
|
|
for button_name in ('submit', 'button_ok', 'button_ko'):
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
resp.form['fblah_1'] = 'blah'
|
|
resp = resp.form.submit(button_name)
|
|
|
|
formdata.refresh_from_storage()
|
|
pub.substitutions.reset()
|
|
pub.substitutions.feed(formdata)
|
|
context = pub.substitutions.get_context_variables(mode='lazy')
|
|
assert formdata.status == 'wf-accepted'
|
|
if button_name == 'button_ko':
|
|
assert context['form_workflow_data_blah_var_str'] == 'blah' # leak
|
|
with pytest.raises(KeyError):
|
|
assert context['form_workflow_form_blah_var_str'] == 'blah'
|
|
else:
|
|
assert context['form_workflow_form_blah_var_str'] == 'blah'
|
|
assert context['form_workflow_data_blah_var_str'] == 'blah'
|
|
|
|
|
|
def test_backoffice_criticality_formdata_view(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow.get_default_workflow()
|
|
wf.id = '2'
|
|
wf.criticality_levels = [
|
|
WorkflowCriticalityLevel(name='green'),
|
|
WorkflowCriticalityLevel(name='yellow'),
|
|
WorkflowCriticalityLevel(name='red'),
|
|
]
|
|
wf.store()
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdata = [x for x in formdef.data_class().select() if x.status == 'wf-new'][0]
|
|
|
|
formdata.set_criticality_level(1)
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'Criticality Level: yellow' in resp.text
|
|
|
|
formdata.set_criticality_level(2)
|
|
formdata.store()
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'Criticality Level: red' in resp.text
|
|
|
|
|
|
def test_workflow_jump_previous(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow(name='jump around')
|
|
# North
|
|
# / \
|
|
# West <----> East
|
|
# | |
|
|
# | autojump
|
|
# | |
|
|
# \ /
|
|
# South
|
|
|
|
st1 = wf.add_status('North')
|
|
st1.id = 'north'
|
|
st2 = wf.add_status('West')
|
|
st2.id = 'west'
|
|
st3 = wf.add_status('East')
|
|
st3.id = 'east'
|
|
st4 = wf.add_status('Autojump')
|
|
st4.id = 'autojump'
|
|
st5 = wf.add_status('South')
|
|
st5.id = 'south'
|
|
|
|
button_by_id = {}
|
|
|
|
def add_jump(label, src, dst_id):
|
|
jump = src.add_action('choice', id=str(random.random()))
|
|
jump.label = label
|
|
jump.by = ['logged-users']
|
|
jump.status = dst_id
|
|
if dst_id != '_previous':
|
|
jump.set_marker_on_status = True
|
|
button_by_id[label] = 'button%s' % jump.id
|
|
return jump
|
|
|
|
add_jump('Go West', st1, st2.id)
|
|
add_jump('Go East', st1, st3.id)
|
|
add_jump('Go South', st2, st5.id)
|
|
add_jump('Go Autojump', st3, st4.id)
|
|
add_jump('Go Back', st5, '_previous')
|
|
|
|
add_jump('Jump West', st3, st2.id)
|
|
add_jump('Jump East', st2, st3.id)
|
|
|
|
jump = st4.add_action('jump', id='_auto-jump')
|
|
jump.status = st5.id
|
|
|
|
wf.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.data_class().wipe()
|
|
formdef.workflow = wf
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
|
|
# jump around using buttons
|
|
resp = resp.form.submit(button_by_id['Go West']).follow() # push (north)
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-%s' % st2.id
|
|
resp = resp.form.submit(button_by_id['Go South']).follow() # push (north, west)
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-%s' % st5.id
|
|
resp = resp.form.submit(button_by_id['Go Back']).follow() # pop (north)
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-%s' % st2.id
|
|
resp = resp.form.submit(button_by_id['Go South']).follow() # push (north, west)
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-%s' % st5.id
|
|
resp = resp.form.submit(button_by_id['Go Back']).follow() # pop (north)
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-%s' % st2.id
|
|
resp = resp.form.submit(button_by_id['Jump East']).follow() # push (north, west)
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-%s' % st3.id
|
|
resp = resp.form.submit(button_by_id['Go Autojump']).follow() # push (north, west, east)
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-%s' % st5.id
|
|
|
|
# check markers are displayed in /inspect page
|
|
user.is_admin = True
|
|
user.store()
|
|
resp2 = app.get('/backoffice/management/form-title/%s/inspect' % formdata.id)
|
|
assert 'Markers Stack' in resp2.text
|
|
assert '<span class="status">East</span>' in resp2.text
|
|
assert '<span class="status">West</span>' in resp2.text
|
|
assert '<span class="status">North</span>' in resp2.text
|
|
assert resp2.text.find('<span class="status">East</span>') < resp2.text.find(
|
|
'<span class="status">West</span>'
|
|
)
|
|
assert resp2.text.find('<span class="status">West</span>') < resp2.text.find(
|
|
'<span class="status">North</span>'
|
|
)
|
|
|
|
resp = resp.form.submit(button_by_id['Go Back']).follow() # pop (north, west)
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-%s' % st3.id
|
|
|
|
# and do a last jump using the API
|
|
formdata = formdef.data_class().get(formdata.id)
|
|
formdata.jump_status('_previous') # pop (north)
|
|
assert formdata.status == 'wf-%s' % st2.id
|
|
|
|
formdata = formdef.data_class().get(formdata.id)
|
|
formdata.jump_status('_previous') # pop ()
|
|
assert formdata.status == 'wf-%s' % st1.id
|
|
|
|
|
|
def test_workflow_jump_previous_on_submit(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow(name='blah')
|
|
st1 = wf.add_status('North')
|
|
st1.id = 'north'
|
|
st2 = wf.add_status('South')
|
|
st2.id = 'south'
|
|
|
|
commentable = st1.add_action('commentable', id='_commentable')
|
|
commentable.by = ['_submitter', '_receiver']
|
|
commentable.button_label = 'CLICK ME!'
|
|
|
|
jump = st1.add_action('jumponsubmit', id='_jump')
|
|
jump.status = st2.id
|
|
jump.set_marker_on_status = True
|
|
|
|
back = st2.add_action('choice', id='_back')
|
|
back.label = 'Back'
|
|
back.by = ['_receiver']
|
|
back.status = '_previous'
|
|
|
|
wf.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.data_class().wipe()
|
|
formdef.workflow = wf
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
resp.form['comment'] = 'HELLO WORLD'
|
|
resp = resp.form.submit('button_commentable')
|
|
resp = resp.follow()
|
|
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-south'
|
|
assert formdef.data_class().get(formdata.id).workflow_data['_markers_stack']
|
|
resp = resp.form.submit('button_back')
|
|
resp = resp.follow()
|
|
|
|
assert formdef.data_class().get(formdata.id).status == 'wf-north'
|
|
assert not formdef.data_class().get(formdata.id).workflow_data['_markers_stack']
|
|
|
|
|
|
def test_workflow_jump_previous_auto(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow(name='blah')
|
|
st1 = wf.add_status('North')
|
|
st1.id = 'north'
|
|
st2 = wf.add_status('South')
|
|
st2.id = 'south'
|
|
|
|
jump = st1.add_action('jump', id='_auto-jump')
|
|
jump.set_marker_on_status = True
|
|
jump.status = st2.id
|
|
|
|
back = st2.add_action('choice', id='_back')
|
|
back.label = 'Back'
|
|
back.by = ['_receiver']
|
|
back.status = '_previous'
|
|
|
|
wf.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.data_class().wipe()
|
|
formdef.workflow = wf
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
assert formdata.status == 'wf-south'
|
|
assert formdata.workflow_data['_markers_stack'] == [{'status_id': 'north'}]
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
resp = resp.form.submit('button_back')
|
|
resp = resp.follow()
|
|
|
|
# jumped and got back to north, then re-jump to south again (auto-jump)
|
|
formdata = formdef.data_class().get(formdata.id)
|
|
statuses = [evo.status for evo in formdata.evolution]
|
|
assert statuses == ['wf-north', 'wf-south', 'wf-north', 'wf-south']
|
|
# formdata went through north->south auto-jump again, status and marker are still here
|
|
assert formdata.status == 'wf-south'
|
|
assert formdata.workflow_data['_markers_stack'] == [{'status_id': 'north'}]
|
|
|
|
# no marker (workflow inconsistency)
|
|
formdata.workflow_data['_markers_stack'] = []
|
|
formdata.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
resp = resp.form.submit('button_back')
|
|
resp = resp.follow()
|
|
formdata = formdef.data_class().get(formdata.id)
|
|
assert formdata.status == 'wf-south'
|
|
assert not formdata.workflow_data['_markers_stack']
|
|
|
|
# unknown marker (workflow inconsistency)
|
|
formdata.workflow_data['_markers_stack'] = [{'status_id': 'unknown_status'}]
|
|
formdata.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
resp = resp.form.submit('button_back')
|
|
resp = resp.follow()
|
|
formdata = formdef.data_class().get(formdata.id)
|
|
assert formdata.status == 'wf-south'
|
|
|
|
|
|
def test_backoffice_fields(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow(name='bo fields')
|
|
wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
|
|
wf.backoffice_fields_formdef.fields = [
|
|
fields.StringField(
|
|
id='bo1', label='1st backoffice field', type='string', varname='backoffice_blah', required=False
|
|
),
|
|
]
|
|
wf.add_status('Status1')
|
|
wf.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'Backoffice Data' not in resp.text
|
|
assert '1st backoffice field' not in resp.text
|
|
|
|
formdata.data = {'bo1': 'HELLO WORLD'}
|
|
formdata.store()
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'Backoffice Data' in resp.text
|
|
assert '1st backoffice field' in resp.text
|
|
assert 'HELLO WORLD' in resp.text
|
|
|
|
wf.backoffice_fields_formdef.fields = [
|
|
fields.StringField(
|
|
id='bo1', label='1st backoffice field', type='string', varname='backoffice_blah', required=True
|
|
),
|
|
]
|
|
wf.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'Backoffice Data' in resp.text
|
|
assert 'Not set' in resp.text
|
|
|
|
|
|
def test_backoffice_logged_errors(pub):
|
|
Workflow.wipe()
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '12'
|
|
st1 = workflow.possible_status[0]
|
|
jump = st1.add_action('jump', id='_jump', prepend=True)
|
|
jump.status = 'rejected'
|
|
jump.condition = {'type': 'python', 'value': '1//0'} # ZeroDivisionError
|
|
workflow.store()
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.id = '34'
|
|
formdef.workflow = workflow
|
|
formdef.name = 'test'
|
|
formdef.confirmation = False
|
|
formdef.fields = []
|
|
formdef.store()
|
|
|
|
# create a carddef with the same id
|
|
CardDef.wipe()
|
|
carddef = CardDef()
|
|
carddef.id = '34'
|
|
carddef.name = 'test'
|
|
carddef.fields = []
|
|
carddef.store()
|
|
|
|
create_superuser(pub)
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/forms/%s/' % formdef.id)
|
|
assert 'ZeroDivisionError' not in resp.text
|
|
resp = app.get('/backoffice/cards/%s/' % carddef.id)
|
|
assert 'ZeroDivisionError' not in resp.text
|
|
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
|
|
assert 'ZeroDivisionError' not in resp.text
|
|
|
|
app = get_app(pub)
|
|
resp = app.get('/test/')
|
|
resp = resp.form.submit('submit').follow()
|
|
resp = resp.form.submit('submit')
|
|
assert pub.loggederror_class.count() == 1
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/forms/%s/' % formdef.id)
|
|
assert 'Failed to evaluate condition' in resp.text
|
|
assert 'ZeroDivisionError' in resp.text
|
|
resp = resp.click('1 error')
|
|
resp = app.get('/backoffice/cards/%s/' % carddef.id)
|
|
assert 'ZeroDivisionError' not in resp.text
|
|
|
|
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
|
|
resp2 = resp.click('1 error')
|
|
assert 'Failed to evaluate condition' in resp2.text
|
|
assert 'ZeroDivisionError' in resp2.text
|
|
resp = resp2.click('Failed to evaluate condition')
|
|
assert 'ZeroDivisionError: integer division or modulo by zero' in resp.text
|
|
assert 'Python Expression: <code>1//0</code>' in resp.text
|
|
resp = resp.click('Delete').follow()
|
|
assert pub.loggederror_class.count() == 0
|
|
|
|
pub.cfg.update({'debug': {'error_email': None}})
|
|
pub.write_cfg()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get('/test/')
|
|
resp = resp.form.submit('submit').follow()
|
|
resp = resp.form.submit('submit')
|
|
assert pub.loggederror_class.count() == 1
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
|
|
assert 'Failed to evaluate condition' in resp2.text
|
|
assert 'ZeroDivisionError' in resp2.text
|
|
resp2 = resp.click('1 error')
|
|
resp = resp2.click('Failed to evaluate condition')
|
|
assert 'href="http://example.net/backoffice/management/test/' in resp.text
|
|
|
|
# very long error string (check it creates a viable tech_id)
|
|
jump.condition = {'type': 'python', 'value': 'x' * 500} # NameError + very long string
|
|
workflow.store()
|
|
|
|
app = get_app(pub)
|
|
resp = app.get('/test/')
|
|
resp = resp.form.submit('submit').follow()
|
|
resp = resp.form.submit('submit')
|
|
assert pub.loggederror_class.count() == 2
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
|
|
assert 'Failed to evaluate condition' in resp.text
|
|
assert "error NameError (name 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx…" in resp.text
|
|
|
|
# remove formdef
|
|
FormDef.wipe()
|
|
resp = resp2.click('Failed to evaluate condition')
|
|
assert 'href="http://example.net/backoffice/management/test/' not in resp.text
|
|
|
|
|
|
def test_backoffice_formdata_named_wscall(http_requests, pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
NamedWsCall.wipe()
|
|
|
|
wscall = NamedWsCall()
|
|
wscall.name = 'Hello world'
|
|
wscall.request = {'url': 'http://remote.example.net/json'}
|
|
wscall.store()
|
|
assert wscall.slug == 'hello_world'
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test'
|
|
formdef.backoffice_submission_roles = user.roles[:]
|
|
formdef.fields = [
|
|
fields.CommentField(id='7', label='X[webservice.hello_world.foo]Y', type='comment'),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/submission/test/')
|
|
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'XbarY'
|
|
|
|
# check with publisher variable in named webservice call
|
|
if not pub.site_options.has_section('variables'):
|
|
pub.site_options.add_section('variables')
|
|
pub.site_options.set('variables', 'example_url', 'http://remote.example.net/')
|
|
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
|
pub.site_options.write(fd)
|
|
|
|
wscall = NamedWsCall()
|
|
wscall.name = 'Hello world'
|
|
wscall.request = {'url': '[example_url]json'}
|
|
wscall.store()
|
|
|
|
resp = app.get('/backoffice/submission/test/')
|
|
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'XbarY'
|
|
|
|
# django-templated URL
|
|
wscall.request = {'url': '{{ example_url }}json'}
|
|
wscall.store()
|
|
resp = app.get('/backoffice/submission/test/')
|
|
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'XbarY'
|
|
|
|
# webservice call in django template
|
|
formdef.fields = [
|
|
fields.CommentField(id='7', label='dja-{{ webservice.hello_world.foo}}-ngo', type='comment'),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
resp = app.get('/backoffice/submission/test/')
|
|
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'dja-bar-ngo'
|
|
|
|
|
|
def test_backoffice_session_var(pub):
|
|
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
|
fd.write(
|
|
'''[options]
|
|
query_string_allowed_vars = foo,bar
|
|
'''
|
|
)
|
|
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test'
|
|
formdef.backoffice_submission_roles = user.roles[:]
|
|
formdef.fields = [
|
|
fields.CommentField(id='7', label='X[session_var_foo]Y', type='comment'),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get('/backoffice/submission/test/?session_var_foo=bar')
|
|
assert resp.location.endswith('/backoffice/submission/test/')
|
|
resp = resp.follow()
|
|
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'XbarY'
|
|
|
|
# django template
|
|
formdef.fields = [
|
|
fields.CommentField(id='7', label='d{{ session_var_foo }}o', type='comment'),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
resp = app.get('/backoffice/submission/test/?session_var_foo=jang')
|
|
assert resp.location.endswith('/backoffice/submission/test/')
|
|
resp = resp.follow()
|
|
assert resp.html.find('div', {'data-field-id': '7'}).text.strip() == 'django'
|
|
|
|
|
|
def test_backoffice_display_message(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
workflow = Workflow(name='test')
|
|
st1 = workflow.add_status('Status1', 'st1')
|
|
|
|
display1 = st1.add_action('displaymsg')
|
|
display1.message = 'message-to-all'
|
|
display1.to = []
|
|
|
|
display2 = st1.add_action('displaymsg')
|
|
display2.message = 'message-to-submitter'
|
|
display2.to = ['_submitter']
|
|
|
|
display3 = st1.add_action('displaymsg')
|
|
display3.message = 'message-to-receiver'
|
|
display3.to = [user.roles[0]]
|
|
|
|
workflow.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class().select()[0]
|
|
formdata.jump_status('st1')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
|
|
assert 'message-to-all' in resp.text
|
|
assert 'message-to-submitter' not in resp.text
|
|
assert 'message-to-receiver' in resp.text
|
|
|
|
# display first message at the bottom of the page
|
|
display1.position = 'bottom'
|
|
workflow.store()
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert resp.text.index('message-to-all') > resp.text.index('message-to-receiver')
|
|
|
|
# display first message on top of actions
|
|
display1.position = 'actions'
|
|
workflow.store()
|
|
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'message-to-all' not in resp.text # no actions no message
|
|
|
|
again = st1.add_action('choice', id='_again')
|
|
again.label = 'Again'
|
|
again.by = ['_receiver']
|
|
again.status = st1.id
|
|
workflow.store()
|
|
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'message-to-all' in resp.text
|
|
assert resp.text.index('message-to-all') > resp.text.index('message-to-receiver')
|
|
|
|
|
|
def test_backoffice_forms_condition_on_button(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub, set_receiver=True)
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
workflow.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
|
|
# move some forms from new to accepted
|
|
for i, formdata in enumerate(formdef.data_class().select(lambda x: x.status == 'wf-new')):
|
|
if i % 2:
|
|
formdata.status = 'wf-accepted'
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert '17 open on 50' in resp.text
|
|
|
|
formdata = [x for x in formdef.data_class().select() if x.status == 'wf-new'][0]
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'button_commentable' in resp.text
|
|
assert 'button_accept' in resp.text
|
|
assert 'button_reject' in resp.text
|
|
|
|
# commentable
|
|
workflow.possible_status[1].items[0].condition = {'type': 'python', 'value': 'False'}
|
|
# reject
|
|
workflow.possible_status[1].items[2].condition = {'type': 'python', 'value': 'False'}
|
|
workflow.store()
|
|
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'button_commentable' not in resp.text
|
|
assert 'button_accept' in resp.text
|
|
assert 'button_reject' not in resp.text
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
assert formdef.data_class().get(formdata.id).actions_roles == {'1'}
|
|
|
|
# accept
|
|
workflow.possible_status[1].items[1].condition = {'type': 'python', 'value': 'False'}
|
|
workflow.store()
|
|
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'button_commentable' not in resp.text
|
|
assert 'button_accept' not in resp.text
|
|
assert 'button_reject' not in resp.text
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
assert formdef.data_class().get(formdata.id).actions_roles == set()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/forms')
|
|
assert '8 open on 50' in resp.text # only the accepted ones
|
|
|
|
|
|
def test_workflow_comment_required(pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
|
|
wf = Workflow(name='blah')
|
|
st1 = wf.add_status('Comment')
|
|
st1.id = 'comment'
|
|
commentable = st1.add_action('commentable', id='_commentable')
|
|
commentable.by = ['_submitter', '_receiver']
|
|
wf.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.data_class().wipe()
|
|
formdef.workflow = wf
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
assert 'widget-required' not in resp.text
|
|
resp.form['comment'] = 'HELLO WORLD 1'
|
|
resp = resp.form.submit('button_commentable')
|
|
resp = resp.follow()
|
|
assert 'HELLO WORLD 1' in resp.text
|
|
assert 'widget-required' not in resp.text
|
|
resp.form['comment'] = None
|
|
resp = resp.form.submit('button_commentable')
|
|
resp = resp.follow()
|
|
|
|
commentable.required = True
|
|
wf.store()
|
|
resp = app.get('/backoffice/management/form-title/%s/' % formdata.id)
|
|
assert 'widget-required' in resp.text
|
|
resp.form['comment'] = ' ' # spaces == empty
|
|
resp = resp.form.submit('button_commentable')
|
|
assert 'widget-with-error' in resp.text
|
|
resp.form['comment'] = 'HELLO WORLD 2'
|
|
resp = resp.form.submit('button_commentable')
|
|
resp = resp.follow()
|
|
assert 'widget-with-error' not in resp.text
|
|
assert 'HELLO WORLD 2' in resp.text
|
|
|
|
|
|
def test_lazy_eval_with_conditional_workflow_form(pub):
|
|
role = pub.role_class(name='foobar')
|
|
role.store()
|
|
user = create_user(pub)
|
|
|
|
app = login(get_app(pub))
|
|
|
|
FormDef.wipe()
|
|
|
|
wf = Workflow(name='lazy backoffice form')
|
|
wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
|
|
wf.backoffice_fields_formdef.fields = [
|
|
fields.StringField(id='bo1', label='Foo Bar', varname='foo_bar'),
|
|
]
|
|
st1 = wf.add_status('New', 'new')
|
|
st2 = wf.add_status('Choose', 'choice')
|
|
st3 = wf.add_status('Done', 'done')
|
|
|
|
# first status with a workflow form, with a live conditional field.
|
|
display_form = st1.add_action('form', id='_display_form')
|
|
display_form.by = [user.roles[0]]
|
|
display_form.varname = 'local'
|
|
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
|
|
display_form.formdef.fields = [
|
|
fields.StringField(id='1', label='Test', varname='str', type='string', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test 2',
|
|
varname='str2',
|
|
type='string',
|
|
condition={'type': 'django', 'value': 'local_var_str'},
|
|
),
|
|
]
|
|
|
|
submit_choice = st1.add_action('jumponsubmit')
|
|
submit_choice.status = st2.id
|
|
|
|
# jump to a second status, that set's a backoffice field data
|
|
setbo = st2.add_action('set-backoffice-fields')
|
|
setbo.fields = [{'field_id': 'bo1', 'value': 'go'}]
|
|
|
|
# and jump to the third status if the evoluation succeeds
|
|
jump = st2.add_action('jump')
|
|
jump.condition = {'type': 'django', 'value': "form_var_foo_bar == 'go'"}
|
|
jump.status = st3.id
|
|
wf.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test'
|
|
formdef.fields = [fields.StringField(id='0', label='Foo', varname='foo')]
|
|
formdef.workflow_roles = {'_receiver': role.id}
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.data = {'0': 'test'}
|
|
formdata.store()
|
|
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
resp.forms[0]['flocal_1'] = 'a'
|
|
resp.forms[0]['flocal_2'] = 'b'
|
|
resp = resp.forms[0].submit()
|
|
assert formdata.select()[0].status == 'wf-done'
|
|
|
|
context = pub.substitutions.get_context_variables(mode='lazy')
|
|
assert context['form_var_foo_bar'] == 'go'
|
|
|
|
|
|
@pytest.fixture(params=[{'attach_to_history': True}, {}])
|
|
def create_formdata(request, pub):
|
|
admin = create_user(pub, is_admin=True)
|
|
|
|
FormDef.wipe()
|
|
|
|
source_formdef = FormDef()
|
|
source_formdef.name = 'source form'
|
|
source_formdef.workflow_roles = {'_receiver': 1}
|
|
source_formdef.fields = [
|
|
fields.StringField(id='0', label='string', varname='toto_string'),
|
|
fields.FileField(id='1', label='file', type='file', varname='toto_file'),
|
|
]
|
|
source_formdef.store()
|
|
|
|
target_formdef = FormDef()
|
|
target_formdef.name = 'target form'
|
|
target_formdef.workflow_roles = {'_receiver': 1}
|
|
target_formdef.backoffice_submission_roles = admin.roles[:]
|
|
target_formdef.fields = [
|
|
fields.StringField(id='0', label='string', varname='foo_string'),
|
|
fields.FileField(id='1', label='file', type='file', varname='foo_file'),
|
|
]
|
|
target_formdef.store()
|
|
wf = Workflow(name='create-formdata')
|
|
|
|
st1 = wf.add_status('New')
|
|
st2 = wf.add_status('Resubmit')
|
|
|
|
jump = st1.add_action('choice', id='_resubmit')
|
|
jump.label = 'Resubmit'
|
|
jump.by = ['_receiver']
|
|
jump.status = st2.id
|
|
|
|
create_formdata = st2.add_action('create_formdata', id='_create_formdata')
|
|
create_formdata.varname = 'resubmitted'
|
|
create_formdata.draft = True
|
|
create_formdata.formdef_slug = target_formdef.url_name
|
|
create_formdata.user_association_mode = 'keep-user'
|
|
create_formdata.backoffice_submission = True
|
|
create_formdata.attach_to_history = request.param.get('attach_to_history', False)
|
|
create_formdata.mappings = [
|
|
Mapping(field_id='0', expression='=form_var_toto_string'),
|
|
Mapping(field_id='1', expression='=form_var_toto_file_raw'),
|
|
]
|
|
|
|
redirect = st2.add_action('redirect_to_url', id='_redirect')
|
|
redirect.url = '{{ form_links_resubmitted.form_backoffice_url }}'
|
|
|
|
jump = st2.add_action('jumponsubmit', id='_jump')
|
|
jump.status = st1.id
|
|
|
|
wf.store()
|
|
source_formdef.workflow_id = wf.id
|
|
source_formdef.store()
|
|
source_formdef.data_class().wipe()
|
|
target_formdef.data_class().wipe()
|
|
return locals()
|
|
|
|
|
|
def test_backoffice_create_formdata_backoffice_submission(pub, create_formdata):
|
|
# create submitting user
|
|
user = create_formdata['pub'].user_class()
|
|
user.name = 'Jean Darmette'
|
|
user.email = 'jean.darmette@triffouilis.fr'
|
|
user.store()
|
|
|
|
# create source formdata
|
|
formdata = create_formdata['source_formdef'].data_class()()
|
|
upload = PicklableUpload('/foo/bar', content_type='text/plain')
|
|
upload.receive([b'hello world'])
|
|
formdata.data = {
|
|
'0': 'coucou',
|
|
'1': upload,
|
|
}
|
|
formdata.user = user
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
|
|
# agent login and go to backoffice management pages
|
|
app = get_app(create_formdata['pub'])
|
|
app = login(app)
|
|
resp = app.get(create_formdata['source_formdef'].get_url(backoffice=True))
|
|
|
|
# click on first available formdata
|
|
resp = resp.click('%s-%s' % (create_formdata['source_formdef'].id, formdata.id))
|
|
target_data_class = create_formdata['target_formdef'].data_class()
|
|
assert target_data_class.count() == 0
|
|
# resubmit it through backoffice submission
|
|
resp = resp.form.submit(name='button_resubmit')
|
|
assert pub.loggederror_class.count() == 0
|
|
assert target_data_class.count() == 1
|
|
target_formdata = target_data_class.select()[0]
|
|
|
|
assert target_formdata.submission_context == {
|
|
'orig_object_type': 'formdef',
|
|
'orig_formdata_id': '1',
|
|
'orig_formdef_id': '1',
|
|
}
|
|
assert target_formdata.submission_agent_id == str(create_formdata['admin'].id)
|
|
assert target_formdata.user.id == user.id
|
|
assert target_formdata.status == 'draft'
|
|
assert resp.location == 'http://example.net/backoffice/management/target-form/%s/' % target_formdata.id
|
|
resp = resp.follow()
|
|
assert resp.location == 'http://example.net/backoffice/submission/target-form/%s/' % target_formdata.id
|
|
resp = resp.follow()
|
|
# second redirect with magic-token
|
|
resp = resp.follow()
|
|
resp = resp.form.submit(name='submit') # -> validation
|
|
resp = resp.form.submit(name='submit') # -> submission
|
|
target_formdata = target_data_class.get(id=target_formdata.id)
|
|
assert target_formdata.user.id == user.id
|
|
assert target_formdata.status == 'wf-new'
|
|
resp = resp.follow()
|
|
pq = resp.pyquery.remove_namespaces()
|
|
assert pq('.field-type-string .value').text() == 'coucou'
|
|
assert pq('.field-type-file .value').text() == 'bar'
|
|
|
|
|
|
def test_linked_forms_variables(pub, create_formdata):
|
|
# create source formdata
|
|
formdata = create_formdata['source_formdef'].data_class()()
|
|
upload = PicklableUpload('/foo/bar', content_type='text/plain')
|
|
upload.receive([b'hello world'])
|
|
formdata.data = {
|
|
'0': 'coucou',
|
|
'1': upload,
|
|
}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
formdata.store()
|
|
formdata.jump_status('2')
|
|
formdata.perform_workflow()
|
|
formdata.store()
|
|
|
|
pub.substitutions.reset()
|
|
pub.substitutions.feed(formdata)
|
|
substvars = pub.substitutions.get_context_variables(mode='lazy')
|
|
assert str(substvars['form_links_resubmitted_form_var_foo_string']) == 'coucou'
|
|
assert 'form_links_resubmitted_form_var_foo_string' in substvars.get_flat_keys()
|
|
|
|
source_formdata = create_formdata['source_formdef'].data_class().select()[0]
|
|
|
|
app = get_app(create_formdata['pub'])
|
|
app = login(app)
|
|
resp = app.get(source_formdata.get_url(backoffice=True) + 'inspect')
|
|
assert 'form_links_resubmitted_form_var_foo_string' in resp
|
|
|
|
# delete target formdata
|
|
create_formdata['target_formdef'].data_class().wipe()
|
|
resp = app.get(source_formdata.get_url(backoffice=True) + 'inspect')
|
|
assert 'form_links_resubmitted_form_var_foo_string' not in resp
|
|
|
|
# delete target formdef
|
|
create_formdata['target_formdef'].remove_self()
|
|
resp = app.get(source_formdata.get_url(backoffice=True) + 'inspect')
|
|
|
|
|
|
def test_backoffice_create_formdata_map_fields_by_varname(pub, create_formdata):
|
|
create_formdata['create_formdata'].map_fields_by_varname = True
|
|
create_formdata['create_formdata'].mappings = []
|
|
create_formdata['wf'].store()
|
|
create_formdata['source_formdef'].fields = [
|
|
fields.StringField(id='0', label='string', varname='string0'),
|
|
fields.FileField(id='1', label='file', type='file', varname='file1'),
|
|
fields.StringField(id='2', label='string', varname='string2', required=False),
|
|
fields.FileField(id='3', label='file', type='file', varname='file3', required=False),
|
|
]
|
|
create_formdata['source_formdef'].store()
|
|
create_formdata['target_formdef'].fields = [
|
|
fields.StringField(id='0', label='string', varname='string0'),
|
|
fields.FileField(id='1', label='file', type='file', varname='file1'),
|
|
fields.StringField(id='2', label='string', varname='string2', required=False),
|
|
fields.FileField(id='3', label='file', type='file', varname='file3', required=False),
|
|
]
|
|
create_formdata['target_formdef'].store()
|
|
|
|
# create submitting user
|
|
user = create_formdata['pub'].user_class()
|
|
user.name = 'Jean Darmette'
|
|
user.email = 'jean.darmette@triffouilis.fr'
|
|
user.store()
|
|
|
|
# create source formdata
|
|
formdata = create_formdata['source_formdef'].data_class()()
|
|
create_formdata['formdata'] = formdata
|
|
upload = PicklableUpload('/foo/bar', content_type='text/plain')
|
|
upload.receive([b'hello world'])
|
|
formdata.data = {
|
|
'0': 'coucou',
|
|
'1': upload,
|
|
}
|
|
formdata.user = user
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
|
|
# agent login and go to backoffice management pages
|
|
app = get_app(create_formdata['pub'])
|
|
app = login(app)
|
|
resp = app.get(create_formdata['source_formdef'].get_url(backoffice=True))
|
|
|
|
# click on first available formdata
|
|
resp = resp.click('%s-%s' % (create_formdata['source_formdef'].id, formdata.id))
|
|
target_data_class = create_formdata['target_formdef'].data_class()
|
|
assert target_data_class.count() == 0
|
|
# resubmit it through backoffice submission
|
|
resp = resp.form.submit(name='button_resubmit')
|
|
assert pub.loggederror_class.count() == 0
|
|
assert target_data_class.count() == 1
|
|
target_formdata = target_data_class.select()[0]
|
|
|
|
assert target_formdata.submission_context == {
|
|
'orig_object_type': 'formdef',
|
|
'orig_formdata_id': '1',
|
|
'orig_formdef_id': '1',
|
|
}
|
|
assert target_formdata.submission_agent_id == str(create_formdata['admin'].id)
|
|
assert target_formdata.user.id == user.id
|
|
assert target_formdata.status == 'draft'
|
|
assert resp.location == 'http://example.net/backoffice/management/target-form/%s/' % target_formdata.id
|
|
resp = resp.follow()
|
|
assert resp.location == 'http://example.net/backoffice/submission/target-form/%s/' % target_formdata.id
|
|
resp = resp.follow()
|
|
# second redirect with magic-token
|
|
resp = resp.follow()
|
|
resp = resp.form.submit(name='submit') # -> validation
|
|
resp = resp.form.submit(name='submit') # -> submission
|
|
target_formdata = target_data_class.get(id=target_formdata.id)
|
|
assert target_formdata.user.id == user.id
|
|
assert target_formdata.status == 'wf-new'
|
|
resp = resp.follow()
|
|
pq = resp.pyquery.remove_namespaces()
|
|
assert pq('.field-type-string .value').text() == 'coucou'
|
|
assert pq('.field-type-file .value').text() == 'bar'
|
|
|
|
resp = app.get(create_formdata['formdata'].get_url(backoffice=True))
|
|
pq = resp.pyquery.remove_namespaces()
|
|
assert pq('.field-type-string .value').text() == 'coucou'
|
|
if create_formdata['create_formdata'].attach_to_history:
|
|
assert pq('.wf-links')
|
|
else:
|
|
assert not pq('.wf-links')
|
|
|
|
|
|
def test_backoffice_create_formdata_map_fields_by_varname_plus_empty(pub, create_formdata):
|
|
create_formdata['create_formdata'].map_fields_by_varname = True
|
|
create_formdata['create_formdata'].mappings = [
|
|
Mapping(field_id='0', expression=None),
|
|
]
|
|
create_formdata['wf'].store()
|
|
create_formdata['source_formdef'].fields = [
|
|
fields.StringField(id='0', label='string', varname='string0'),
|
|
fields.StringField(id='2', label='string', varname='string2', required=False),
|
|
]
|
|
create_formdata['source_formdef'].store()
|
|
create_formdata['target_formdef'].fields = [
|
|
fields.StringField(id='0', label='string', varname='string0'),
|
|
fields.StringField(id='2', label='string', varname='string2', required=False),
|
|
]
|
|
create_formdata['target_formdef'].store()
|
|
|
|
# create submitting user
|
|
user = create_formdata['pub'].user_class()
|
|
user.name = 'Jean Darmette'
|
|
user.email = 'jean.darmette@triffouilis.fr'
|
|
user.store()
|
|
|
|
# create source formdata
|
|
formdata = create_formdata['source_formdef'].data_class()()
|
|
create_formdata['formdata'] = formdata
|
|
formdata.data = {
|
|
'0': 'foo',
|
|
'2': 'bar',
|
|
}
|
|
formdata.user = user
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
|
|
# agent login and go to backoffice management pages
|
|
app = get_app(create_formdata['pub'])
|
|
app = login(app)
|
|
resp = app.get(create_formdata['source_formdef'].get_url(backoffice=True))
|
|
|
|
# click on first available formdata
|
|
resp = resp.click('%s-%s' % (create_formdata['source_formdef'].id, formdata.id))
|
|
target_data_class = create_formdata['target_formdef'].data_class()
|
|
assert target_data_class.count() == 0
|
|
# resubmit it through backoffice submission
|
|
resp = resp.form.submit(name='button_resubmit')
|
|
assert target_data_class.count() == 1
|
|
target_formdata = target_data_class.select()[0]
|
|
|
|
assert target_formdata.submission_context == {
|
|
'orig_object_type': 'formdef',
|
|
'orig_formdata_id': '1',
|
|
'orig_formdef_id': '1',
|
|
}
|
|
assert target_formdata.submission_agent_id == str(create_formdata['admin'].id)
|
|
assert target_formdata.user.id == user.id
|
|
assert target_formdata.status == 'draft'
|
|
assert target_formdata.data == {'0': None, '2': 'bar'}
|
|
|
|
|
|
def test_backoffice_create_carddata_from_formdata(pub):
|
|
CardDef.wipe()
|
|
FormDef.wipe()
|
|
|
|
user = create_user(pub, is_admin=True)
|
|
user.name = 'Foo Bar'
|
|
user.email = 'foo@example.com'
|
|
user.store()
|
|
|
|
carddef = CardDef()
|
|
carddef.name = 'My card'
|
|
carddef.fields = [
|
|
fields.StringField(id='1', label='string'),
|
|
fields.ItemField(id='2', label='List', items=['item1', 'item2']),
|
|
fields.DateField(id='3', label='Date'),
|
|
]
|
|
carddef.store()
|
|
|
|
wf = Workflow(name='create-carddata')
|
|
st1 = wf.add_status('New')
|
|
st2 = wf.add_status('Create card')
|
|
|
|
jump = st1.add_action('choice', id='_createcard')
|
|
jump.label = 'Create card'
|
|
jump.by = ['_receiver']
|
|
jump.status = st2.id
|
|
|
|
create_card = st2.add_action('create_carddata', id='_create')
|
|
create_card.label = 'Create Card Data'
|
|
create_card.varname = 'mycard'
|
|
create_card.formdef_slug = carddef.url_name
|
|
create_card.mappings = [
|
|
Mapping(field_id='1', expression='Simple String'),
|
|
Mapping(field_id='2', expression='{{ form_var_list_raw }}'),
|
|
Mapping(field_id='3', expression='{{ form_var_date }}'),
|
|
]
|
|
|
|
display_message = st2.add_action('displaymsg')
|
|
display_message.message = 'Card nr. {{ form_links_mycard_form_number }} created'
|
|
wf.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'Source form'
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.fields = [
|
|
fields.ItemField(id='1', label='List', items=['item1', 'item2'], varname='list'),
|
|
fields.DateField(id='2', label='Date', varname='date'),
|
|
]
|
|
formdef.workflow_id = wf.id
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
today = time.strptime('2020-01-01', '%Y-%m-%d')
|
|
formdata.data = {'1': 'item2', '2': today}
|
|
|
|
formdata.user = user
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
resp = resp.form.submit(name='button_createcard').follow()
|
|
assert 'Card nr. 1-1 created' in resp
|
|
|
|
# visit inspect page
|
|
resp = app.get(formdata.get_url(backoffice=True) + 'inspect')
|
|
assert "variables from parent's request" in resp
|
|
|
|
|
|
def test_backoffice_after_submit_location(pub):
|
|
create_superuser(pub)
|
|
create_environment(pub)
|
|
|
|
workflow = Workflow(name='test')
|
|
st1 = workflow.add_status('Status1', 'st1')
|
|
|
|
commentable = st1.add_action('commentable', id='_commentable')
|
|
commentable.by = [logged_users_role().id]
|
|
commentable.required = True
|
|
|
|
workflow.store()
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
for formdata in formdef.data_class().select():
|
|
formdata.status = 'wf-%s' % st1.id
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
resp.form['comment'] = 'plop'
|
|
resp = resp.form.submit('submit')
|
|
assert (
|
|
resp.location == 'http://example.net/backoffice/management/form-title/%s/#action-zone' % formdata.id
|
|
)
|
|
resp = resp.follow()
|
|
|
|
display = st1.add_action('displaymsg')
|
|
display.message = 'message-to-all'
|
|
display.to = []
|
|
workflow.store()
|
|
|
|
resp.form['comment'] = 'plop'
|
|
resp = resp.form.submit('submit')
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/%s/#' % formdata.id
|
|
|
|
|
|
def test_backoffice_http_basic_auth(pub):
|
|
access = ApiAccess()
|
|
access.name = 'test'
|
|
access.access_identifier = 'test'
|
|
access.access_key = '12345'
|
|
access.store()
|
|
|
|
create_superuser(pub)
|
|
app = get_app(pub)
|
|
app.set_authorization(('Basic', ('test', '12345')))
|
|
app.get('/backoffice/', status=403)
|
|
|
|
|
|
def test_backoffice_dispatch_lose_access(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
role1 = pub.role_class(name='xxx1')
|
|
role1.store()
|
|
role2 = pub.role_class(name='xxx2')
|
|
role2.store()
|
|
user.roles.append(role1.id)
|
|
user.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test dispatch lose access'
|
|
formdef.fields = []
|
|
|
|
wf = Workflow(name='dispatch')
|
|
|
|
st1 = wf.add_status('Status1')
|
|
dispatch = st1.add_action('dispatch', id='_dispatch')
|
|
dispatch.role_key = '_receiver'
|
|
dispatch.role_id = role2.id
|
|
|
|
add_function = st1.add_action('choice', id='_change_function')
|
|
add_function.label = 'Change function'
|
|
add_function.by = ['_receiver']
|
|
add_function.status = st1.id
|
|
|
|
wf.store()
|
|
|
|
formdef.workflow_id = wf.id
|
|
formdef.workflow_roles = {'_receiver': role1.id}
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/%s/%s/' % (formdef.url_name, formdata.id))
|
|
resp = resp.form.submit('button_add_function')
|
|
assert resp.location == '..' # no access -> to listing
|
|
|
|
|
|
def test_backoffice_dispatch_multi(pub):
|
|
user = create_user(pub)
|
|
create_environment(pub)
|
|
|
|
role1 = pub.role_class(name='xxx1')
|
|
role1.store()
|
|
role2 = pub.role_class(name='xxx2')
|
|
role2.store()
|
|
user.roles.append(role1.id)
|
|
user.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test dispatch multi'
|
|
formdef.fields = []
|
|
|
|
wf = Workflow(name='dispatch')
|
|
wf.roles['_foobar'] = 'Foobar'
|
|
|
|
st1 = wf.add_status('Status1')
|
|
dispatch = st1.add_action('dispatch', id='_dispatch')
|
|
dispatch.role_key = '_receiver'
|
|
dispatch.role_id = role2.id
|
|
dispatch.operation_mode = 'add'
|
|
|
|
add_function = st1.add_action('choice', id='_add_function')
|
|
add_function.label = 'Add function'
|
|
add_function.by = ['_receiver']
|
|
add_function.status = st1.id
|
|
|
|
wf.store()
|
|
|
|
formdef.workflow_id = wf.id
|
|
formdef.workflow_roles = {'_receiver': role1.id}
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/%s/%s/' % (formdef.url_name, formdata.id))
|
|
resp = resp.form.submit('button_add_function').follow(status=200) # access to role1 is still ok
|
|
formdata.refresh_from_storage()
|
|
assert formdata.workflow_roles == {'_receiver': [role1.id, role2.id]}
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
'user_template',
|
|
[
|
|
'{{ session_user }}',
|
|
'{{ session_user_email }}',
|
|
'{{ session_user_nameid }}',
|
|
'{{ session_user_name }}',
|
|
'foobar', # a role, not an user
|
|
],
|
|
)
|
|
def test_backoffice_dispatch_single_user(pub, user_template):
|
|
pub.user_class.wipe()
|
|
user = create_user(pub)
|
|
user.name_identifiers = ['0123456789']
|
|
user.store()
|
|
create_environment(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test dispatch user'
|
|
formdef.fields = []
|
|
|
|
wf = Workflow(name='dispatch')
|
|
wf.roles['_foobar'] = 'Foobar'
|
|
|
|
st1 = wf.add_status('Status1')
|
|
dispatch = st1.add_action('dispatch', id='_dispatch')
|
|
dispatch.role_key = '_foobar'
|
|
dispatch.role_id = user_template
|
|
|
|
add_function = st1.add_action('choice', id='_add_function')
|
|
add_function.label = 'Add function'
|
|
add_function.by = ['_receiver']
|
|
add_function.status = st1.id
|
|
|
|
a_button = st1.add_action('choice', id='_a_button')
|
|
a_button.label = 'A button'
|
|
a_button.by = ['_foobar']
|
|
a_button.status = st1.id
|
|
|
|
wf.store()
|
|
|
|
formdef.workflow_id = wf.id
|
|
formdef.workflow_roles = {'_receiver': user.roles[0]}
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/%s/%s/' % (formdef.url_name, formdata.id))
|
|
assert 'button_a_button' not in resp.text
|
|
resp = resp.form.submit('button_add_function').follow(status=200)
|
|
formdata.refresh_from_storage()
|
|
if user_template != 'foobar':
|
|
assert formdata.workflow_roles == {'_foobar': ['_user:%s' % user.id]}
|
|
else:
|
|
# check role are still dispatched by name
|
|
assert formdata.workflow_roles == {'_foobar': [user.roles[0]]}
|
|
|
|
assert 'button_a_button' in resp.text
|