5850 lines
204 KiB
Python
5850 lines
204 KiB
Python
import datetime
|
|
import io
|
|
import os
|
|
import random
|
|
import re
|
|
import time
|
|
import uuid
|
|
import zipfile
|
|
|
|
import pytest
|
|
import responses
|
|
from webtest import Upload
|
|
|
|
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.fields import StringField
|
|
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.sql_criterias import Contains
|
|
from wcs.wf.create_formdata import Mapping
|
|
from wcs.wf.form import WorkflowFormFieldsFormDef
|
|
from wcs.wf.register_comment import JournalEvolutionPart
|
|
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(emails):
|
|
pub = create_temporary_pub()
|
|
|
|
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
|
|
pub.set_app_dir(req)
|
|
pub.cfg['identification'] = {'methods': ['password']}
|
|
pub.cfg['language'] = {'language': 'en'}
|
|
pub.write_cfg()
|
|
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.allows_backoffice_access = True
|
|
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': 'jsonvalue',
|
|
'value': '[{"id": "A", "text": "aa"}, {"id": "B", "text": "bb"}, {"id": "C", "text": "cc"}]',
|
|
}
|
|
|
|
formdef.fields = []
|
|
formdef.store() # make sure sql columns are removed
|
|
|
|
formdef.fields = [
|
|
fields.StringField(
|
|
id='1', label='1st field', display_locations=['validation', 'summary', 'listings']
|
|
),
|
|
fields.ItemField(
|
|
id=str(uuid.uuid4()),
|
|
label='2nd field',
|
|
items=['foo', 'bar', 'baz'],
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.ItemField(id='3', label='3rd field', 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[formdef.fields[1].id] = 'foo'
|
|
formdata.data['%s_display' % formdef.fields[1].id] = 'foo'
|
|
formdata.data['3'] = 'A'
|
|
formdata.data['3_display'] = 'aa'
|
|
elif i % 4 == 1:
|
|
formdata.data[formdef.fields[1].id] = 'bar'
|
|
formdata.data['%s_display' % formdef.fields[1].id] = 'bar'
|
|
formdata.data['3'] = 'B'
|
|
formdata.data['3_display'] = 'bb'
|
|
else:
|
|
formdata.data[formdef.fields[1].id] = 'baz'
|
|
formdata.data['%s_display' % formdef.fields[1].id] = '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_manage_redirect(pub):
|
|
app = get_app(pub)
|
|
assert app.get('/manage', status=302).location == 'http://example.net/backoffice'
|
|
assert app.get('/manage/studio/', status=302).location == 'http://example.net/backoffice/studio/'
|
|
assert (
|
|
app.get('/manage/studio/?param=1', status=302).location
|
|
== 'http://example.net/backoffice/studio/?param=1'
|
|
)
|
|
|
|
|
|
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)
|
|
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 resp.pyquery.find('body.section-management')
|
|
|
|
|
|
def test_backoffice_form_access_forbidden(pub):
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.store()
|
|
user = create_user(pub)
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
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&limit=5&offset=30', status=400)
|
|
resp = app.get('/backoffice/management/form-title/?limit=5&offset=toto', status=400)
|
|
resp = app.get('/backoffice/management/form-title/?limit=5&offset=30&offset=30', 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)
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
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/%s/' % formdata.id)
|
|
assert resp.location == 'http://example.net/backoffice/management/form-title/%s/' % formdata.id
|
|
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)
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
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'
|
|
|
|
# check webservice (external) triggers are not displayed
|
|
action3 = workflow.add_global_action('THIRD ACTION')
|
|
action3.triggers = []
|
|
trigger = action3.append_trigger('webservice')
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
workflow.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
assert 'id="multi-actions"' in resp.text
|
|
assert 'THIRD ACTION' not in resp.text
|
|
|
|
|
|
def test_backoffice_multi_actions_some_status(pub):
|
|
create_superuser(pub)
|
|
Workflow.wipe()
|
|
FormDef.wipe()
|
|
|
|
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.statuses = ['new']
|
|
trigger.roles = ['_receiver']
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
initial_statuses = {}
|
|
for i in range(15):
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
if i < 5:
|
|
formdata.jump_status('accepted')
|
|
elif i % 3 == 0:
|
|
formdata.jump_status('new')
|
|
else:
|
|
formdata.jump_status('finished')
|
|
initial_statuses[str(formdata.id)] = formdata.status
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/?filter=all')
|
|
ids = []
|
|
for checkbox in resp.forms[0].fields['select[]']:
|
|
if checkbox._value == '_all':
|
|
continue
|
|
# check them all
|
|
ids.append(checkbox._value)
|
|
checkbox.checked = True
|
|
|
|
assert len(resp.pyquery('[data-status_new]')) == 3
|
|
assert len(resp.pyquery('[data-status_finished]')) == 7
|
|
assert len(resp.pyquery('[data-status_accepted]')) == 5
|
|
|
|
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
|
|
new_statuses = {str(x.id): x.status for x in formdef.data_class().select()}
|
|
for id in ids:
|
|
# check action was only executed on "new"
|
|
if initial_statuses[id] == 'wf-new':
|
|
assert new_statuses[id] == 'wf-finished'
|
|
else:
|
|
assert new_statuses[id] == initial_statuses[id]
|
|
|
|
resp = app.get('/backoffice/management/form-title/?filter=all')
|
|
assert len(resp.pyquery('[data-status_new]')) == 0
|
|
assert len(resp.pyquery('[data-status_finished]')) == 10
|
|
assert len(resp.pyquery('[data-status_accepted]')) == 5
|
|
|
|
|
|
def test_backoffice_multi_actions_jump(pub):
|
|
create_superuser(pub)
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
|
|
# add identifier to jumps
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
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()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
initial_statuses = {}
|
|
for i in range(15):
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
if i < 5:
|
|
formdata.jump_status('accepted')
|
|
elif i % 3 == 0:
|
|
formdata.jump_status('new')
|
|
else:
|
|
formdata.jump_status('finished')
|
|
initial_statuses[str(formdata.id)] = formdata.status
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/?filter=all')
|
|
assert 'select[]' in resp.forms['multi-actions'].fields
|
|
assert len(resp.pyquery('[data-status_new]')) == 3
|
|
assert len(resp.pyquery('[data-status_finished]')) == 7
|
|
assert len(resp.pyquery('[data-status_accepted]')) == 5
|
|
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[]']:
|
|
if checkbox._value == '_all':
|
|
continue
|
|
# check them all
|
|
ids.append(checkbox._value)
|
|
checkbox.checked = True
|
|
|
|
resp = resp.forms['multi-actions'].submit('button-action-st-new-accept-_accept')
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "Accept" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
|
|
new_statuses = {str(x.id): x.status for x in formdef.data_class().select()}
|
|
for id in ids:
|
|
# check action was only executed on "new"
|
|
if initial_statuses[id] == 'wf-new':
|
|
assert new_statuses[id] == 'wf-accepted'
|
|
else:
|
|
assert new_statuses[id] == initial_statuses[id]
|
|
|
|
resp = app.get('/backoffice/management/form-title/?filter=all')
|
|
assert len(resp.pyquery('[data-status_new]')) == 0
|
|
assert len(resp.pyquery('[data-status_finished]')) == 7
|
|
assert len(resp.pyquery('[data-status_accepted]')) == 8
|
|
|
|
|
|
def test_backoffice_multi_actions_jump_condition(pub):
|
|
create_superuser(pub)
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
# add identifier to jumps
|
|
accept_button = workflow.get_status('new').items[1]
|
|
accept_button.identifier = 'accept'
|
|
workflow.get_status('new').items[2].identifier = 'reject'
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
for i in range(10):
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
if i % 3 == 0:
|
|
formdata.jump_status('finished')
|
|
else:
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp.forms['listing-settings']['filter'] = 'new'
|
|
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
|
|
|
|
checked_ids = []
|
|
for checkbox in resp.forms[0].fields['select[]'][1:6]:
|
|
checked_ids.append(checkbox._value)
|
|
checkbox.checked = True
|
|
|
|
# modify jump to have a condition so it's not executed on some of the checked formdatas
|
|
selected_ids = [checked_ids[1], checked_ids[2]]
|
|
accept_button.condition = {
|
|
'type': 'django',
|
|
'value': 'form_number_raw == "%s" or form_number_raw == "%s"' % tuple(selected_ids),
|
|
}
|
|
workflow.store()
|
|
|
|
resp = resp.forms['multi-actions'].submit('button-action-st-new-accept-_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 checked_ids:
|
|
if id in selected_ids:
|
|
assert formdef.data_class().get(id).status == 'wf-accepted'
|
|
else:
|
|
assert formdef.data_class().get(id).status == 'wf-new'
|
|
|
|
|
|
@pytest.mark.parametrize('target', [None, 'xxx'])
|
|
def test_backoffice_multi_actions_mistarget_jump(pub, target):
|
|
create_superuser(pub)
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
|
|
# add extra jump, with no target
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
jump = workflow.get_status('new').add_action('choice', id='_test')
|
|
jump.label = 'Test'
|
|
jump.identifier = 'test'
|
|
jump.by = ['_receiver']
|
|
jump.status = target
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/?filter=all')
|
|
assert 'select[]' in resp.forms['multi-actions'].fields
|
|
assert len(resp.pyquery.find('#multi-actions div.buttons button')) == 1
|
|
assert resp.pyquery.find('#multi-actions div.buttons button').text() == 'Test'
|
|
|
|
ids = []
|
|
for checkbox in resp.forms[0].fields['select[]']:
|
|
if checkbox._value == '_all':
|
|
continue
|
|
# check them all
|
|
ids.append(checkbox._value)
|
|
checkbox.checked = True
|
|
|
|
resp = resp.forms['multi-actions'].submit('button-action-st-new-test-_test')
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "Test" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
|
|
# check status didn't change
|
|
formdata = formdef.data_class().get(formdata.id)
|
|
assert formdata.get_status().id == 'new'
|
|
|
|
|
|
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_multi_actions_interactive(pub):
|
|
user = create_superuser(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test multi actions interactive'
|
|
formdef.workflow_roles = {'_receiver': user.roles[0]}
|
|
formdef.store()
|
|
|
|
for i in range(10):
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdef.get_url(backoffice=True))
|
|
assert 'id="multi-actions"' in resp.text # always there
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('FOOBAR')
|
|
|
|
form_action = action.add_action('form')
|
|
form_action.varname = 'blah'
|
|
form_action.formdef = WorkflowFormFieldsFormDef(item=form_action)
|
|
form_action.formdef.fields.append(fields.StringField(id='1', label='Test', varname='test', required=True))
|
|
form_action.hide_submit_button = False
|
|
register_comment = action.add_action('register-comment')
|
|
register_comment.comment = 'HELLO {{ 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(formdef.get_url(backoffice=True))
|
|
assert 'id="multi-actions"' in resp.text
|
|
for checkbox in resp.forms[0].fields['select[]'][1:6]:
|
|
checkbox.checked = True
|
|
resp = resp.forms[0].submit('button-action-1')
|
|
assert '/actions/' in resp.location
|
|
resp = resp.follow()
|
|
resp = resp.follow() # back to form listing
|
|
assert 'Error: empty action' in resp.text
|
|
|
|
form_action.by = trigger.roles
|
|
workflow.store()
|
|
|
|
resp = app.get(formdef.get_url(backoffice=True) + '?limit=20')
|
|
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 '/actions/' in resp.location
|
|
resp = resp.follow()
|
|
assert '5 selected forms' in resp.text
|
|
resp = resp.form.submit('submit')
|
|
assert resp.pyquery('#form_error_fblah_1').text() == 'required field'
|
|
resp.form['fblah_1'] = 'GLOBAL INTERACTIVE ACTION'
|
|
resp = resp.form.submit('submit')
|
|
|
|
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/test-multi-actions-interactive/?limit=20'
|
|
)
|
|
for formdata in formdef.data_class().select():
|
|
pub.substitutions.reset()
|
|
pub.substitutions.feed(formdata)
|
|
context = pub.substitutions.get_context_variables(mode='lazy')
|
|
if str(formdata.id) in ids:
|
|
assert context['form_workflow_form_blah_var_test'].get_value() == 'GLOBAL INTERACTIVE ACTION'
|
|
history_message = [
|
|
x for x in formdata.iter_evolution_parts() if isinstance(x, JournalEvolutionPart)
|
|
][-1]
|
|
assert 'HELLO admin' in history_message.content
|
|
else:
|
|
with pytest.raises(KeyError):
|
|
assert context['form_workflow_form_blah_var_test']
|
|
|
|
# check for various conditions for directory errors
|
|
resp = app.get(formdef.get_url(backoffice=True) + '?limit=20')
|
|
resp.forms[0].fields['select[]'][1].checked = True
|
|
resp = resp.forms[0].submit('button-action-1')
|
|
token = pub.token_class.get(resp.headers['location'].split('/')[-2])
|
|
token.context['form_type'] = 'xxx'
|
|
token.store()
|
|
app.get(resp.headers['location'], status=404)
|
|
token.context['form_type'] = 'formdef'
|
|
token.context['form_ids'] = [formdata.id + 100] # missing
|
|
token.store()
|
|
app.get(resp.headers['location'], status=404)
|
|
token.context['form_ids'] = [formdata.id]
|
|
token.context['action_id'] = 'xxx'
|
|
token.store()
|
|
app.get(resp.headers['location'], status=404)
|
|
|
|
|
|
def test_backoffice_multi_actions_interactive_create_carddata(pub):
|
|
user = create_superuser(pub)
|
|
|
|
carddef = CardDef()
|
|
carddef.name = 'My card'
|
|
carddef.fields = [
|
|
fields.StringField(id='1', label='string'),
|
|
]
|
|
carddef.store()
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('FOOBAR')
|
|
|
|
form_action = action.add_action('form')
|
|
form_action.varname = 'blah'
|
|
form_action.formdef = WorkflowFormFieldsFormDef(item=form_action)
|
|
form_action.formdef.fields.append(fields.StringField(id='1', label='Test', varname='test', required=True))
|
|
form_action.hide_submit_button = False
|
|
|
|
create_card = action.add_action('create_carddata')
|
|
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='{{ form_var_test }} - {{form_workflow_form_blah_var_test}}'),
|
|
]
|
|
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
form_action.by = trigger.roles
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test multi actions interactive create carddata'
|
|
formdef.fields = [fields.StringField(id='1', label='test', varname='test')]
|
|
formdef.workflow_roles = {'_receiver': user.roles[0]}
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
|
|
for i in range(10):
|
|
formdata = formdef.data_class()()
|
|
formdata.data['1'] = 'Foo %s' % i
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdef.get_url(backoffice=True))
|
|
assert 'id="multi-actions"' in resp.text # always there
|
|
|
|
resp = app.get(formdef.get_url(backoffice=True) + '?limit=20&order_by=id')
|
|
for checkbox in resp.forms[0].fields['select[]'][1:6]:
|
|
checkbox.checked = True
|
|
|
|
resp = resp.forms[0].submit('button-action-1')
|
|
assert '/actions/' in resp.location
|
|
resp = resp.follow()
|
|
assert '5 selected forms' in resp.text
|
|
resp.form['fblah_1'] = 'GLOBAL'
|
|
resp = resp.form.submit('submit')
|
|
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "FOOBAR" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
|
|
assert {x.data['1'] for x in carddef.data_class().select()} == {
|
|
'Foo 0 - GLOBAL',
|
|
'Foo 1 - GLOBAL',
|
|
'Foo 2 - GLOBAL',
|
|
'Foo 3 - GLOBAL',
|
|
'Foo 4 - GLOBAL',
|
|
}
|
|
|
|
|
|
@pytest.mark.parametrize('upload_mode', ['no_ajax', 'ajax'])
|
|
def test_backoffice_multi_actions_interactive_file_field(pub, upload_mode):
|
|
user = create_superuser(pub)
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('FOOBAR')
|
|
|
|
form_action = action.add_action('form')
|
|
form_action.varname = 'blah'
|
|
form_action.formdef = WorkflowFormFieldsFormDef(item=form_action)
|
|
form_action.formdef.fields.append(fields.FileField(id='1', label='Test', varname='test', required=True))
|
|
form_action.hide_submit_button = False
|
|
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
form_action.by = trigger.roles
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test multi actions interactive file field'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': user.roles[0]}
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
|
|
for i in range(10):
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdef.get_url(backoffice=True))
|
|
assert 'id="multi-actions"' in resp.text # always there
|
|
|
|
resp = app.get(formdef.get_url(backoffice=True) + '?limit=20&order_by=id')
|
|
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 '/actions/' in resp.location
|
|
resp = resp.follow()
|
|
assert '5 selected forms' in resp.text
|
|
resp.form['fblah_1$file'] = Upload('test3.txt', b'foobar3', 'text/plain')
|
|
if upload_mode == 'ajax':
|
|
# this part is actually done in javascript
|
|
upload_url = resp.form['fblah_1$file'].attrs['data-url']
|
|
upload_resp = app.post(upload_url, params=resp.form.submit_fields())
|
|
resp.form['fblah_1$file'] = None
|
|
resp.form['fblah_1$token'] = upload_resp.json[0]['token']
|
|
|
|
resp = resp.form.submit('submit')
|
|
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "FOOBAR" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
|
|
for formdata in formdef.data_class().select([Contains('id', ids)]):
|
|
assert (
|
|
formdata.get_substitution_variables()['form'].workflow_form.blah.var.test.raw.get_content()
|
|
== b'foobar3'
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize('mode', ['no_prefill', 'prefill'])
|
|
def test_backoffice_multi_actions_interactive_items_field(pub, mode):
|
|
user = create_superuser(pub)
|
|
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('FOOBAR')
|
|
|
|
form_action = action.add_action('form')
|
|
form_action.varname = 'blah'
|
|
form_action.formdef = WorkflowFormFieldsFormDef(item=form_action)
|
|
form_action.formdef.fields = [
|
|
fields.ItemsField(id='1', label='Test', varname='test', required=True, items=['foo', 'bar', 'baz'])
|
|
]
|
|
if mode == 'prefill':
|
|
form_action.formdef.fields[0].prefill = {'type': 'string', 'value': 'baz'}
|
|
|
|
form_action.hide_submit_button = False
|
|
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
form_action.by = trigger.roles
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test multi actions interactive items field'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': user.roles[0]}
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
|
|
for i in range(10):
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdef.get_url(backoffice=True))
|
|
assert 'id="multi-actions"' in resp.text # always there
|
|
|
|
resp = app.get(formdef.get_url(backoffice=True) + '?limit=20&order_by=id')
|
|
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 '/actions/' in resp.location
|
|
resp = resp.follow()
|
|
assert '5 selected forms' in resp.text
|
|
if mode == 'prefill':
|
|
assert resp.form['fblah_1$element2'].checked is True
|
|
else:
|
|
assert resp.form['fblah_1$element2'].checked is False
|
|
resp.form['fblah_1$element0'].checked = True
|
|
resp.form['fblah_1$element1'].checked = True
|
|
resp.form['fblah_1$element2'].checked = False
|
|
resp = resp.form.submit('submit')
|
|
|
|
assert '?job=' in resp.location
|
|
resp = resp.follow()
|
|
assert 'Executing task "FOOBAR" on forms' in resp.text
|
|
assert '>completed<' in resp.text
|
|
|
|
for formdata in formdef.data_class().select([Contains('id', ids)]):
|
|
assert formdata.get_substitution_variables()['form'].workflow_form.blah.var.test.raw == ['foo', 'bar']
|
|
|
|
|
|
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'))
|
|
formdef.fields.append(fields.MapField(id='5', label='5th field'))
|
|
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)
|
|
|
|
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):
|
|
user = create_user(pub)
|
|
|
|
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 = FormDef()
|
|
formdef.name = 'test global remove'
|
|
formdef.fields = []
|
|
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
|
|
|
|
carddef = CardDef()
|
|
carddef.name = 'test global remove'
|
|
carddef.fields = []
|
|
carddef.workflow_id = workflow.id
|
|
carddef.workflow_roles = {'_editor': user.roles[0]}
|
|
carddef.store()
|
|
|
|
carddata = carddef.data_class()()
|
|
carddata.just_created()
|
|
carddata.jump_status('new')
|
|
carddata.user_id = user.id
|
|
carddata.store()
|
|
|
|
resp = app.get('/backoffice/data/%s/%s/' % (carddef.url_name, carddata.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/data/test-global-remove/'
|
|
assert 'The card has been deleted.' in resp.text
|
|
|
|
|
|
def test_backoffice_global_action_jump_to_current_status(pub):
|
|
create_user(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.store()
|
|
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_global_interactive_action(pub):
|
|
create_user(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test global action'
|
|
formdef.fields = [
|
|
fields.StringField(id='1', label='1st field', varname='foo'),
|
|
]
|
|
workflow = Workflow.get_default_workflow()
|
|
workflow.id = '2'
|
|
action = workflow.add_global_action('FOOBAR')
|
|
|
|
display = action.add_action('displaymsg')
|
|
display.message = 'This is a message'
|
|
display.to = []
|
|
|
|
form_action = action.add_action('form')
|
|
form_action.varname = 'blah'
|
|
form_action.formdef = WorkflowFormFieldsFormDef(item=form_action)
|
|
form_action.formdef.fields.append(
|
|
fields.StringField(
|
|
id='1',
|
|
label='Test',
|
|
varname='test',
|
|
required=True,
|
|
prefill={'type': 'string', 'value': 'a{{form_var_foo}}b'},
|
|
),
|
|
)
|
|
form_action.hide_submit_button = False
|
|
register_comment = action.add_action('register-comment')
|
|
register_comment.comment = 'HELLO {{ form_workflow_form_blah_var_test }}'
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
|
|
button1 = action.add_action('choice')
|
|
button1.label = 'button1'
|
|
button1.condition = {'type': 'django', 'value': 'form_var_foo != "plop"'}
|
|
|
|
button2 = action.add_action('choice')
|
|
button2.label = 'button2'
|
|
button2.condition = {'type': 'django', 'value': 'form_var_foo == "plop"'}
|
|
|
|
workflow.store()
|
|
formdef.workflow_id = workflow.id
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'1': 'plop'}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert 'button-action-1' in resp.form.fields
|
|
resp = resp.form.submit('button-action-1')
|
|
resp = resp.follow() # -> error, empty action
|
|
resp = resp.follow() # -> back to form
|
|
assert 'Error: empty action' in resp.text
|
|
|
|
button1.by = trigger.roles
|
|
button2.by = trigger.roles
|
|
form_action.by = trigger.roles
|
|
workflow.store()
|
|
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
resp = resp.form.submit('button-action-1')
|
|
resp = resp.follow()
|
|
assert 'This is a message' in resp.text
|
|
assert resp.form['fblah_1'].value == 'aplopb' # field was prefilled
|
|
resp.form['fblah_1'] = ''
|
|
assert not resp.pyquery('button[value="button1"]') # not displayed
|
|
assert resp.pyquery('button[value="button2"]') # displayed
|
|
resp = resp.form.submit('submit')
|
|
# error as the field was empty
|
|
assert resp.pyquery('#form_error_fblah_1').text() == 'required field'
|
|
resp.form['fblah_1'] = 'GLOBAL INTERACTIVE ACTION'
|
|
resp = resp.form.submit('submit')
|
|
assert resp.location == formdata.get_url(backoffice=True)
|
|
resp = resp.follow()
|
|
|
|
assert 'HELLO GLOBAL INTERACTIVE ACTION' in resp.text
|
|
|
|
|
|
def test_backoffice_global_interactive_action_manual_jump(pub):
|
|
create_user(pub)
|
|
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'test global action'
|
|
formdef.fields = []
|
|
workflow = Workflow(name='test global action jump')
|
|
workflow.add_status('st1')
|
|
st2 = workflow.add_status('st2')
|
|
|
|
register_comment = st2.add_action('register-comment')
|
|
register_comment.comment = 'HELLO'
|
|
|
|
action = workflow.add_global_action('FOOBAR')
|
|
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
|
|
button = action.add_action('choice')
|
|
button.label = 'button'
|
|
button.status = str(st2.id)
|
|
button.by = trigger.roles
|
|
|
|
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(formdata.get_url(backoffice=True))
|
|
resp = resp.form.submit('button-action-1')
|
|
resp = resp.follow()
|
|
resp = resp.form.submit('button1')
|
|
assert resp.location == formdata.get_url(backoffice=True)
|
|
resp = resp.follow()
|
|
|
|
assert 'HELLO' in resp.text
|
|
|
|
|
|
def test_backoffice_global_interactive_action_auto_jump(pub):
|
|
create_user(pub)
|
|
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'test global action'
|
|
formdef.fields = []
|
|
workflow = Workflow(name='test global action jump')
|
|
workflow.add_status('st1')
|
|
st2 = workflow.add_status('st2')
|
|
|
|
register_comment = st2.add_action('register-comment')
|
|
register_comment.comment = 'HELLO'
|
|
|
|
action = workflow.add_global_action('FOOBAR')
|
|
|
|
trigger = action.triggers[0]
|
|
trigger.roles = [x.id for x in pub.role_class.select() if x.name == 'foobar']
|
|
|
|
commentable = action.add_action('commentable')
|
|
commentable.by = trigger.roles
|
|
commentable.button_label = 'CLICK ME!'
|
|
|
|
jump = action.add_action('jump')
|
|
jump.by = trigger.roles
|
|
jump.status = str(st2.id)
|
|
|
|
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(formdata.get_url(backoffice=True))
|
|
resp = resp.form.submit('button-action-1')
|
|
resp = resp.follow()
|
|
resp = resp.form.submit('button1')
|
|
assert resp.location == formdata.get_url(backoffice=True)
|
|
resp = resp.follow()
|
|
|
|
assert 'HELLO' in resp.text
|
|
|
|
|
|
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'))
|
|
formdef.fields.append(fields.FileField(id='5', label='file2 field'))
|
|
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
|
|
|
|
# check proper escaping
|
|
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
|
|
|
|
pub.cfg['users'] = {'sidebar_template': '<b>{{ form_user_display_name }}</b>YYY'}
|
|
pub.write_cfg()
|
|
resp = app.get(resp.request.url)
|
|
assert '<p><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.allows_backoffice_access = True
|
|
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'),
|
|
]
|
|
|
|
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()
|
|
field1 = formdef.fields[1]
|
|
|
|
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['f%s' % field1.id].value == number31.data[field1.id]
|
|
assert resp.form['f3'].value == number31.data['3']
|
|
assert 'value="Save Changes"' in resp.text
|
|
resp.form['f%s' % field1.id].value = 'bar'
|
|
resp = resp.form.submit('submit')
|
|
resp = resp.follow()
|
|
assert form_class().get(number31.id).data[field1.id] == '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()
|
|
field1 = formdef.fields[1]
|
|
|
|
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['f%s' % field1.id].value = 'bar'
|
|
resp = resp.form.submit('submit')
|
|
resp = resp.follow()
|
|
assert form_class().get(number31.id).data[field1.id] == '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'))
|
|
formdef.fields.append(fields.PageField(id='4', label='2nd 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()
|
|
field1 = formdef.fields[1]
|
|
|
|
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['f%s' % field1.id].value == number31.data[field1.id]
|
|
assert resp.form['f3'].value == number31.data['3']
|
|
resp.form['f%s' % field1.id].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[field1.id] == '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()
|
|
field1 = formdef.fields[1]
|
|
|
|
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['f%s' % field1.id].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', 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()
|
|
field1 = formdef.fields[1]
|
|
|
|
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['f%s' % field1.id].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 responses.RequestsMock() as rsps:
|
|
rsps.get(
|
|
'https://www.example.invalid/',
|
|
json={'data': [{'id': 'A', 'text': 'hello'}, {'id': 'B', 'text': 'world'}]},
|
|
)
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert len(rsps.calls) == 1
|
|
assert '?name_id=admin' in rsps.calls[-1].request.url
|
|
resp.form['f3'].value = 'A'
|
|
resp = resp.form.submit('submit')
|
|
assert len(rsps.calls) == 2
|
|
assert '?name_id=admin' in rsps.calls[-1].request.url
|
|
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 responses.RequestsMock() as rsps:
|
|
rsps.get(
|
|
'https://www.example.invalid/',
|
|
json={'data': [{'id': 'A', 'text': 'hello'}, {'id': 'B', 'text': 'world'}]},
|
|
)
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert len(rsps.calls) == 1
|
|
assert '?test=foobar' in rsps.calls[-1].request.url
|
|
resp.form['f3'].value = 'A'
|
|
resp = resp.form.submit('submit')
|
|
assert len(rsps.calls) == 2
|
|
assert '?test=foobar' in rsps.calls[-1].request.url
|
|
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 responses.RequestsMock() as rsps:
|
|
rsps.get(
|
|
'https://www.example.invalid/',
|
|
json={'data': [{'id': 'DD', 'text': 'DD'}, {'id': 'EE', 'text': 'EE'}]},
|
|
)
|
|
|
|
resp = app.get('/backoffice/management/form-title/%s/' % number31.id)
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert len(rsps.calls) == 1
|
|
assert '?xxx=FOO%20BAR%2030' in rsps.calls[-1].request.url
|
|
assert len(resp.pyquery('.error:not(#form_error_fieldname)')) == 0
|
|
assert resp.form['f3'].value == 'EE'
|
|
resp.form['f3'].value = 'DD'
|
|
resp = resp.form.submit('submit')
|
|
assert len(rsps.calls) == 2
|
|
assert '?xxx=FOO%20BAR%2030' in rsps.calls[-1].request.url
|
|
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'))
|
|
formdef.fields.append(fields.PageField(id='4', label='2nd 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()
|
|
field1 = formdef.fields[1]
|
|
|
|
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'][field1.id]['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'][field1.id]['visible']
|
|
|
|
|
|
def test_backoffice_wfedit_and_prefill_with_user_variable(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"'}
|
|
formdef.fields.append(
|
|
fields.StringField(
|
|
id='100',
|
|
label='user name',
|
|
prefill={'type': 'string', 'value': 'a{{form_user_name}}b'},
|
|
)
|
|
)
|
|
formdef.store()
|
|
|
|
form_class = formdef.data_class()
|
|
|
|
second_user = pub.user_class(name='foobar')
|
|
second_user.store()
|
|
number31 = [x for x in form_class.select() if x.data['1'] == 'FOO BAR 30'][0]
|
|
number31.user_id = second_user.id
|
|
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)
|
|
resp = resp.form.submit('button_wfedit').follow()
|
|
assert resp.form['f100'].value == 'afoobarb'
|
|
|
|
live_url = resp.html.find('form').attrs['data-live-url']
|
|
live_resp = app.post(live_url + '?prefilled_100=on', params=resp.form.submit_fields())
|
|
assert live_resp.json['result']['100']['content'] == 'afoobarb'
|
|
|
|
|
|
def test_backoffice_wfedit_and_category(pub):
|
|
user = create_user(pub)
|
|
Category.wipe()
|
|
|
|
workflow = Workflow(name='wfedit')
|
|
st1 = workflow.add_status('Status1')
|
|
wfedit = st1.add_action('editable', id='_wfedit')
|
|
wfedit.by = [user.roles[0]]
|
|
workflow.store()
|
|
|
|
cat1 = Category(name='cat1')
|
|
cat1.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.category_id = cat1.id
|
|
formdef.name = 'test_backoffice_wfedit_and_category'
|
|
formdef.fields = [fields.StringField(id='1', label='1st field')]
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'1': 'blah'}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
resp = resp.form.submit('button_wfedit')
|
|
resp = resp.follow()
|
|
assert resp.form['f1'].value == 'blah'
|
|
|
|
|
|
def test_backoffice_wfedit_single_page(pub):
|
|
user = create_user(pub)
|
|
|
|
workflow = Workflow(name='test')
|
|
st1 = workflow.add_status('Status1', 'st1')
|
|
editable = st1.add_action('editable', id='_editable')
|
|
editable.by = ['_receiver']
|
|
editable.operation_mode = 'single'
|
|
editable.page_identifier = 'plop'
|
|
workflow.store()
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'test'
|
|
formdef.fields = []
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
formdef.fields = [
|
|
fields.PageField(id='1', label='1st page'),
|
|
fields.StringField(id='2', label='field1'),
|
|
fields.PageField(id='3', label='2nd page', varname='plop'),
|
|
fields.StringField(id='4', label='field2'),
|
|
fields.StringField(
|
|
id='5', label='field2b', condition={'type': 'django', 'value': 'not is_in_backoffice'}
|
|
),
|
|
fields.PageField(id='6', label='3rd page'),
|
|
fields.StringField(
|
|
id='7', label='field3', condition={'type': 'django', 'value': 'not is_in_backoffice'}
|
|
),
|
|
]
|
|
formdef.workflow_id = workflow.id
|
|
formdef.workflow_roles = {'_receiver': user.roles[0]}
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'2': 'a', '4': 'b', '5': 'b2', '7': 'c'}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
|
|
resp = app.get(formdata.get_backoffice_url())
|
|
resp = resp.form.submit('button_editable').follow()
|
|
assert [x.text for x in resp.pyquery('#steps .label')] == ['2nd page']
|
|
resp.form['f4'] = 'changed'
|
|
resp = resp.form.submit('submit')
|
|
formdata.refresh_from_storage()
|
|
assert formdata.data == {'2': 'a', '4': 'changed', '5': None, '7': 'c'}
|
|
|
|
|
|
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)
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
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'
|
|
|
|
|
|
@pytest.mark.parametrize('settings_mode', ['new', 'legacy'])
|
|
def test_global_listing_user_label(pub, settings_mode):
|
|
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', varname='first_name'))
|
|
user_formdef.fields.append(fields.StringField(id='4', label='last_name', varname='last_name'))
|
|
user_formdef.store()
|
|
if settings_mode == 'new':
|
|
pub.cfg['users']['fullname_template'] = '{{ user_var_first_name }} {{ user_var_last_name }}'
|
|
else:
|
|
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)
|
|
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
|
|
|
|
resp = app.get('/backoffice/management/listing?category_ids$element0=foo')
|
|
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
|
|
|
|
|
|
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.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.geolocations = {'base': 'Geolocafoobar'}
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
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)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.enable_tracking_codes = True
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata2 = formdef.data_class()()
|
|
formdata2.just_created()
|
|
formdata2.store()
|
|
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>'
|
|
|
|
# error in lateral template
|
|
formdef.lateral_template = 'XX{% for %}XX'
|
|
formdef.store()
|
|
|
|
pub.loggederror_class.wipe()
|
|
partial_resp = app.get(lateral_block_url)
|
|
assert partial_resp.text == ''
|
|
assert pub.loggederror_class.count() == 1
|
|
assert (
|
|
pub.loggederror_class.select()[0].summary
|
|
== "Could not render lateral template (syntax error in Django template: 'for' statements should have at least four words: for)"
|
|
)
|
|
|
|
|
|
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)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.StringField(
|
|
id='1', label='1st field', display_locations=['validation', 'summary', 'listings']
|
|
),
|
|
]
|
|
formdef.backoffice_submission_roles = user.roles[:]
|
|
formdef.store()
|
|
|
|
for i in range(3):
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'1': 'foo'}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
resp = login(get_app(pub)).get('/backoffice/submission/count')
|
|
assert resp.json['count'] == 0
|
|
|
|
formdata1, formdata2, formdata3 = formdef.data_class().select()
|
|
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):
|
|
FormDef.wipe()
|
|
create_user(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 resp.pyquery('#summary.section.foldable:not(.folded)')
|
|
# do something: summary is folded
|
|
resp = resp.form.submit('button_commentable')
|
|
resp = resp.follow()
|
|
assert resp.pyquery('#summary.section.foldable.folded')
|
|
|
|
|
|
def test_backoffice_backoffice_submission_in_listings(pub):
|
|
create_superuser(pub)
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
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/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)
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
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=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)
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
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)
|
|
|
|
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.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.StringField(id='1', label='1st field', varname='foo'),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
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', 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', 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',
|
|
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', required=True),
|
|
fields.StringField(id='2', label='Test2', varname='str2', 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', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
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', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
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', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
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', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
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', required=True),
|
|
fields.ItemField(
|
|
id='2',
|
|
label='Test2',
|
|
varname='str2',
|
|
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 responses.RequestsMock() as rsps:
|
|
rsps.get(
|
|
'https://www.example.invalid/',
|
|
json={'data': [{'id': 'A', 'text': 'hello'}, {'id': 'B', 'text': 'world'}]},
|
|
)
|
|
rsps.get(
|
|
'https://www.example.invalid/toto',
|
|
json={'data': [{'id': 'C', 'text': 'hello'}, {'id': 'D', 'text': 'world'}]},
|
|
)
|
|
|
|
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'),
|
|
]
|
|
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', required=True),
|
|
fields.BlockField(id='2', label='Blocks', block_slug='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.hide_submit_button = False
|
|
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
|
|
display_form.formdef.fields.append(fields.StringField(id='1', label='Test', varname='str', 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)
|
|
|
|
wf = Workflow(name='bo fields')
|
|
wf.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(wf)
|
|
wf.backoffice_fields_formdef.fields = [
|
|
fields.StringField(id='bo1', label='1st backoffice field', varname='backoffice_blah', required=False),
|
|
]
|
|
wf.add_status('Status1')
|
|
wf.store()
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
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', 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)
|
|
|
|
FormDef.wipe()
|
|
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'),
|
|
]
|
|
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'),
|
|
]
|
|
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
|
|
'''
|
|
)
|
|
|
|
FormDef.wipe()
|
|
user = create_user(pub)
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test'
|
|
formdef.backoffice_submission_roles = user.roles[:]
|
|
formdef.fields = [
|
|
fields.CommentField(id='7', label='X[session_var_foo]Y'),
|
|
]
|
|
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'),
|
|
]
|
|
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)
|
|
|
|
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.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.workflow = workflow
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {}
|
|
formdata.just_created()
|
|
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)
|
|
|
|
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.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
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', required=True),
|
|
fields.StringField(
|
|
id='2',
|
|
label='Test 2',
|
|
varname='str2',
|
|
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', 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', 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', varname='file1'),
|
|
fields.StringField(id='2', label='string', varname='string2', required=False),
|
|
fields.FileField(id='3', label='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', varname='file1'),
|
|
fields.StringField(id='2', label='string', varname='string2', required=False),
|
|
fields.FileField(id='3', label='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
|
|
create_formdata['source_formdef'].digest_templates = {'default': 'blah'}
|
|
create_formdata['source_formdef'].store()
|
|
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()
|
|
# check parent form is displayed in sidebar
|
|
assert resp.pyquery('.extra-context--orig-data').attr.href == formdata.get_backoffice_url()
|
|
assert resp.pyquery('.extra-context--orig-data').text() == 'source form #1-1 (blah)'
|
|
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)
|
|
|
|
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.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
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)
|
|
|
|
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)
|
|
|
|
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()
|
|
|
|
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
|
|
|
|
|
|
def test_backoffice_workflow_form_file_access(pub):
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
|
|
role = pub.role_class(name='xxx1')
|
|
role.store()
|
|
|
|
user = create_superuser(pub)
|
|
user.roles.append(role.id)
|
|
user.store()
|
|
|
|
wf = Workflow(name='test')
|
|
status = wf.add_status('New', 'st1')
|
|
next_status = wf.add_status('Next', 'st2')
|
|
|
|
status.items = []
|
|
display_form = status.add_action('form', id='_display_form')
|
|
display_form.by = ['_receiver']
|
|
display_form.varname = 'blah'
|
|
display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
|
|
display_form.formdef.fields = [
|
|
fields.FileField(id='1', label='test', varname='file'),
|
|
fields.StringField(id='2', label='test2', required=True),
|
|
]
|
|
|
|
jump = status.add_action('jumponsubmit', id='_jump')
|
|
jump.status = next_status.id
|
|
|
|
wf.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test'
|
|
formdef.workflow_id = wf.id
|
|
formdef.workflow_roles = {'_receiver': role.id}
|
|
formdef.fields = []
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
resp.form['fblah_1$file'] = Upload('test3.txt', b'foobar3', 'text/plain')
|
|
resp = resp.form.submit('submit')
|
|
# it will fail on the equired string field; this allows testing
|
|
# the temporary file URL.
|
|
assert resp.click('test3.txt').body == b'foobar3'
|
|
|
|
|
|
def test_backoffice_block_empty_value(pub):
|
|
user = create_user(pub)
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
BlockDef.wipe()
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test1', varname='t1'),
|
|
fields.StringField(id='234', required=False, label='Test2', varname='t2'),
|
|
]
|
|
block.store()
|
|
|
|
workflow = Workflow(name='test')
|
|
workflow.roles = {'_receiver': 'Recipient'}
|
|
workflow.add_status('new')
|
|
|
|
workflow.backoffice_fields_formdef = WorkflowBackofficeFieldsFormDef(workflow)
|
|
workflow.backoffice_fields_formdef.fields = [
|
|
fields.BlockField(
|
|
id='bo1', label='Blocks', required=True, block_slug='foobar', max_items=1, varname='bo'
|
|
),
|
|
]
|
|
workflow.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.name = 'test'
|
|
formdef.workflow_roles = {'_receiver': user.roles[0]}
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='Blocks', block_slug='foobar', max_items=3),
|
|
]
|
|
formdef.workflow_id = workflow.id
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
app = login(get_app(pub))
|
|
resp = app.get(formdef.get_url())
|
|
resp.form['f1$element0$f123'] = 'foo'
|
|
resp.form['f1$element0$f234'] = 'bar'
|
|
resp = resp.form.submit('f1$add_element')
|
|
resp.form['f1$element1$f123'] = 'baz'
|
|
resp = resp.form.submit('submit') # -> validation
|
|
resp = resp.form.submit('submit').follow()
|
|
formdata_id = resp.request.url.strip('/').split('/')[-1]
|
|
# check the three values are displayed, but nothing for second field of second row
|
|
assert resp.pyquery('.field-type-block .value .value').text() == 'foo bar baz'
|
|
|
|
formdata = formdef.data_class().get(formdata_id)
|
|
formdata.data['bo1'] = formdata.data['1']
|
|
formdata.data['bo1_display'] = formdata.data['1_display']
|
|
formdata.store()
|
|
|
|
# check it behaves the same in backoffice, and for backoffice data
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
# form data
|
|
assert (
|
|
resp.pyquery('.section.foldable.folded .dataview .field-type-block .value .value').text()
|
|
== 'foo bar baz'
|
|
)
|
|
# backoffice data
|
|
assert (
|
|
resp.pyquery('.section.foldable:not(.folded) .dataview .field-type-block .value .value').text()
|
|
== 'foo bar baz'
|
|
)
|
|
|
|
# check it displays "Not set", for backoffice data for unset required fields
|
|
block.fields[1].required = True
|
|
block.store()
|
|
resp = app.get(formdata.get_url(backoffice=True))
|
|
assert (
|
|
resp.pyquery('.section.foldable.folded .dataview .field-type-block .value .value').text()
|
|
== 'foo bar baz'
|
|
)
|
|
assert (
|
|
resp.pyquery('.section.foldable:not(.folded) .dataview .field-type-block .value .value').text()
|
|
== 'foo bar baz Not set'
|
|
)
|
|
|
|
|
|
def test_webservice_call_error_handling_with_marker(http_requests, pub):
|
|
create_user(pub)
|
|
create_environment(pub)
|
|
app = login(get_app(pub))
|
|
|
|
Workflow.wipe()
|
|
wf = Workflow(name='error with marker')
|
|
st1 = wf.add_status('One')
|
|
st1.id = 'one'
|
|
st2 = wf.add_status('Two')
|
|
st2.id = 'two'
|
|
ws_call = st1.add_action('webservice_call')
|
|
ws_call.label = 'wscall'
|
|
ws_call.url = 'http://remote.example.net/connection-error'
|
|
ws_call.action_on_network_errors = st2.id
|
|
ws_call.set_marker_on_status = True
|
|
jump = st2.add_action('choice', id=str(random.random()))
|
|
jump.label = 'back'
|
|
jump.by = ['logged-users']
|
|
jump.status = '_previous'
|
|
wf.store()
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'baz'
|
|
formdef.fields = []
|
|
formdef.workflow = wf
|
|
formdef.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
formdata.store()
|
|
|
|
assert formdata.status == 'wf-two'
|
|
resp = app.get('/backoffice/management/baz/%s/' % formdata.id)
|
|
# jump back
|
|
resp = resp.form.submit('button%s' % jump.id).follow()
|
|
formdata.refresh_from_storage()
|
|
assert formdata.status == 'wf-two'
|
|
evolutions = formdata.evolution
|
|
assert len(evolutions) == 4
|
|
assert evolutions[0].status == 'wf-one'
|
|
assert evolutions[1].status == 'wf-two'
|
|
# jump back occured here
|
|
assert evolutions[2].status == 'wf-one'
|
|
# error handling of wscall
|
|
assert evolutions[3].status == 'wf-two'
|
|
|
|
|
|
def test_anonymise_action_intermediate(pub):
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
|
|
role = pub.role_class(name='xxx')
|
|
role.store()
|
|
user = create_user(pub, is_admin=True)
|
|
user.name = 'Foo Bar'
|
|
user.email = 'foo@example.com'
|
|
user.roles.append(role.id)
|
|
user.store()
|
|
|
|
wf = Workflow(name='anonymise-action-intermediate')
|
|
wf.id = '1'
|
|
wf.roles = {'_receiver': role.id}
|
|
anonymise_intermediate_status = wf.add_status('anonymise_intermediate', id='anonymise_intermediate')
|
|
anonymise_intermediate_status.visibility = ['_receiver']
|
|
anonymise_final_status = wf.add_status('anonymise_final', id='anonymise_final')
|
|
anonymise_final_status.visibility = ['_receiver']
|
|
|
|
anonymise_intermediate_action = anonymise_intermediate_status.add_action(
|
|
'anonymise', id='_anonymise', prepend=True
|
|
)
|
|
anonymise_intermediate_action.label = 'Intermediate anonymisation'
|
|
anonymise_intermediate_action.mode = 'intermediate'
|
|
jump_to_anonymise_final = anonymise_intermediate_status.add_action('choice', id='_to_anonymise_final')
|
|
jump_to_anonymise_final.by = ['_receiver']
|
|
jump_to_anonymise_final.status = anonymise_final_status.id
|
|
jump_to_anonymise_final.label = 'choice'
|
|
jump_to_anonymise_final.identifier = 'id1'
|
|
|
|
anonymise_final_action = anonymise_final_status.add_action('anonymise', id='_anonymise', prepend=True)
|
|
anonymise_final_action.label = 'Final anonymisation'
|
|
anonymise_final_action.mode = 'final'
|
|
wf.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.id = '1'
|
|
formdef.workflow_roles = {'_receiver': role.id}
|
|
formdef.name = 'Foo'
|
|
formdef.workflow_id = wf.id
|
|
formdef.fields = [
|
|
StringField(id='0', label='string', anonymise='intermediate', varname='inter'),
|
|
StringField(id='1', label='string', anonymise='final', varname='final'),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'0': 'Foo', '1': 'Bar'}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.status == 'wf-anonymise_intermediate'
|
|
assert formdata.data == {'0': None, '1': 'Bar'}
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/foo/%s/' % formdata.id)
|
|
resp = resp.form.submit('button_to_anonymise_final')
|
|
resp = resp.follow()
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.status == 'wf-anonymise_final'
|
|
assert formdata.data == {'0': None, '1': None}
|
|
|
|
|
|
def test_anonymise_action_final_also_deletes_fields_with_intermediate(pub):
|
|
FormDef.wipe()
|
|
Workflow.wipe()
|
|
|
|
role = pub.role_class(name='xxx')
|
|
role.store()
|
|
user = create_user(pub, is_admin=True)
|
|
user.name = 'Foo Bar'
|
|
user.email = 'foo@example.com'
|
|
user.roles.append(role.id)
|
|
user.store()
|
|
|
|
wf = Workflow(name='anonymise-action-final')
|
|
wf.id = '1'
|
|
wf.roles = {'_receiver': role.id}
|
|
received_status = wf.add_status('received', id='anonymise_received')
|
|
anonymise_final_status = wf.add_status('anonymise_final', id='anonymise_final')
|
|
anonymise_final_status.visibility = ['_receiver']
|
|
|
|
anonymise_final_action = anonymise_final_status.add_action('anonymise', id='_anonymise', prepend=True)
|
|
anonymise_final_action.label = 'Final anonymisation'
|
|
anonymise_final_action.mode = 'final'
|
|
jump_to_anonymise_final = received_status.add_action('choice', id='_to_anonymise_final')
|
|
jump_to_anonymise_final.by = ['_receiver']
|
|
jump_to_anonymise_final.status = anonymise_final_status.id
|
|
jump_to_anonymise_final.label = 'choice'
|
|
jump_to_anonymise_final.identifier = 'id1'
|
|
wf.store()
|
|
|
|
formdef = FormDef()
|
|
formdef.id = '1'
|
|
formdef.workflow_roles = {'_receiver': role.id}
|
|
formdef.name = 'Foo'
|
|
formdef.workflow_id = wf.id
|
|
formdef.fields = [
|
|
StringField(id='0', label='string', anonymise='intermediate', varname='inter'),
|
|
StringField(id='1', label='string', anonymise='final', varname='final'),
|
|
]
|
|
formdef.store()
|
|
formdef.data_class().wipe()
|
|
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'0': 'Foo', '1': 'Bar'}
|
|
formdata.just_created()
|
|
formdata.store()
|
|
formdata.perform_workflow()
|
|
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.status == 'wf-anonymise_received'
|
|
assert formdata.data == {'0': 'Foo', '1': 'Bar'}
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/foo/%s/' % formdata.id)
|
|
resp = resp.form.submit('button_to_anonymise_final')
|
|
resp = resp.follow()
|
|
formdata = formdef.data_class().select()[0]
|
|
assert formdata.status == 'wf-anonymise_final'
|
|
assert formdata.data == {'0': None, '1': None}
|