wcs/tests/admin_pages/test_settings.py

805 lines
30 KiB
Python

import io
import os
import urllib.parse
import zipfile
try:
import lasso # pylint: disable=unused-import
except ImportError:
lasso = None
import pytest
import responses
from quixote.http_request import Upload as QuixoteUpload
from webtest import Upload
from wcs import fields
from wcs.api_access import ApiAccess
from wcs.carddef import CardDef
from wcs.categories import (
BlockCategory,
CardDefCategory,
Category,
DataSourceCategory,
MailTemplateCategory,
WorkflowCategory,
)
from wcs.data_sources import NamedDataSource
from wcs.formdef import FormDef
from wcs.qommon.form import UploadedFile
from wcs.qommon.http_request import HTTPRequest
from wcs.wf.export_to_model import ExportToModel
from wcs.workflows import Workflow
from wcs.wscalls import NamedWsCall
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
from .test_all import create_superuser
@pytest.fixture
def pub():
pub = create_temporary_pub()
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
pub.cfg['identification'] = {'methods': ['password']}
pub.cfg['language'] = {'language': 'en'}
pub.write_cfg()
return pub
def teardown_module(module):
clean_temporary_pub()
def test_settings(pub):
create_superuser(pub)
app = login(get_app(pub))
app.get('/backoffice/settings/')
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/admin-permissions')
def test_settings_disabled_screens(pub):
create_superuser(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/settings/')
assert 'Identification' in resp.text
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'settings-disabled-screens', 'identification')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
resp = app.get('/backoffice/settings/')
assert 'Identification' not in resp.text
def test_settings_export_import(pub):
def wipe():
FormDef.wipe()
CardDef.wipe()
Workflow.wipe()
pub.role_class.wipe()
Category.wipe()
CardDefCategory.wipe()
WorkflowCategory.wipe()
NamedDataSource.wipe()
NamedWsCall.wipe()
ApiAccess.wipe()
BlockCategory.wipe()
MailTemplateCategory.wipe()
DataSourceCategory.wipe()
wipe()
create_superuser(pub)
app = login(get_app(pub))
resp = app.get('/backoffice/settings/export')
resp = resp.form.submit('cancel')
resp = app.get('/backoffice/settings/export')
resp = resp.form.submit('submit')
assert resp.location.startswith('http://example.net/backoffice/processing?job=')
job_id = urllib.parse.parse_qs(urllib.parse.urlparse(resp.location).query)['job'][0]
resp = resp.follow()
assert 'completed' in resp.text
resp = resp.click('Download Export')
zip_content = io.BytesIO(resp.body)
with zipfile.ZipFile(zip_content, 'a') as zipf:
filelist = zipf.namelist()
assert len(filelist) == 0
# check afterjob ajax call
status_resp = app.get('/afterjobs/' + job_id)
assert status_resp.text == 'completed|completed'
formdef = FormDef()
formdef.name = 'foo'
formdef.store()
carddef = CardDef()
carddef.name = 'bar'
carddef.store()
Category(name='baz').store()
Category(name='baz2').store()
CardDefCategory(name='foobar').store()
WorkflowCategory(name='foobaz').store()
BlockCategory(name='category for blocks').store()
MailTemplateCategory(name='category for mail templates').store()
DataSourceCategory(name='category for data sources').store()
pub.role_class(name='qux').store()
NamedDataSource(name='quux').store()
ds = NamedDataSource(name='agenda')
ds.external = 'agenda'
ds.store()
NamedWsCall(name='corge').store()
wf = Workflow(name='bar')
st1 = wf.add_status('Status1', 'st1')
export_to = ExportToModel()
export_to.label = 'test'
upload = QuixoteUpload('/foo/bar', content_type='application/vnd.oasis.opendocument.text')
file_content = b'''PK\x03\x04\x14\x00\x00\x08\x00\x00\'l\x8eG^\xc62\x0c\'\x00'''
upload.fp = io.BytesIO()
upload.fp.write(file_content)
upload.fp.seek(0)
export_to.model_file = UploadedFile('models', 'export_to_model-1.upload', upload)
st1.items.append(export_to)
export_to.parent = st1
wf.store()
api_access = ApiAccess()
api_access.name = 'Jhon'
api_access.api_identifier = 'jhon'
api_access.api_key = '1234'
api_access.store()
resp = app.get('/backoffice/settings/export')
resp = resp.form.submit('submit').follow()
resp = resp.click('Download Export')
zip_content = io.BytesIO(resp.body)
with zipfile.ZipFile(zip_content, 'a') as zipf:
filelist = zipf.namelist()
assert 'formdefs/1' not in filelist
assert 'formdefs_xml/1' in filelist
assert 'carddefs/1' not in filelist
assert 'carddefs_xml/1' in filelist
assert 'workflows/1' not in filelist
assert 'workflows_xml/1' in filelist
assert 'models/export_to_model-1.upload' not in filelist
assert 'roles/1' not in filelist
assert 'roles_xml/1' in filelist
assert 'categories/1' in filelist
assert 'carddef_categories/1' in filelist
assert 'workflow_categories/1' in filelist
assert 'block_categories/1' in filelist
assert 'data_source_categories/1' in filelist
assert 'mail_template_categories/1' in filelist
assert 'datasources/1' in filelist
assert 'datasources/2' not in filelist # agenda datasource, not exported
assert 'wscalls/corge' in filelist
assert 'apiaccess/1' in filelist
for filename in filelist:
assert '.indexes' not in filename
wipe()
assert FormDef.count() == 0
resp = app.get('/backoffice/settings/import')
assert 'This site has existing' not in resp.text
resp = resp.form.submit('cancel')
resp = app.get('/backoffice/settings/import')
resp.form['file'] = Upload('export.wcs', b'invalid content')
resp = resp.form.submit('submit')
assert 'Error: Not a valid export file' in resp.text
resp = app.get('/backoffice/settings/import')
resp.form['file'] = Upload('export.wcs', zip_content.getvalue())
resp = resp.form.submit('submit')
assert 'Imported successfully' in resp.text
assert '1 form' in resp.text
assert '1 card' in resp.text
assert '2 categories' in resp.text
assert '1 card category' in resp.text
assert '1 workflow category' in resp.text
assert FormDef.count() == 1
assert FormDef.select()[0].url_name == 'foo'
assert CardDef.count() == 1
assert CardDef.select()[0].url_name == 'bar'
assert BlockCategory.count() == 1
assert MailTemplateCategory.count() == 1
assert DataSourceCategory.count() == 1
assert ApiAccess.count() == 1
assert pub.role_class.count() == 1
# check roles are found by name
wipe()
role = pub.role_class(name='qux')
role.store()
workflow = Workflow(name='Workflow One')
st1 = workflow.add_status(name='st1')
commentable = st1.add_action('commentable', id='_commentable')
commentable.by = [role.id]
commentable.label = 'foobar'
workflow.store()
formdef = FormDef()
formdef.name = 'foo'
formdef.workflow_id = workflow.id
formdef.roles = [role.id]
formdef.backoffice_submission_roles = [role.id]
formdef.workflow_roles = {'_receiver': role.id}
formdef.fields = [fields.StringField(id='1', type='string', data_source={'type': 'carddef:unknown'})]
formdef.store()
resp = app.get('/backoffice/settings/export')
resp.form['formdefs'] = True
resp.form['workflows'] = True
resp.form['roles'] = False
resp.form['categories'] = False
resp.form['datasources'] = False
resp.form['wscalls'] = False
resp = resp.form.submit('submit').follow()
resp = resp.click('Download Export')
zip_content = io.BytesIO(resp.body)
with zipfile.ZipFile(zip_content, 'a') as zipf:
filelist = zipf.namelist()
assert 'formdefs_xml/%s' % formdef.id in filelist
assert 'workflows_xml/%s' % workflow.id in filelist
assert 'roles_xml/%s' % role.id not in filelist
FormDef.wipe()
Workflow.wipe()
pub.role_class.wipe()
# create role beforehand, it should be matched by name
role = pub.role_class(name='qux')
role.id = '012345'
role.store()
resp = app.get('/backoffice/settings/import')
resp.form['file'] = Upload('export.wcs', zip_content.getvalue())
resp = resp.form.submit('submit')
assert FormDef.select()[0].roles == ['012345']
assert FormDef.select()[0].backoffice_submission_roles == ['012345']
assert FormDef.select()[0].workflow_roles == {'_receiver': '012345'}
assert len(FormDef.select()[0].fields) == 1
assert Workflow.select()[0].possible_status[0].items[0].by == ['012345']
# do not export roles when managed by idp
pub.cfg['sp'] = {'idp-manage-roles': True}
pub.write_cfg()
resp = app.get('/backoffice/settings/export')
resp = resp.form.submit('submit').follow()
resp = resp.click('Download Export')
zip_content = io.BytesIO(resp.body)
with zipfile.ZipFile(zip_content, 'a') as zipf:
filelist = zipf.namelist()
assert len([x for x in filelist if 'roles_xml/' in x]) == 0
# check a warning is displayed if there's some content already
resp = app.get('/backoffice/settings/import')
assert 'This site has existing' in resp.text
# check an error is displayed if such an import is then used and roles are
# missing.
FormDef.wipe()
Workflow.wipe()
pub.role_class.wipe()
resp = app.get('/backoffice/settings/import')
resp.form['file'] = Upload('export.wcs', zip_content.getvalue())
resp = resp.form.submit('submit')
assert 'Unknown referenced objects [Unknown roles: qux]' in resp
# unknown field block
Workflow.wipe()
formdef = FormDef()
formdef.name = 'foo'
formdef.fields = [fields.BlockField(id='1', type='block:unknown')]
formdef.store()
resp = app.get('/backoffice/settings/export')
resp = resp.form.submit('submit').follow()
resp = resp.click('Download Export')
zip_content = io.BytesIO(resp.body)
resp = app.get('/backoffice/settings/import')
resp.form['file'] = Upload('export.wcs', zip_content.getvalue())
resp = resp.form.submit('submit')
assert 'Unknown referenced objects [Unknown fields blocks: unknown]' in resp
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[3]['label'] = 'foobar'
resp = resp.forms[3].submit()
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
resp = resp.follow()
assert b'foobar' in pub.cfg['users']['formdef']
assert 'foobar' in resp.text
# set field as email
resp.forms['mapping']['field_email'] = '1'
resp = resp.forms['mapping'].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['mapping']['field_email'] = ''
resp = resp.forms['mapping'].submit()
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
resp = resp.follow()
assert pub.cfg['users']['field_email'] is None
# add a comment field
resp.forms[3]['label'] = 'barfoo'
resp.forms[3]['type'] = 'comment'
resp = resp.forms[3].submit()
assert resp.location == 'http://example.net/backoffice/settings/users/fields/'
resp = resp.follow()
assert b'barfoo' in pub.cfg['users']['formdef']
assert 'barfoo' in resp.text
# check fields are present in edit form
resp = app.get('/backoffice/users/%s/edit' % user.id)
assert 'barfoo' in resp.text
assert 'f1' in resp.form.fields
assert 'email' in resp.form.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.form.fields
assert 'email' not in resp.form.fields
# set a sidebar template
app = login(get_app(pub))
resp = app.get('/backoffice/settings/users').follow().follow()
resp.forms['template']['sidebar_template'] = 'hello {{ form_user_display_name }}'
resp = resp.forms['template'].submit().follow()
assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}'
resp.forms['template']['sidebar_template'] = '{% if True %}'
resp = resp.forms['template'].submit().follow()
assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}'
assert 'syntax error in Django template' in resp
# set a search result template
resp = app.get('/backoffice/settings/users/fields/')
assert 'search_result_template' not in pub.cfg['users']
assert resp.forms['search_result_template']['search_result_template'].value.replace('\n', '') == (
'{{ user_email|default:"" }}'
'{% if user_var_phone %} 📞 {{ user_var_phone }}{% endif %}'
'{% if user_var_mobile %} 📱 {{ user_var_mobile }}{% endif %}'
'{% if user_var_address or user_var_zipcode or user_var_city %} 📨{% endif %}'
'{% if user_var_address %} {{ user_var_address }}{% endif %}'
'{% if user_var_zipcode %} {{ user_var_zipcode }}{% endif %}'
'{% if user_var_city %} {{ user_var_city }}{% endif %}'
)
resp.forms['search_result_template']['search_result_template'] = '{{ user_email|default:"" }} Foo Bar'
resp = resp.forms['search_result_template'].submit().follow()
assert pub.cfg['users']['search_result_template'] == '{{ user_email|default:"" }} Foo Bar'
# disable users screen
if not pub.site_options.has_section('options'):
pub.site_options.add_section('options')
pub.site_options.set('options', 'settings-disabled-screens', 'users')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
resp = app.get('/backoffice/settings/')
resp = resp.click('Users', href='user-templates')
resp.forms['template']['sidebar_template'] = '{% if True %}'
resp = resp.forms['template'].submit()
assert 'syntax error in Django template' in resp
resp.forms['template']['sidebar_template'] = 'hello {{ form_user_display_name }}'
resp.forms['template']['search_result_template'] = '{{ form_user_display_name }}'
resp = resp.forms['template'].submit()
assert pub.cfg['users']['sidebar_template'] == 'hello {{ form_user_display_name }}'
assert pub.cfg['users']['search_result_template'] == '{{ form_user_display_name }}'
# 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 <foo@example.net>' in resp.text
resp.form['from'] = 'test@localhost'
resp = resp.form.submit('submit')
pub.reload_cfg()
assert pub.cfg['emails']['from'] == 'test@localhost'
assert pub.cfg['emails']['well_known_domains']
assert pub.cfg['emails']['valid_known_domains']
pub.cfg['debug'] = {}
pub.write_cfg()
resp = app.get('/backoffice/settings/emails/')
resp = resp.click('General Options')
assert 'Warning: all emails are sent to <foo@example.net>' not in resp.text
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
# disable password authentication method
pub.cfg['identification'] = {'methods': []}
pub.write_cfg()
resp = app.get('/backoffice/settings/emails/')
assert 'Approval of new account' not in resp.text
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'] is None
# disable password authentication method
pub.cfg['identification'] = {'methods': []}
pub.write_cfg()
resp = app.get('/backoffice/settings/texts/')
assert 'Text on top of the login page' not in resp.text
@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 'identification/password/' not in resp.text
assert 'identification/idp/' not in resp.text
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.text
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.text
assert pub.cfg['identification']['methods'] == ['password']
@pytest.mark.skipif('lasso is None')
def test_settings_idp(pub):
# create admin session
create_superuser(pub)
app = login(get_app(pub))
pub.cfg['identification'] = {'methods': ['idp']}
pub.write_cfg()
app.get('/saml/metadata', status=404)
resp = app.get('/backoffice/settings/')
resp = resp.click(href='identification/idp/')
resp = resp.click('Service Provider')
resp = resp.form.submit('generate_rsa').follow()
resp = resp.form.submit('submit')
resp = resp.follow()
resp2 = resp.click('Identities')
resp2 = resp2.form.submit('cancel').follow()
resp2 = resp.click('Identities')
resp2 = resp2.form.submit('submit')
resp_metadata = app.get('/saml/metadata', status=200)
assert resp_metadata.text.startswith('<?xml')
resp2 = resp.click('Identity Providers')
resp2 = resp2.click('New')
idp_metadata_filename = os.path.join(os.path.dirname(__file__), '..', 'idp_metadata.xml')
with open(idp_metadata_filename, 'rb') as fd:
resp2.form['metadata'] = Upload('idp_metadata.xml', fd.read())
resp2 = resp2.form.submit('submit')
resp = resp.click('Identity Providers')
assert 'http://authentic.example.net/' in resp.text
resp2 = resp.click(href='http-authentic.example.net-idp-saml2-metadata/', index=0)
assert 'ns0:EntityDescriptor' in resp2.text
resp = resp.click(href='http-authentic.example.net-idp-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://authentic.example.net/idp/saml2/sso?SAMLRequest')
resp = resp.click(href='/backoffice/settings/identification/idp/idp/', index=0) # breadcrumb
resp = resp.click(href='http-authentic.example.net-idp-saml2-metadata/delete')
resp = resp.forms[0].submit() # confirm delete
assert len(pub.cfg['idp']) == 0
with responses.RequestsMock() as rsps:
idp_metadata_filename = os.path.join(os.path.dirname(__file__), '..', 'idp_metadata.xml')
with open(idp_metadata_filename, 'rb') as body:
rsps.get('http://authentic.example.net/idp/saml2/metadata', body=body.read())
resp = app.get('/backoffice/settings/identification/idp/idp/')
resp = resp.click('Create new from remote URL')
resp.form['metadata_url'] = 'http://authentic.example.net/idp/saml2/metadata'
resp = resp.form.submit('submit')
resp = resp.follow()
assert 'http://authentic.example.net/idp/saml2/metadata' in resp.text
assert len(rsps.calls) == 1
resp = resp.click('View')
resp = resp.click('Update from remote URL')
assert len(rsps.calls) == 2
def test_settings_auth_password(pub):
pub.role_class.wipe()
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()
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.text
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 (.' in resp.text
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.text
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.text
resp = app.get('/backoffice/settings/filetypes/')
resp = resp.forms[0].submit('submit')
assert 'This field is required.' in resp
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.text
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form title'
formdef.fields = [
fields.FileField(
id='1',
label='1st field',
type='file',
document_type={
'id': 1,
'mimetypes': ['application/pdf', 'application/msword'],
'label': 'Text files',
},
)
]
formdef.store()
assert FormDef.get(formdef.id).fields[0].document_type == {
'id': 1,
'mimetypes': ['application/pdf', 'application/msword'],
'label': 'Text files',
}
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].document_type == {
'id': 1,
'mimetypes': [
'application/vnd.oasis.opendocument.text',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'application/pdf',
],
'label': 'Text files',
}
resp = app.get('/backoffice/settings/filetypes/')
resp = resp.click('Text files')
resp.forms[0]['mimetypes'] = ''
resp = resp.forms[0].submit('submit')
assert 'This field is required.' in resp
def test_settings_geolocation(pub):
create_superuser(pub)
app = login(get_app(pub))
assert pub.get_default_zoom_level() == '13'
resp = app.get('/backoffice/settings/')
resp = resp.click('Geolocation')
resp.form['default-position$latlng'].value = '1.234;-1.234'
resp = resp.form.submit('cancel').follow()
resp = resp.click('Geolocation')
assert 'value="1.234;-1.234' not in resp.text
resp.form['default-position$latlng'].value = '1.234;-1.234'
resp = resp.form.submit().follow()
resp = resp.click('Geolocation')
assert 'value="1.234;-1.234' in resp.text
pub.reload_cfg()
assert pub.cfg['misc']['default-position'] == '1.234;-1.234'
assert pub.cfg['misc']['default-zoom-level'] == '13'
resp = resp.click('Geolocation')
resp.form['default-zoom-level'] = '16'
resp = resp.form.submit().follow()
assert pub.cfg['misc']['default-zoom-level'] == '16'
def test_settings_permissions(pub):
create_superuser(pub)
pub.role_class.wipe()
role1 = pub.role_class(name='foobar1')
role1.store()
role2 = pub.role_class(name='foobar2')
role2.store()
role3 = pub.role_class(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 pub.role_class.get(role1.id).allows_backoffice_access is False
assert pub.role_class.get(role2.id).allows_backoffice_access is True
# give some roles access to the forms workshop (2nd checkbox) and to the
# workflows workshop (4th)
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-3'].checked = True
resp = resp.forms[0].submit()
pub.reload_cfg()
assert set(pub.cfg['admin-permissions']['forms']) == {role2.id, role3.id}
assert set(pub.cfg['admin-permissions']['workflows']) == {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-3'].checked = False
resp = resp.forms[0].submit()
pub.reload_cfg()
assert pub.cfg['admin-permissions']['forms'] == []
assert pub.cfg['admin-permissions']['workflows'] == []
def test_postgresql_settings(pub):
create_superuser(pub)
database = pub.cfg['postgresql']['database']
assert pub.cfg['postgresql'].get('port') is None
app = login(get_app(pub))
resp = app.get('/backoffice/settings/postgresql')
assert resp.form['database'].value == database
assert resp.form['port'].value == ''
resp = resp.form.submit()
assert pub.cfg['postgresql']['port'] is None
pub.cfg['postgresql']['port'] = 5432
pub.write_cfg()
resp = app.get('/backoffice/settings/postgresql')
assert resp.form['port'].value == '5432'
resp = resp.form.submit()
assert pub.cfg['postgresql']['port'] == 5432
resp = app.get('/backoffice/settings/postgresql')
resp.form['port'] = ''
resp = resp.form.submit()
assert pub.cfg['postgresql']['port'] is None
pub.cfg['postgresql']['port'] = '5432' # from an old convert-to-sql (before #10170)
pub.write_cfg()
resp = app.get('/backoffice/settings/postgresql')
assert resp.form['port'].value == '5432'
resp = resp.form.submit()
assert pub.cfg['postgresql']['port'] == 5432