wcs/tests/test_admin_pages.py

2364 lines
80 KiB
Python

import datetime
import os
import re
import shutil
import StringIO
import tarfile
import time
import xml.etree.ElementTree as ET
try:
import lasso
except ImportError:
lasso = None
import pytest
from webtest import Upload
from quixote import cleanup, get_publisher
from wcs.qommon import errors, sessions
from qommon.ident.password_accounts import PasswordAccount
from wcs.qommon.http_request import HTTPRequest
from wcs.qommon.template import get_current_theme
from wcs.categories import Category
from wcs.data_sources import NamedDataSource
from wcs.roles import Role
from wcs.workflows import Workflow, DisplayMessageWorkflowStatusItem
from wcs.formdef import FormDef
from wcs import fields
from utilities import get_app, login, create_temporary_pub, clean_temporary_pub
def pytest_generate_tests(metafunc):
if 'pub' in metafunc.fixturenames:
metafunc.parametrize('pub', ['pickle', 'sql'], indirect=True)
@pytest.fixture
def pub(request):
pub = create_temporary_pub(sql_mode=(request.param == 'sql'))
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
pub.cfg['identification'] = {'methods': ['password']}
pub.cfg['language'] = {'language': 'en'}
pub.write_cfg()
return pub
def create_superuser(pub):
if pub.user_class.select(lambda x: x.name == 'admin'):
user1 = pub.user_class.select(lambda x: x.name == 'admin')[0]
user1.is_admin = True
user1.store()
return user1
user1 = pub.user_class(name='admin')
user1.is_admin = True
user1.store()
account1 = PasswordAccount(id='admin')
account1.set_password('admin')
account1.user_id = user1.id
account1.store()
return user1
def create_role():
Role.wipe()
role = Role(name='foobar')
role.store()
return role
def teardown_module(module):
clean_temporary_pub()
def test_empty_site(pub):
resp = get_app(pub).get('/backoffice/')
resp = resp.click('Users', index=0)
resp = resp.click('New User')
resp = get_app(pub).get('/backoffice/')
resp = resp.click('Settings', index=0)
def test_with_user(pub):
create_superuser(pub)
resp = get_app(pub).get('/backoffice/', status=302)
resp = resp.follow()
assert resp.location == 'http://example.net/login/'
def test_with_superuser(pub):
app = login(get_app(pub))
app.get('/backoffice/')
def test_admin_redirect(pub):
create_superuser(pub)
app = login(get_app(pub))
assert app.get('/admin/whatever', status=302).location == 'http://example.net/backoffice/whatever'
def test_admin_for_all(pub):
user = create_superuser(pub)
role = create_role()
try:
open(os.path.join(pub.app_dir, 'ADMIN_FOR_ALL'), 'w').close()
resp = get_app(pub).get('/backoffice/', status=200)
# check there are menu items
resp.click('Management', index=0)
resp.click('Forms Workshop', index=0)
resp.click('Settings', index=0)
# cheeck it's possible to get inside the subdirectories
resp = get_app(pub).get('/backoffice/settings/', status=200)
pub.cfg['admin-permissions'] = {'settings': [role.id]}
pub.write_cfg()
resp = get_app(pub).get('/backoffice/settings/', status=200)
# check it doesn't work with a non-empty ADMIN_FOR_ALL file
fd = open(os.path.join(pub.app_dir, 'ADMIN_FOR_ALL'), 'w')
fd.write('x.x.x.x')
fd.close()
resp = get_app(pub).get('/backoffice/settings/', status=302)
# check it works if the file contains the user IP address
fd = open(os.path.join(pub.app_dir, 'ADMIN_FOR_ALL'), 'w')
fd.write('127.0.0.1')
fd.close()
resp = get_app(pub).get('/backoffice/settings/', status=200)
# check it's also ok if the user is logged in but doesn't have the
# permissions
user.is_admin = False
user.store()
resp = login(get_app(pub)).get('/backoffice/settings/', status=200)
# check there are menu items
resp.click('Management', index=0)
resp.click('Forms Workshop', index=0)
resp.click('Settings', index=0)
finally:
if 'admin-permissions' in pub.cfg:
del pub.cfg['admin-permissions']
pub.write_cfg()
os.unlink(os.path.join(pub.app_dir, 'ADMIN_FOR_ALL'))
role.remove_self()
user.is_admin = True
user.store()
def test_forms(pub):
app = login(get_app(pub))
resp = app.get('/backoffice/forms/')
assert 'You first have to define roles.' in resp.body
assert not 'New Form' in resp.body
def test_forms_new(pub):
app = login(get_app(pub))
user = create_superuser(pub)
create_role()
# create a new form
resp = app.get('/backoffice/forms/')
assert 'New Form' in resp.body
resp = resp.click('New Form')
resp.forms[0]['name'] = 'form title'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert 'Form - form title' in resp.body
# makes sure the data has been correctly saved
formdef = FormDef.get(1)
assert formdef.name == 'form title'
assert formdef.url_name == 'form-title'
assert formdef.fields == []
assert formdef.disabled == True
assert formdef.last_modification_user_id == str(user.id)
def assert_option_display(resp, label, value):
option_line = re.findall('%s.*%s' % (label, value), resp.body, re.DOTALL)
assert option_line
assert not '</li>' in option_line
def test_forms_edit(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
# try changing an option
# confirmation page
assert_option_display(resp, 'Confirmation Page', 'Enabled')
resp = resp.click('Confirmation Page')
assert resp.forms[0]['confirmation'].checked
resp.forms[0]['confirmation'].checked = False
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Confirmation Page', 'Disabled')
assert FormDef.get(1).confirmation == False
# try cancel button
resp = resp.click('Confirmation Page')
assert resp.forms[0]['confirmation'].checked is False
resp.forms[0]['confirmation'].checked = True
resp = resp.forms[0].submit('cancel')
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Confirmation Page', 'Disabled')
assert FormDef.get(1).confirmation == False
# history and status
assert_option_display(resp, 'History and Status', 'Public')
resp = resp.click('History and Status')
assert resp.forms[0]['private_status_and_history'].checked is False
resp.forms[0]['private_status_and_history'].checked = True
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'History and Status', 'Private')
assert FormDef.get(1).private_status_and_history is True
# Limit to one form
assert_option_display(resp, 'Limit to one form', 'Disabled')
resp = resp.click('Limit to one form')
assert resp.forms[0]['only_allow_one'].checked is False
resp.forms[0]['only_allow_one'].checked = True
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Limit to one form', 'Enabled')
assert FormDef.get(1).only_allow_one is True
# Tracking code
assert_option_display(resp, 'Tracking Code', 'Disabled')
resp = resp.click('Tracking Code')
assert resp.forms[0]['enable_tracking_codes'].checked is False
resp.forms[0]['enable_tracking_codes'].checked = True
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Tracking Code', 'Enabled')
assert FormDef.get(1).enable_tracking_codes is True
# CAPTCHA
assert_option_display(resp, 'CAPTCHA for anonymous users', 'Disabled')
resp = resp.click('CAPTCHA for anonymous users')
assert resp.forms[0]['has_captcha'].checked is False
resp.forms[0]['has_captcha'].checked = True
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'CAPTCHA for anonymous users', 'Enabled')
assert FormDef.get(1).has_captcha is True
# Publication
assert_option_display(resp, 'Online Status', 'Active')
resp = resp.click('Online Status')
assert resp.forms[0]['disabled'].checked is False
resp.forms[0]['disabled'].checked = True
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Online Status', 'Disabled')
assert FormDef.get(1).disabled is True
resp = resp.click('Online Status')
assert resp.forms[0]['disabled'].checked is True
resp.forms[0]['disabled_redirection'] = 'http://www.example.net'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Online Status', 'Redirected')
assert FormDef.get(1).disabled is True
assert FormDef.get(1).disabled_redirection == 'http://www.example.net'
resp = resp.click('Online Status')
resp.forms[0]['disabled'].checked = False
resp.forms[0]['expiration_date'] = '2000-01-01' # this is past(tm)
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Online Status', 'Inactive by date')
# try changing title
resp = app.get('/backoffice/forms/1/')
resp = resp.click('change title')
assert resp.forms[0]['name'].value == 'form title'
resp.forms[0]['name'] = 'new title'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert FormDef.get(1).name == 'new title'
assert FormDef.get(1).url_name == 'new-title'
def test_form_category(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
assert_option_display(resp, 'Category', 'None')
Category.wipe()
cat = Category(name='Foo')
cat.store()
cat = Category(name='Bar')
cat.store()
resp = app.get('/backoffice/forms/1/')
assert 'Category' in resp.body
assert_option_display(resp, 'Category', 'None')
def test_form_category_select(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
Category.wipe()
cat = Category(name='Foo')
cat.store()
cat = Category(name='Bar')
cat.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='category')
resp = resp.forms[0].submit('cancel')
assert FormDef.get(formdef.id).category_id is None
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='category')
resp.forms[0]['category_id'] = cat.id
resp = resp.forms[0].submit('submit')
assert FormDef.get(formdef.id).category_id == cat.id
def test_form_workflow(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
assert_option_display(resp, 'Workflow', 'Default')
Workflow.wipe()
workflow = Workflow(name='Workflow One')
workflow.store()
workflow = Workflow(name='Workflow Two')
workflow.store()
resp = app.get('/backoffice/forms/1/')
assert_option_display(resp, 'Workflow', 'Default')
def test_form_workflow_change(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
Workflow.wipe()
workflow = Workflow(name='Workflow One')
workflow.store()
workflow = Workflow(name='Workflow Two')
workflow.possible_status = Workflow.get_default_workflow().possible_status[:]
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='workflow', index=1)
resp = resp.forms[0].submit('cancel')
assert FormDef.get(formdef.id).workflow_id is None
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='workflow', index=1)
assert 'Workflow One' not in resp.body # this workflow doesn't have any status
resp.forms[0]['workflow_id'] = workflow.id
resp = resp.forms[0].submit('submit')
assert FormDef.get(formdef.id).workflow_id == workflow.id
def test_form_workflow_remapping(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.status = 'wf-new'
formdata.store()
Workflow.wipe()
workflow = Workflow(name='Workflow One')
workflow.store()
workflow = Workflow(name='Workflow Two')
# create it with a single status
workflow.possible_status = [Workflow.get_default_workflow().possible_status[-1]]
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='workflow', index=1)
resp.forms[0]['workflow_id'] = workflow.id
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/forms/1/workflow-status-remapping?new=2'
resp = resp.follow()
for status in Workflow.get_default_workflow().possible_status:
assert resp.forms[0]['mapping-%s' % status.id]
# there's only one possible new status
assert len(resp.forms[0]['mapping-just_submitted'].options) == 1
assert data_class.get(1).status == 'wf-new'
resp = resp.forms[0].submit()
assert data_class.get(1).status == 'wf-finished'
def test_form_workflow_role(pub):
create_superuser(pub)
role = create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='role/_receiver')
resp = resp.forms[0].submit('cancel')
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='role/_receiver')
resp.forms[0]['role_id'] = role.id
resp = resp.forms[0].submit('submit')
assert FormDef.get(1).workflow_roles == {'_receiver': '1'}
# check it doesn't fail if a second role with the same name exists
role = Role(name='foobar')
role.store()
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='role/_receiver')
def test_form_workflow_options(pub):
create_superuser(pub)
create_role()
Workflow.wipe()
workflow = Workflow(name='Workflow One')
workflow.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.workflow_id = workflow.id
formdef.workflow_options = {'2*1*body': 'xxx'}
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
assert '"workflow-options"' in resp.body
def test_form_workflow_variables(pub):
create_superuser(pub)
create_role()
Workflow.wipe()
workflow = Workflow(name='Workflow One')
from wcs.workflows import WorkflowVariablesFieldsFormDef
workflow.variables_formdef = WorkflowVariablesFieldsFormDef(workflow=workflow)
workflow.variables_formdef.fields.append(
fields.StringField(id='1', varname='test', label='Test', type='string'))
workflow.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.workflow_id = workflow.id
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
assert '"workflow-variables"' in resp.body
# visit the variables page
resp = resp.click(href='workflow-variables')
# and set a value
resp.forms[0]['f1'] = 'foobar'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
# check the value has been correctly saved
assert FormDef.get(formdef.id).workflow_options == {'test': 'foobar'}
# go back to the variables page, also check value
resp = resp.follow()
resp = resp.click(href='workflow-variables')
assert resp.forms[0]['f1'].value == 'foobar'
resp.forms[0]['f1'] = 'barbaz'
resp = resp.forms[0].submit('cancel')
assert resp.location == 'http://example.net/backoffice/forms/1/'
def test_form_roles(pub):
create_superuser(pub)
role = create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click('User Roles')
resp = resp.forms[0].submit('cancel')
resp = app.get('/backoffice/forms/1/')
resp = resp.click('User Roles')
resp.forms[0]['roles$element0'].value = role.id
resp = resp.forms[0].submit('submit')
assert FormDef.get(1).roles == [role.id]
def test_form_always_advertise(pub):
create_superuser(pub)
role = create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
# Display to unlogged users
formdef.roles = [role.id]
formdef.store()
resp = app.get('/backoffice/forms/1/')
assert_option_display(resp, 'Display to unlogged users', 'Disabled')
resp = resp.click('Display to unlogged users')
assert resp.forms[0]['always_advertise'].checked is False
resp.forms[0]['always_advertise'].checked = True
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Display to unlogged users', 'Enabled')
assert FormDef.get(1).always_advertise is True
def test_form_delete(pub):
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='delete')
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/'
resp = resp.follow()
assert FormDef.count() == 0
def test_form_duplicate(pub):
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='duplicate')
assert resp.location == 'http://example.net/backoffice/forms/2/'
resp = resp.follow()
assert FormDef.count() == 2
assert FormDef.get(2).name == 'form title (copy)'
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='duplicate')
assert resp.location == 'http://example.net/backoffice/forms/3/'
resp = resp.follow()
assert FormDef.count() == 3
assert FormDef.get(3).name == 'form title (copy 2)'
def test_form_export(pub):
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='export')
xml_export = resp.body
fd = StringIO.StringIO(xml_export)
formdef2 = FormDef.import_from_xml(fd)
assert formdef2.name == 'form title'
def test_form_import(pub):
user = create_superuser(pub)
role = create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
formdef_xml = ET.tostring(formdef.export_to_xml(include_id=True))
FormDef.wipe()
assert FormDef.count() == 0
app = login(get_app(pub))
resp = app.get('/backoffice/forms/')
resp = resp.click(href='import')
resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
resp = resp.forms[0].submit()
assert FormDef.count() == 1
# import the same formdef a second time, make sure the urlname is not
# reused
resp = app.get('/backoffice/forms/')
resp = resp.click(href='import')
resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
resp = resp.forms[0].submit()
assert FormDef.count() == 2
assert FormDef.get(1).url_name == 'form-title'
assert FormDef.get(2).url_name == 'form-title-1'
# import a formdef with an url_name that doesn't match its title
formdef.url_name = 'xxx-other-form-title'
formdef_xml = ET.tostring(formdef.export_to_xml(include_id=True))
resp = app.get('/backoffice/forms/')
resp = resp.click(href='import')
resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
resp = resp.forms[0].submit()
def test_form_qrcode(pub):
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='qrcode')
assert '<div id="qrcode">' in resp.body
def test_form_description(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
assert_option_display(resp, 'Description', 'None')
resp = resp.click('Description')
resp.forms[0]['description'].value = '<p>Hello World</p>'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = resp.follow()
assert_option_display(resp, 'Description', 'On')
def test_form_new_field(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='fields/')
assert 'There are not yet any fields for this form' in resp.body
resp.forms[0]['label'] = 'foobar'
resp.forms[0]['type'] = 'Text (line)'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/fields/'
resp = resp.follow()
assert 'foobar' in resp.body
assert 'Use drag and drop to reorder fields.' in resp.body
assert len(FormDef.get(1).fields) == 1
assert FormDef.get(1).fields[0].key == 'string'
assert FormDef.get(1).fields[0].label == 'foobar'
# add a title too
resp.forms[0]['label'] = 'baz'
resp.forms[0]['type'] = 'Title'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/fields/'
resp = resp.follow()
# check it's in the preview
resp = app.get('/backoffice/forms/1/')
assert '<h3>baz</h3>' in resp.body
def test_form_delete_field(pub):
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [fields.StringField(id='1', label='1st field', type='string')]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='fields/')
assert '1st field' in resp.body
assert 'Use drag and drop to reorder fields.' in resp.body
resp = resp.click(href='1/delete')
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/forms/1/fields/'
resp = resp.follow()
assert len(FormDef.get(1).fields) == 0
def test_form_duplicate_field(pub):
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [fields.StringField(id='1', label='1st field', type='string')]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='fields/')
assert '1st field' in resp.body
resp = resp.click(href='1/duplicate')
assert resp.location == 'http://example.net/backoffice/forms/1/fields/'
resp = resp.follow()
assert len(FormDef.get(1).fields) == 2
assert FormDef.get(1).fields[0].label == '1st field'
assert FormDef.get(1).fields[1].label == '1st field'
def test_form_edit_field(pub):
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [fields.StringField(id='1', label='1st field', type='string')]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='fields/')
assert '1st field' in resp.body
resp = resp.click('Edit', href='1/')
assert resp.forms[0]['label'].value == '1st field'
resp.forms[0]['label'] = 'changed field'
resp.forms[0]['required'] = False
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/forms/1/fields/'
assert FormDef.get(1).fields[0].label == 'changed field'
assert FormDef.get(1).fields[0].required == False
def test_form_edit_field_advanced(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [fields.StringField(id='1', label='1st field', type='string')]
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='fields/')
assert '1st field' in resp.body
resp = resp.click('Edit', href='1/')
assert resp.forms[0]['label'].value == '1st field'
assert '<legend>Additional parameters</legend>' in resp.body
assert '<label for="form_prefill">Prefill</label>' in resp.body
# hceck the "prefill" field is under additional parameters
assert resp.body.index('<legend>Additional parameters</legend>') < \
resp.body.index('<label for="form_prefill">Prefill</label>')
# start filling the "prefill" field
resp.forms[0]['prefill$type'] = 'String'
resp = resp.forms[0].submit('prefill$apply')
# it should now appear before the additional parameters section
assert resp.body.index('<legend>Additional parameters</legend>') > \
resp.body.index('<label for="form_prefill">Prefill</label>')
# complete it
resp.forms[0]['prefill$value'] = 'test'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/forms/1/fields/'
resp = resp.follow()
assert FormDef.get(formdef.id).fields[0].prefill == {'type': 'string', 'value': 'test'}
# do the same with 'data sources' field
resp = resp.click('Edit', href='1/')
assert resp.forms[0]['label'].value == '1st field'
assert '<legend>Additional parameters</legend>' in resp.body
assert '<label for="form_data_source">Data Source</label>' in resp.body
# hceck the "data source" field is under additional parameters
assert resp.body.index('<legend>Additional parameters</legend>') < \
resp.body.index('<label for="form_data_source">Data Source</label>')
# start filling the "data source" field
resp.forms[0]['data_source$type'] = 'JSON URL'
resp = resp.forms[0].submit('data_source$apply')
# it should now appear before the additional parameters section
assert resp.body.index('<legend>Additional parameters</legend>') > \
resp.body.index('<label for="form_data_source">Data Source</label>')
def test_form_legacy_int_id(pub):
create_superuser(pub)
create_role()
Category.wipe()
cat = Category(name='Foo')
cat.store()
Workflow.wipe()
workflow = Workflow(name='Workflow One')
# create it with a single status
workflow.possible_status = [Workflow.get_default_workflow().possible_status[-1]]
workflow.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
role = Role(name='ZAB') # Z to get sorted last
role.store()
# set attributes using integers
formdef.category_id = int(cat.id)
formdef.workflow_id = int(workflow.id)
formdef.workflow_roles = {'_receiver': int(role.id)}
formdef.roles = ['logged-users', int(role.id)]
formdef.store()
formdef = FormDef.get(formdef.id) # will run migrate
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='category')
assert resp.forms[0]['category_id'].value
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='workflow', index=1)
assert resp.forms[0]['workflow_id'].value
resp = app.get('/backoffice/forms/1/')
resp = resp.click('User Roles')
assert resp.forms[0]['roles$element0'].value == 'logged-users'
assert resp.forms[0]['roles$element1'].value == role.id
resp = app.get('/backoffice/forms/1/')
resp = resp.click('Recipient')
assert resp.forms[0]['role_id'].value == role.id
def test_form_anonymise(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
for i in range(10):
formdata = data_class()
formdata.just_created()
if i < 3:
formdata.status = 'wf-new'
else:
formdata.status = 'wf-rejected'
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='anonymise')
resp = resp.form.submit('cancel')
assert len([x for x in formdef.data_class().select() if x.anonymised]) == 0
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='anonymise')
resp = resp.form.submit('submit')
assert resp.location == 'http://example.net/backoffice/forms/1/'
assert len([x for x in formdef.data_class().select() if x.anonymised]) == 0
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='anonymise')
resp.form['before_request_date'].value = (datetime.datetime.today() +
datetime.timedelta(days=1)).strftime('%Y-%m-%d')
resp = resp.form.submit('submit')
assert resp.location == 'http://example.net/backoffice/forms/1/'
assert len([x for x in formdef.data_class().select() if x.anonymised]) == 7
data_class.wipe()
for i in range(10):
formdata = data_class()
formdata.just_created()
if i < 3:
formdata.status = 'wf-rejected'
else:
formdata.status = 'wf-finished'
formdata.store()
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='anonymise')
resp.form['before_request_date'].value = (datetime.datetime.today() +
datetime.timedelta(days=1)).strftime('%Y-%m-%d')
resp.form['endpoints$elementfinished'].checked = False
resp = resp.form.submit('submit')
assert resp.location == 'http://example.net/backoffice/forms/1/'
assert len([x for x in formdef.data_class().select() if x.anonymised]) == 3
def test_form_public_url(pub):
create_superuser(pub)
create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click('Display public URL')
assert 'http://example.net/form-title/' in resp.body
def test_form_archive(pub):
create_superuser(pub)
create_role()
if getattr(pub, 'pgconn', None):
# this doesn't exist in SQL
pytest.skip('no archive in SQL mode')
return
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = []
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
for i in range(10):
formdata = data_class()
formdata.just_created()
if i < 3:
formdata.status = 'wf-new'
else:
formdata.status = 'wf-rejected'
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='archive')
resp = resp.form.submit('cancel')
assert data_class.count() == 10
assert resp.location == 'http://example.net/backoffice/forms/1/'
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='archive')
resp = resp.form.submit('submit')
assert resp.content_type == 'application/x-wcs-archive'
tf = tarfile.open(fileobj=StringIO.StringIO(resp.body))
assert 'formdef' in [x.name for x in tf.getmembers()]
assert len(tf.getmembers()) == 8 # 7 formdata + 1 formdef
# second archive, it shouldn't get anything (but the formdef)
resp = app.get('/backoffice/forms/1/')
resp = resp.click(href='archive')
resp = resp.form.submit('submit')
assert resp.content_type == 'application/x-wcs-archive'
tf = tarfile.open(fileobj=StringIO.StringIO(resp.body))
assert 'formdef' in [x.name for x in tf.getmembers()]
assert len(tf.getmembers()) == 1 # 0 formdata + 1 formdef
def test_form_overwrite(pub):
user = create_superuser(pub)
role = create_role()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form test'
formdef.table_name = 'xxx'
formdef.fields = [fields.StringField(id='1', label='1st field', type='string'),
fields.StringField(id='2', label='2nd field', type='string')]
formdef.store()
formdata = formdef.data_class()()
formdata.data = {'1': 'foo', '2': 'bar'}
formdata.just_created()
formdata.store()
formdef_id = formdef.id
formdef.fields[0].label = '1st modified field'
formdef_xml = ET.tostring(formdef.export_to_xml(include_id=True))
app = login(get_app(pub))
resp = app.get('/backoffice/forms/%s/' % formdef_id)
resp = resp.click(href='overwrite')
resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
resp = resp.forms[0].submit()
assert FormDef.get(formdef_id).fields[0].label == '1st modified field'
# check with added/removed field
formdef = FormDef()
formdef.name = 'form test overwrite'
formdef.fields = [
fields.StringField(id='2', label='2nd field', type='string'),
fields.StringField(id='3', label='3rd field', type='string')]
formdef_xml = ET.tostring(formdef.export_to_xml(include_id=True))
app = login(get_app(pub))
resp = app.get('/backoffice/forms/%s/' % formdef_id)
resp = resp.click(href='overwrite')
resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
resp = resp.forms[0].submit()
assert 'The form removes and changes fields' in resp.body
assert not 'The form has incompatible fields, it may cause data corruption and bugs' in resp.body
resp = resp.forms[0].submit()
assert FormDef.get(formdef_id).fields[0].id == '2'
assert FormDef.get(formdef_id).fields[0].label == '2nd field'
assert FormDef.get(formdef_id).fields[1].id == '3'
assert FormDef.get(formdef_id).fields[1].label == '3rd field'
# check with a field of different type
formdef = FormDef()
formdef.name = 'form test overwrite'
formdef.fields = [
fields.StringField(id='2', label='2nd field', type='string'),
fields.TextField(id='3', label='3rd field, text', type='text')]
formdef_xml = ET.tostring(formdef.export_to_xml(include_id=True))
app = login(get_app(pub))
resp = app.get('/backoffice/forms/%s/' % formdef_id)
resp = resp.click(href='overwrite')
resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
resp = resp.forms[0].submit()
assert 'The form removes and changes fields' in resp.body
assert 'The form has incompatible fields, it may cause data corruption and bugs' in resp.body
resp.forms[0]['force'] = True
resp = resp.forms[0].submit()
assert FormDef.get(formdef_id).fields[1].id == '3'
assert FormDef.get(formdef_id).fields[1].label == '3rd field, text'
assert FormDef.get(formdef_id).fields[1].type == 'text'
# check we kept stable references
assert FormDef.get(formdef_id).url_name == 'form-test'
assert FormDef.get(formdef_id).table_name == 'xxx'
def test_workflows(pub):
app = login(get_app(pub))
app.get('/backoffice/workflows/')
def test_workflows_default(pub):
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/')
assert 'Default' in resp.body
resp = resp.click(href='_default')
assert 'Just Submitted' in resp.body
assert 'This is the default workflow' in resp.body
# makes sure it cannot be edited
assert 'Edit' not in resp.body
# and makes sure status are not editable either
resp = resp.click('Just Submitted')
assert 'Workflow - Default - Just Submitted' in resp.body
assert 'Change Status Name' not in resp.body
assert 'Delete' not in resp.body
def test_workflows_new(pub):
Workflow.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/')
# create a new workflow
resp = resp.click('New Workflow')
resp.forms[0]['name'] = 'a new workflow'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/workflows/1/'
resp = resp.follow()
assert 'There are not yet any status defined in this workflow' in resp.body
assert not '<svg ' in resp.body
# create a new status
resp.forms[0]['name'] = 'new status'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/'
resp = resp.follow()
assert '<svg ' in resp.body
# create a new action
resp = resp.click('new status')
resp.forms[0]['type'] = 'Display message'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
resp = resp.follow()
assert 'Use drag and drop to reorder items' in resp.body
# fill action
resp = resp.click('Display message')
resp.forms[0]['message'] = 'bla bla bla'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/items/'
resp = resp.follow()
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
wf = Workflow.get(1)
assert wf.name == 'a new workflow'
assert wf.possible_status[0].name == 'new status'
assert wf.possible_status[0].items[0].message == 'bla bla bla'
def test_workflows_edit(pub):
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/1/')
resp = resp.click(href='edit')
assert resp.forms[0]['name'].value == 'foo'
resp.forms[0]['name'] = 'baz'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/workflows/'
resp = resp.follow()
assert 'baz' in resp.body
def test_workflows_edit_status(pub):
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.add_status(name='baz')
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/1/')
resp = resp.click('baz')
resp = resp.click('Change Status Name')
resp.forms[0]['name'] = 'bza'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
resp = resp.follow()
assert Workflow.get(1).possible_status[0].name == 'bza'
resp = resp.click('Change Status Visibility')
resp.forms[0]['hide_status_from_user'].checked = True
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
resp = resp.follow()
assert Workflow.get(1).possible_status[0].visibility == ['_receiver']
resp = resp.click('Change Terminal Status')
resp.forms[0]['force_terminal_status'].checked = True
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
resp = resp.follow()
assert Workflow.get(1).possible_status[0].forced_endpoint == True
resp = resp.click('Change Status Colour')
assert resp.forms[0]['colour'].value == 'FFFFFF'
resp.forms[0]['colour'] = 'FF0000'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
resp = resp.follow()
assert Workflow.get(1).possible_status[0].colour == 'FF0000'
resp = resp.click('Change Backoffice Information Text')
assert resp.forms[0]['backoffice_info_text'].value == ''
resp.forms[0]['backoffice_info_text'] = '<p>Hello</p>'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/status/1/'
resp = resp.follow()
assert Workflow.get(1).possible_status[0].backoffice_info_text == '<p>Hello</p>'
def test_workflows_delete(pub):
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/1/')
resp = resp.click(href='delete')
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/'
resp = resp.follow()
assert Workflow.count() == 0
def test_workflows_add_all_actions(pub):
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.add_status(name='baz')
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/1/')
resp = resp.click('baz')
for action in [x[0] for x in resp.forms[0]['type'].options]:
resp.forms[0]['type'] = action
resp = resp.forms[0].submit()
resp = resp.follow()
for i in range(len(resp.forms[0]['type'].options)):
resp = resp.click('Edit', href='items/%d/' % (i+1), index=0)
resp = resp.forms[0].submit('cancel')
resp = resp.follow() # redirect to items/
resp = resp.follow() # redirect to ./
def test_workflows_variables(pub):
create_superuser(pub)
create_role()
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/1/')
resp = resp.click(href='variables/')
assert resp.location == 'http://example.net/backoffice/workflows/1/variables/fields/'
resp = resp.follow()
# makes sure we can't add page fields
assert 'value="New Page"' not in resp.body
# add a simple field
resp.forms[0]['label'] = 'foobar'
resp.forms[0]['type'] = 'Text (line)'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/workflows/1/variables/fields/'
resp = resp.follow()
# check it's been saved correctly
assert 'foobar' in resp.body
assert len(Workflow.get(1).variables_formdef.fields) == 1
assert Workflow.get(1).variables_formdef.fields[0].key == 'string'
assert Workflow.get(1).variables_formdef.fields[0].label == 'foobar'
def test_workflows_variables_edit(pub):
test_workflows_variables(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/1/')
resp = resp.click(href='variables/', index=0)
assert resp.location == 'http://example.net/backoffice/workflows/1/variables/fields/'
resp = resp.follow()
resp = resp.click('Edit', href='1/')
assert resp.forms[0]['varname$name'].value == 'foobar'
assert not 'varname$select' in resp.forms[0].fields
workflow = Workflow.get(1)
baz_status = workflow.add_status(name='baz')
display_message = DisplayMessageWorkflowStatusItem()
display_message.parent = baz_status
baz_status.items.append(display_message)
workflow.store()
resp = app.get('/backoffice/workflows/1/variables/fields/')
resp = resp.click('Edit', href='1/')
assert 'varname$select' in resp.forms[0].fields
resp.forms[0]['varname$select'].value = '1*1*message'
resp = resp.forms[0].submit('submit')
assert Workflow.get(1).variables_formdef.fields[0].key == 'string'
assert Workflow.get(1).variables_formdef.fields[0].varname == '1*1*message'
def test_workflows_functions(pub):
create_superuser(pub)
create_role()
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.store()
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('add function')
resp = resp.forms[0].submit('cancel')
assert Workflow.get(workflow.id).roles.keys() == ['_receiver']
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('add function')
resp.forms[0]['name'] = 'Other Function'
resp = resp.forms[0].submit('submit')
assert set(Workflow.get(workflow.id).roles.keys()) == set(['_receiver', '_other-function'])
assert Workflow.get(workflow.id).roles['_other-function'] == 'Other Function'
# test rename
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('Other Function')
resp = resp.forms[0].submit('cancel')
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('Other Function')
resp.forms[0]['name'] = 'Other Renamed Function'
resp = resp.forms[0].submit('submit')
assert set(Workflow.get(workflow.id).roles.keys()) == set(['_receiver', '_other-function'])
assert Workflow.get(workflow.id).roles['_other-function'] == 'Other Renamed Function'
# test removal
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('Other Renamed Function')
resp = resp.forms[0].submit('delete')
assert set(Workflow.get(workflow.id).roles.keys()) == set(['_receiver'])
# make sure it's not possible to remove the "_receiver" key
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('Recipient')
assert not 'delete' in resp.forms[0].fields
def test_workflows_functions_vs_visibility(pub):
create_superuser(pub)
create_role()
Workflow.wipe()
workflow = Workflow(name='foo')
workflow.possible_status = Workflow.get_default_workflow().possible_status[:]
workflow.store()
# restrict visibility
app = login(get_app(pub))
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('Just Submitted')
resp = resp.click('Change Status Visibility')
resp.forms[0]['hide_status_from_user'].checked = True
resp = resp.forms[0].submit()
assert Workflow.get(workflow.id).possible_status[0].visibility == ['_receiver']
# add function, make sure visibility follows
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('add function')
resp.forms[0]['name'] = 'Other Function'
resp = resp.forms[0].submit('submit')
assert set(Workflow.get(workflow.id).roles.keys()) == set(['_receiver', '_other-function'])
assert Workflow.get(workflow.id).roles['_other-function'] == 'Other Function'
assert set(Workflow.get(workflow.id).possible_status[0].visibility) == set(
['_receiver', '_other-function'])
# restrict visibility in a different status, check it gets all the
# functions
resp = app.get('/backoffice/workflows/%s/' % workflow.id)
resp = resp.click('Rejected')
resp = resp.click('Change Status Visibility')
resp.forms[0]['hide_status_from_user'].checked = True
resp = resp.forms[0].submit()
assert set(Workflow.get(workflow.id).possible_status[2].visibility) == set(
['_receiver', '_other-function'])
def test_users(pub):
create_superuser(pub)
app = login(get_app(pub))
app.get('/backoffice/users/')
def test_users_new(pub):
pub.user_class.wipe()
create_superuser(pub)
user_count = pub.user_class.count()
account_count = PasswordAccount.count()
app = login(get_app(pub))
resp = app.get('/backoffice/users/')
resp = resp.click('New User')
resp.forms[0]['name'] = 'a new user'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/users/'
resp = resp.follow()
assert 'a new user' in resp.body
resp = resp.click('a new user')
assert 'User - a new user' in resp.body
assert pub.user_class.count() == user_count + 1
assert PasswordAccount.count() == account_count
def test_users_new_with_account(pub):
pub.user_class.wipe()
create_superuser(pub)
user_count = pub.user_class.count()
account_count = PasswordAccount.count()
app = login(get_app(pub))
resp = app.get('/backoffice/users/')
resp = resp.click('New User')
resp.forms[0]['name'] = 'a second user'
resp.forms[0]['method_password$username'] = 'second-user'
resp.forms[0]['method_password$password'] = 'foobar'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/users/'
resp = resp.follow()
assert 'a second user' in resp.body
resp = resp.click('a second user')
assert 'User - a second user' in resp.body
assert pub.user_class.count() == user_count + 1
assert PasswordAccount.count() == account_count + 1
def test_users_edit(pub):
pub.user_class.wipe()
create_superuser(pub)
user = pub.user_class(name='foo bar')
user.store()
app = login(get_app(pub))
resp = app.get('/backoffice/users/%s/' % user.id)
resp = resp.click(href='edit')
resp.forms[0]['is_admin'].checked = True
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/users/%s/' % user.id
resp = resp.follow()
def test_users_edit_new_account(pub):
pub.user_class.wipe()
PasswordAccount.wipe()
create_superuser(pub)
user = pub.user_class(name='foo bar')
user.store()
account_count = PasswordAccount.count()
app = login(get_app(pub))
resp = app.get('/backoffice/users/%s/' % user.id)
resp = resp.click(href='edit')
resp.forms[0]['is_admin'].checked = True
resp.forms[0]['method_password$username'] = 'foo'
resp.forms[0]['method_password$password'] = 'bar'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/users/%s/' % user.id
resp = resp.follow()
assert PasswordAccount.count() == account_count + 1
def test_users_edit_edit_account(pub):
pub.user_class.wipe()
PasswordAccount.wipe()
create_superuser(pub)
user = pub.user_class(name='foo bar')
user.store()
account = PasswordAccount(id='test')
account.user_id = user.id
account.store()
assert PasswordAccount.has_key('test')
app = login(get_app(pub))
resp = app.get('/backoffice/users/%s/' % user.id)
resp = resp.click(href='edit')
resp.forms[0]['is_admin'].checked = True
resp.forms[0]['method_password$username'] = 'foo' # change username
resp.forms[0]['method_password$password'] = 'bar'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/users/%s/' % user.id
resp = resp.follow()
# makes sure the old account has been removed
assert not PasswordAccount.has_key('test')
assert PasswordAccount.has_key('foo')
assert PasswordAccount.get('foo').user_id == user.id
def test_users_delete(pub):
pub.user_class.wipe()
PasswordAccount.wipe()
create_superuser(pub)
user = pub.user_class(name='foo bar')
user.store()
account = PasswordAccount(id='test')
account.user_id = user.id
account.store()
user_count = pub.user_class.count()
account_count = PasswordAccount.count()
app = login(get_app(pub))
resp = app.get('/backoffice/users/%s/' % user.id)
resp = resp.click(href='delete')
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/users/'
resp = resp.follow()
assert pub.user_class.count() == user_count - 1
assert PasswordAccount.count() == account_count - 1
def test_users_pagination(pub):
pub.user_class.wipe()
PasswordAccount.wipe()
create_superuser(pub)
for i in range(50):
user = pub.user_class(name='foo bar %s' % (i+1))
user.store()
app = login(get_app(pub))
resp = app.get('/backoffice/users/')
assert 'foo bar 10' in resp.body
assert 'foo bar 30' not in resp.body
resp = resp.click('Next Page')
assert 'foo bar 10' not in resp.body
assert 'foo bar 30' in resp.body
resp = resp.click('Previous Page')
assert 'foo bar 10' in resp.body
assert 'foo bar 30' not in resp.body
resp = resp.click('Next Page')
resp = resp.click('Next Page')
assert 'foo bar 50' in resp.body
def test_users_filter(pub):
pub.user_class.wipe()
PasswordAccount.wipe()
create_superuser(pub)
role = create_role()
for i in range(50):
user = pub.user_class(name='foo bar %s' % (i+1))
user.store()
for i in range(5):
user = pub.user_class(name='baz bar %s' % (i+1))
user.roles = [role.id]
user.store()
app = login(get_app(pub))
resp = app.get('/backoffice/users/')
assert 'admin' in resp.body # superuser
assert 'foo bar 10' in resp.body # simple user
# uncheck 'None'; unfortunately this doesn't work with webtest 1.3
# resp.forms[0].fields['role'][-1].checked = False
# resp = resp.forms[0].submit()
# therefore we fall back on using the URL
resp = app.get('/backoffice/users/?offset=0&limit=100&q=&filter=true&role=admin')
assert '>Number of filtered users: 1<' in resp.body
assert 'user-is-admin' in resp.body # superuser
assert 'foo bar 1' not in resp.body # simple user
assert 'baz bar 1' not in resp.body # user with role
resp = app.get('/backoffice/users/?offset=0&limit=100&q=&filter=true&role=1')
assert '>Number of filtered users: 5<' in resp.body
assert 'user-is-admin' not in resp.body # superuser
assert 'foo bar 10' not in resp.body # simple user
assert 'baz bar 1' in resp.body # user with role
def test_users_search(pub):
pub.user_class.wipe()
PasswordAccount.wipe()
create_superuser(pub)
for i in range(20):
user = pub.user_class(name='foo %s' % (i+1))
user.store()
for i in range(10):
user = pub.user_class(name='bar %s' % (i+1))
user.store()
app = login(get_app(pub))
resp = app.get('/backoffice/users/')
assert 'foo 10' in resp.body
resp.forms[0]['q'] = 'bar'
resp = resp.forms[0].submit()
assert 'foo 10' not in resp.body
assert 'bar 10' in resp.body
assert 'Number of filtered users: 10' in resp.body
def test_roles(pub):
app = login(get_app(pub))
app.get('/backoffice/roles/')
def test_roles_new(pub):
Role.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/roles/')
resp = resp.click('New Role')
resp.forms[0]['name'] = 'a new role'
resp.forms[0]['details'] = 'bla bla bla'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/roles/'
resp = resp.follow()
assert 'a new role' in resp.body
resp = resp.click('a new role')
assert 'Role - a new role' in resp.body
assert Role.get(1).name == 'a new role'
assert Role.get(1).details == 'bla bla bla'
def test_roles_edit(pub):
Role.wipe()
role = Role(name='foobar')
role.store()
app = login(get_app(pub))
resp = app.get('/backoffice/roles/1/')
assert 'Holders of this role are granted access to the backoffice' in resp.body
resp = resp.click(href='edit')
assert resp.forms[0]['name'].value == 'foobar'
resp.forms[0]['name'] = 'baz'
resp.forms[0]['details'] = 'bla bla bla'
resp.forms[0]['emails_to_members'].checked = True
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/roles/1/'
resp = resp.follow()
assert 'Role - baz' in resp.body
assert 'Holders of this role will receive all emails adressed to the role.' in resp.body
assert Role.get(1).details == 'bla bla bla'
assert Role.get(1).emails_to_members == True
def test_roles_matching_formdefs(pub):
Role.wipe()
role = Role(name='foo')
role.store()
FormDef.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/roles/1/')
assert 'form bar' not in resp.body
formdef = FormDef()
formdef.name = 'form bar'
formdef.roles = [role.id]
formdef.fields = []
formdef.store()
resp = app.get('/backoffice/roles/1/')
assert 'form bar' in resp.body
assert 'form baz' not in resp.body
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form baz'
formdef.fields = []
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
resp = app.get('/backoffice/roles/1/')
assert 'form baz' in resp.body
assert 'form bar' not in resp.body
def test_roles_delete(pub):
Role.wipe()
role = Role(name='foobar')
role.store()
app = login(get_app(pub))
resp = app.get('/backoffice/roles/1/')
resp = resp.click(href='delete')
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/roles/'
resp = resp.follow()
assert Role.count() == 0
def test_categories(pub):
app = login(get_app(pub))
app.get('/backoffice/categories/')
def test_categories_new(pub):
Category.wipe()
app = login(get_app(pub))
# go to the page and cancel
resp = app.get('/backoffice/categories/')
resp = resp.click('New Category')
resp = resp.forms[0].submit('cancel')
assert resp.location == 'http://example.net/backoffice/categories/'
# go to the page and add a category
resp = app.get('/backoffice/categories/')
resp = resp.click('New Category')
resp.forms[0]['name'] = 'a new category'
resp.forms[0]['description'] = 'description of the category'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/categories/'
resp = resp.follow()
assert 'a new category' in resp.body
resp = resp.click('a new category')
assert 'Category - a new category' in resp.body
assert Category.get(1).name == 'a new category'
assert Category.get(1).description == 'description of the category'
def test_categories_edit(pub):
Category.wipe()
category = Category(name='foobar')
category.store()
app = login(get_app(pub))
resp = app.get('/backoffice/categories/1/')
assert 'no form associated to this category' in resp.body
resp = resp.click(href='edit')
assert resp.forms[0]['name'].value == 'foobar'
resp.forms[0]['description'] = 'category description'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/categories/'
resp = resp.follow()
resp = resp.click('foobar')
assert 'Category - foobar' in resp.body
assert Category.get(1).description == 'category description'
def test_categories_edit_duplicate_name(pub):
Category.wipe()
category = Category(name='foobar')
category.store()
category = Category(name='foobar2')
category.store()
app = login(get_app(pub))
resp = app.get('/backoffice/categories/1/')
resp = resp.click(href='edit')
assert resp.forms[0]['name'].value == 'foobar'
resp.forms[0]['name'] = 'foobar2'
resp = resp.forms[0].submit('submit')
assert 'This name is already used' in resp.body
resp = resp.forms[0].submit('cancel')
assert resp.location == 'http://example.net/backoffice/categories/'
def test_categories_with_formdefs(pub):
Category.wipe()
category = Category(name='foobar')
category.store()
FormDef.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/categories/1/')
assert 'form bar' not in resp.body
formdef = FormDef()
formdef.name = 'form bar'
formdef.fields = []
formdef.category_id = category.id
formdef.store()
resp = app.get('/backoffice/categories/1/')
assert 'form bar' in resp.body
assert 'no form associated to this category' not in resp.body
def test_categories_delete(pub):
Category.wipe()
category = Category(name='foobar')
category.store()
FormDef.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/categories/1/')
resp = resp.click(href='delete')
resp = resp.forms[0].submit('cancel')
assert resp.location == 'http://example.net/backoffice/categories/'
assert Category.count() == 1
resp = app.get('/backoffice/categories/1/')
resp = resp.click(href='delete')
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/categories/'
resp = resp.follow()
assert Category.count() == 0
def test_categories_edit_description(pub):
Category.wipe()
category = Category(name='foobar')
category.description = 'category description'
category.store()
app = login(get_app(pub))
# this URL is used for editing from the frontoffice, there's no link
# pointing to it in the admin.
resp = app.get('/backoffice/categories/1/description')
assert resp.forms[0]['description'].value == 'category description'
resp.forms[0]['description'] = 'updated description'
# check cancel doesn't save the change
resp2 = resp.forms[0].submit('cancel')
assert resp2.location == 'http://example.net/backoffice/categories/1/'
assert Category.get(1).description == 'category description'
# check submit does it properly
resp2 = resp.forms[0].submit('submit')
assert resp2.location == 'http://example.net/backoffice/categories/1/'
resp2 = resp2.follow()
assert Category.get(1).description == 'updated description'
def test_categories_new_duplicate_name(pub):
Category.wipe()
category = Category(name='foobar')
category.store()
app = login(get_app(pub))
resp = app.get('/backoffice/categories/')
resp = resp.click('New Category')
resp.forms[0]['name'] = 'foobar'
resp = resp.forms[0].submit('submit')
assert 'This name is already used' in resp.body
def test_categories_reorder(pub):
Category.wipe()
category = Category(name='foo')
category.store()
category = Category(name='bar')
category.store()
category = Category(name='baz')
category.store()
app = login(get_app(pub))
resp = app.get('/backoffice/categories/update_order?order=1;2;3;')
categories = Category.select()
Category.sort_by_position(categories)
assert [x.id for x in categories] == ['1', '2', '3']
resp = app.get('/backoffice/categories/update_order?order=3;1;2;')
categories = Category.select()
Category.sort_by_position(categories)
assert [x.id for x in categories] == ['3', '1', '2']
def test_settings(pub):
app = login(get_app(pub))
app.get('/backoffice/settings/')
app.get('/backoffice/settings/misc')
app.get('/backoffice/settings/debug_options')
app.get('/backoffice/settings/language')
app.get('/backoffice/settings/import')
app.get('/backoffice/settings/export')
app.get('/backoffice/settings/identification')
app.get('/backoffice/settings/sitename')
app.get('/backoffice/settings/sms')
app.get('/backoffice/settings/session')
app.get('/backoffice/settings/admin-permissions')
def test_settings_themes(pub):
create_superuser(pub)
app = login(get_app(pub))
# create mock theme
os.mkdir(os.path.join(pub.app_dir, 'themes'))
os.mkdir(os.path.join(pub.app_dir, 'themes', 'test'))
fd = open(os.path.join(pub.app_dir, 'themes', 'test', 'desc.xml'), 'w')
fd.write('<?xml version="1.0"?>'\
'<theme name="test" version="1.0">'\
' <label>Test Theme</label>'\
'</theme>')
fd.close()
resp = app.get('/backoffice/settings/themes')
assert 'biglist themes' in resp.body
assert 'Test Theme (1.0)' in resp.body
# just for the kick, there's no support for uploading file in webtest 1.3
resp = app.get('/backoffice/settings/themes')
resp.click('Install New Theme')
# select the theme
resp = app.get('/backoffice/settings/themes')
resp.forms[0]['theme'].value = 'test'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/settings/'
resp = app.get('/backoffice/settings/themes')
assert 'checked' in resp.body
assert get_current_theme()['name'] == 'test'
def test_settings_template(pub):
create_superuser(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/settings/template')
# change template
orig_value = resp.forms[0]['template'].value
assert not 'foobar' in orig_value
resp.forms[0]['template'] = orig_value + '<!-- foobar -->'
resp = resp.forms[0].submit('submit')
# restore default template
resp = app.get('/backoffice/settings/template')
assert 'foobar' in resp.forms[0]['template'].value
resp = resp.forms[0].submit('restore-default')
# check
resp = app.get('/backoffice/settings/template')
assert resp.forms[0]['template'].value == orig_value
def test_settings_user(pub):
user = create_superuser(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/settings/users').follow().follow()
# add a field
resp.forms[1]['label'] = 'foobar'
resp = resp.forms[1].submit()
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
resp = resp.follow()
assert 'foobar' in pub.cfg['users']['formdef']
assert 'foobar' in resp.body
# set field as email
resp.forms[0]['field_email'] = '1'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
resp = resp.follow()
assert pub.cfg['users']['field_email'] == '1'
# and unset it
resp.forms[0]['field_email'] = ''
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
resp = resp.follow()
assert pub.cfg['users']['field_email'] == None
# add a comment field
resp.forms[1]['label'] = 'barfoo'
resp.forms[1]['type'] = 'Comment'
resp = resp.forms[1].submit()
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
resp = resp.follow()
assert 'barfoo' in pub.cfg['users']['formdef']
assert 'barfoo' in resp.body
# check fields are present in edit form
resp = app.get('/backoffice/users/%s/edit' % user.id)
assert 'barfoo' in resp.body
assert 'f1' in resp.forms[0].fields
assert 'email' in resp.forms[0].fields
# check the email field is not displayed if it's overridden by a custom
# field.
pub.cfg['users']['field_email'] = '1'
pub.write_cfg()
resp = app.get('/backoffice/users/%s/edit' % user.id)
assert 'f1' in resp.forms[0].fields
assert 'email' not in resp.forms[0].fields
# restore config
pub.cfg['users']['field_email'] = None
pub.write_cfg()
def test_settings_emails(pub):
create_superuser(pub)
app = login(get_app(pub))
pub.cfg['debug'] = {'mail_redirection': 'foo@example.net'}
pub.write_cfg()
resp = app.get('/backoffice/settings/emails/')
resp = resp.click('General Options')
assert 'Warning: all emails are sent to &lt;foo@example.net&gt;' in resp.body
pub.cfg['debug'] = {}
pub.write_cfg()
resp = app.get('/backoffice/settings/emails/')
resp = resp.click('General Options')
assert 'Warning: all emails are sent to &lt;foo@example.net&gt;' not in resp.body
resp = app.get('/backoffice/settings/emails/')
resp = resp.click('Approval of new account')
resp.forms[0]['email-new-account-approved_subject'] = 'bla'
resp.forms[0]['email-new-account-approved'] = 'bla bla bla'
resp = resp.forms[0].submit()
assert pub.cfg['emails']['email-new-account-approved_subject'] == 'bla'
assert pub.cfg['emails']['email-new-account-approved'] == 'bla bla bla'
# reset to default value
resp = app.get('/backoffice/settings/emails/')
resp = resp.click('Approval of new account')
resp.forms[0]['email-new-account-approved_subject'] = 'Your account has been approved'
resp = resp.forms[0].submit()
assert pub.cfg['emails']['email-new-account-approved_subject'] is None
def test_settings_texts(pub):
create_superuser(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/settings/texts/')
resp = resp.click('Text on top of the login page')
resp.forms[0]['text-top-of-login'] = 'Hello world'
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/settings/texts/'
assert pub.cfg['texts']['text-top-of-login'] == 'Hello world'
resp = app.get('/backoffice/settings/texts/')
resp = resp.click('Text on top of the login page')
resp = resp.forms[0].submit('restore-default')
assert resp.location == 'http://example.net/backoffice/settings/texts/'
assert pub.cfg['texts']['text-top-of-login'] == None
@pytest.mark.skipif('lasso is None')
def test_settings_auth(pub):
pub.user_class.wipe() # makes sure there are no users
pub.cfg['identification'] = {}
pub.write_cfg()
app = get_app(pub)
resp = app.get('/backoffice/settings/')
assert not 'identification/password/' in resp.body
assert not 'identification/idp/' in resp.body
resp = resp.click('Identification')
assert resp.forms[0]['methods$elementidp'].checked is False
assert resp.forms[0]['methods$elementpassword'].checked is False
resp.forms[0]['methods$elementidp'].checked = True
resp = resp.forms[0].submit()
resp = resp.follow()
assert 'identification/idp/' in resp.body
assert pub.cfg['identification']['methods'] == ['idp']
resp = resp.click('Identification')
assert resp.forms[0]['methods$elementidp'].checked is True
assert resp.forms[0]['methods$elementpassword'].checked is False
resp.forms[0]['methods$elementidp'].checked = False
resp.forms[0]['methods$elementpassword'].checked = True
resp = resp.forms[0].submit()
resp = resp.follow()
assert 'identification/password/' in resp.body
assert pub.cfg['identification']['methods'] == ['password']
@pytest.mark.skipif('lasso is None')
def test_settings_idp(pub):
pub.user_class.wipe() # makes sure there are no users
pub.cfg['identification'] = {'methods': ['idp']}
pub.write_cfg()
app = get_app(pub)
app.get('/saml/metadata', status=404)
resp = app.get('/backoffice/settings/')
resp = resp.click(href='identification/idp/')
resp = resp.click('Service Provider')
resp = resp.forms[0].submit()
resp = resp.follow()
resp_metadata = app.get('/saml/metadata', status=200)
assert resp_metadata.body.startswith('<?xml')
resp2 = resp.click('Identity Providers')
resp2.click('New') # this would then require file upload support
from test_saml_auth import setup_environment
setup_environment(pub)
resp = resp.click('Identity Providers')
assert 'http://sso.example.net/' in resp.body
resp2 = resp.click(href='http-sso.example.net-saml2-metadata/', index=0)
assert 'ns0:EntityDescriptor' in resp2.body
resp = resp.click(href='http-sso.example.net-saml2-metadata/edit')
resp = resp.forms[0].submit('submit')
resp = resp.follow()
# test that login initiates a SSO
login_resp = app.get('/login/', status=302)
assert login_resp.location.startswith('http://sso.example.net/saml2/sso?SAMLRequest')
resp = resp.click(href='/backoffice/settings/identification/idp/idp/') # breadcrumb
resp = resp.click(href='http-sso.example.net-saml2-metadata/delete')
resp = resp.forms[0].submit() # confirm delete
assert len(pub.cfg['idp']) == 0
def test_settings_auth_password(pub):
pub.user_class.wipe() # makes sure there are no users
pub.cfg['identification'] = {'methods': ['password']}
assert pub.cfg['identification']['methods'] == ['password']
pub.write_cfg()
app = get_app(pub)
resp = app.get('/backoffice/settings/identification/password/')
resp = resp.click('Identities')
resp = resp.forms[0].submit()
resp = app.get('/backoffice/settings/identification/password/')
resp = resp.click('Passwords')
resp = resp.forms[0].submit()
resp = app.get('/backoffice/settings/identification/password/')
resp = resp.click('Bulk Import')
resp = resp.forms[0].submit()
def test_settings_filetypes(pub):
create_superuser(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/settings/filetypes/')
assert 'There are no file type defined at the moment.' in resp.body
resp.forms[0]['label'] = 'Text files'
resp.forms[0]['mimetypes'] = '.odt'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/settings/filetypes/'
resp = resp.follow()
assert pub.cfg['filetypes'][1]['label'] == 'Text files'
resp = resp.click('Text files')
assert resp.forms[0]['mimetypes'].value == 'application/vnd.oasis.opendocument.text'
resp.forms[0]['mimetypes'] = 'application/vnd.oasis.opendocument.text, .doc, .docx, .pdf'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/settings/filetypes/'
resp = resp.follow()
assert 'application/msword (.doc)' in resp.body
assert 'application/pdf' in pub.cfg['filetypes'][1]['mimetypes']
resp.forms[0]['label'] = 'HTML files'
resp.forms[0]['mimetypes'] = '.html'
resp = resp.forms[0].submit('submit')
resp = resp.follow()
resp = resp.click('HTML files') # go to form
resp = resp.forms[0].submit('cancel') # and cancel
assert resp.location == 'http://example.net/backoffice/settings/filetypes/'
resp = resp.follow()
assert 'HTML files' in resp.body
resp = resp.click('HTML files') # go to form
resp = resp.forms[0].submit('delete') # and delete
assert resp.location == 'http://example.net/backoffice/settings/filetypes/'
resp = resp.follow()
assert 'HTML files' not in resp.body
def test_settings_filetypes_update(pub):
create_superuser(pub)
app = login(get_app(pub))
pub.cfg['filetypes'] = {
1: {'mimetypes': ['application/pdf', 'application/msword'],
'label': 'Text files'}
}
pub.write_cfg()
resp = app.get('/backoffice/settings/filetypes/')
assert 'Text files' in resp.body
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [fields.FileField(
id='1', label='1st field', type='file',
file_type=['application/pdf,application/msword'])]
formdef.store()
assert FormDef.get(formdef.id).fields[0].file_type == ['application/pdf,application/msword']
resp = resp.click('Text files')
resp.forms[0]['mimetypes'] = 'application/vnd.oasis.opendocument.text, .doc, .docx, .pdf'
resp = resp.forms[0].submit('submit')
assert 'application/pdf' in pub.cfg['filetypes'][1]['mimetypes']
assert FormDef.get(formdef.id).fields[0].file_type == ['application/vnd.oasis.opendocument.text,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/pdf']
def test_data_sources(pub):
create_superuser(pub)
app = login(get_app(pub))
app.get('/backoffice/settings/data-sources/')
def test_data_sources_new(pub):
create_superuser(pub)
NamedDataSource.wipe()
app = login(get_app(pub))
# go to the page and cancel
resp = app.get('/backoffice/settings/data-sources/')
resp = resp.click('New Data Source')
resp = resp.forms[0].submit('cancel')
assert resp.location == 'http://example.net/backoffice/settings/data-sources/'
# go to the page and add a data source
resp = app.get('/backoffice/settings/data-sources/')
resp = resp.click('New Data Source')
resp.forms[0]['name'] = 'a new data source'
resp.forms[0]['description'] = 'description of the data source'
resp.forms[0]['data_source$type'] = 'Formula (Python)'
resp = resp.forms[0].submit('data_source$apply')
resp.forms[0]['data_source$value'] = repr(
[{'id': '1', 'text': 'un'}, {'id': '2', 'text': 'deux'}])
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/settings/data-sources/'
resp = resp.follow()
assert 'a new data source' in resp.body
resp = resp.click('a new data source')
assert 'Data Source - a new data source' in resp.body
resp = resp.click('Edit')
assert 'Edit Data Source' in resp.body
assert NamedDataSource.get(1).name == 'a new data source'
assert NamedDataSource.get(1).description == 'description of the data source'
def test_data_sources_edit(pub):
create_superuser(pub)
NamedDataSource.wipe()
data_source = NamedDataSource(name='foobar')
data_source.data_source = {'type': 'formula', 'value': '[]'}
data_source.store()
app = login(get_app(pub))
resp = app.get('/backoffice/settings/data-sources/1/')
resp = resp.click(href='edit')
assert resp.forms[0]['name'].value == 'foobar'
resp.forms[0]['description'] = 'data source description'
resp = resp.forms[0].submit('submit')
assert resp.location == 'http://example.net/backoffice/settings/data-sources/'
resp = resp.follow()
resp = resp.click('foobar')
assert NamedDataSource.get(1).description == 'data source description'
def test_data_sources_edit_duplicate_name(pub):
create_superuser(pub)
NamedDataSource.wipe()
data_source = NamedDataSource(name='foobar')
data_source.data_source = {'type': 'formula', 'value': '[]'}
data_source.store()
data_source = NamedDataSource(name='foobar2')
data_source.data_source = {'type': 'formula', 'value': '[]'}
data_source.store()
app = login(get_app(pub))
resp = app.get('/backoffice/settings/data-sources/1/')
resp = resp.click(href='edit')
assert resp.forms[0]['name'].value == 'foobar'
resp.forms[0]['name'] = 'foobar2'
resp = resp.forms[0].submit('submit')
assert 'This name is already used' in resp.body
resp = resp.forms[0].submit('cancel')
assert resp.location == 'http://example.net/backoffice/settings/data-sources/'
def test_data_sources_delete(pub):
create_superuser(pub)
NamedDataSource.wipe()
category = NamedDataSource(name='foobar')
category.store()
FormDef.wipe()
app = login(get_app(pub))
resp = app.get('/backoffice/settings/data-sources/1/')
resp = resp.click(href='delete')
resp = resp.forms[0].submit('cancel')
assert resp.location == 'http://example.net/backoffice/settings/data-sources/'
assert NamedDataSource.count() == 1
resp = app.get('/backoffice/settings/data-sources/1/')
resp = resp.click(href='delete')
resp = resp.forms[0].submit()
assert resp.location == 'http://example.net/backoffice/settings/data-sources/'
resp = resp.follow()
assert NamedDataSource.count() == 0
def test_settings_permissions(pub):
create_superuser(pub)
role1 = create_role()
role1.name = 'foobar1'
role1.store()
role2 = Role(name='foobar2')
role2.store()
role3 = Role(name='foobar3')
role3.store()
app = login(get_app(pub))
resp = app.get('/backoffice/settings/admin-permissions')
# assert all first checkboxes are checked
assert resp.forms[0]['permissions$c-0-0'].checked
assert resp.forms[0]['permissions$c-1-0'].checked
assert resp.forms[0]['permissions$c-2-0'].checked
role2.allows_backoffice_access = False
role2.store()
resp = app.get('/backoffice/settings/admin-permissions')
assert resp.forms[0]['permissions$c-0-0'].checked
assert not resp.forms[0]['permissions$c-1-0'].checked
assert resp.forms[0]['permissions$c-2-0'].checked
resp.forms[0]['permissions$c-0-0'].checked = False
resp.forms[0]['permissions$c-1-0'].checked = True
resp = resp.forms[0].submit()
assert Role.get(role1.id).allows_backoffice_access is False
assert Role.get(role2.id).allows_backoffice_access is True
# give some roles access to the forms workshop (2nd checkbox) and to the
# workflows workshop (3rd)
resp = app.get('/backoffice/settings/admin-permissions')
resp.forms[0]['permissions$c-1-1'].checked = True
resp.forms[0]['permissions$c-2-1'].checked = True
resp.forms[0]['permissions$c-2-2'].checked = True
resp = resp.forms[0].submit()
pub.reload_cfg()
assert set(pub.cfg['admin-permissions']['forms']) == set([role2.id, role3.id])
assert set(pub.cfg['admin-permissions']['workflows']) == set([role3.id])
# remove accesses
resp = app.get('/backoffice/settings/admin-permissions')
resp.forms[0]['permissions$c-1-1'].checked = False
resp.forms[0]['permissions$c-2-1'].checked = False
resp.forms[0]['permissions$c-2-2'].checked = False
resp = resp.forms[0].submit()
pub.reload_cfg()
assert pub.cfg['admin-permissions']['forms'] == []
assert pub.cfg['admin-permissions']['workflows'] == []