wcs/tests/backoffice_pages/test_columns.py

818 lines
25 KiB
Python

import os
import re
import time
import pytest
from wcs import fields
from wcs.admin.settings import UserFieldsFormDef
from wcs.blocks import BlockDef
from wcs.carddef import CardDef
from wcs.formdef import FormDef
from wcs.qommon.http_request import HTTPRequest
from wcs.qommon.upload_storage import PicklableUpload
from ..utilities import clean_temporary_pub, create_temporary_pub, get_app, login
from .test_all import create_superuser
@pytest.fixture
def pub(request, emails):
pub = create_temporary_pub(sql_mode=True)
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
pub.set_app_dir(req)
pub.cfg['identification'] = {'methods': ['password']}
pub.cfg['language'] = {'language': 'en'}
pub.write_cfg()
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
fd.write(
'''
[api-secrets]
coucou = 1234
'''
)
return pub
def teardown_module(module):
clean_temporary_pub()
def test_backoffice_columns(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.geolocations = {'base': 'Geolocation'}
formdef.fields = [
fields.StringField(id='1', label='1st field', type='string', display_locations=['listings']),
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {'1': 'Foo Bar'}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert resp.text.count('</th>') == 7 # five columns
resp.forms['listing-settings']['1'].checked = False
assert 'submission_channel' not in resp.forms['listing-settings'].fields
assert 'last_update_time' in resp.forms['listing-settings'].fields
resp = resp.forms['listing-settings'].submit()
assert resp.text.count('</th>') == 6 # fixe columns
assert resp.text.count('data-link') == 1 # 1 rows
assert resp.text.count('FOO BAR') == 0 # no field 1 column
# change column order
assert (
resp.forms['listing-settings']['columns-order'].value == 'id,time,last_update_time,user-label,status'
)
resp.forms['listing-settings']['columns-order'].value = 'user-label,id,time,last_update_time,status'
resp = resp.forms['listing-settings'].submit()
assert resp.text.find('<span>User Label</span>') < resp.text.find('<span>Number</span>')
def test_backoffice_channel_column(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
if not pub.site_options.has_section('variables'):
pub.site_options.add_section('variables')
pub.site_options.set('variables', 'welco_url', 'xxx')
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
pub.site_options.write(fd)
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.geolocations = {'base': 'Geolocation'}
formdef.fields = []
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert resp.text.count('</th>') == 6 # four columns
resp.forms['listing-settings']['submission_channel'].checked = True
resp = resp.forms['listing-settings'].submit()
assert resp.text.count('</th>') == 7 # five columns
assert resp.text.count('data-link') == 1 # 1 row
assert resp.text.count('<td>Web</td>') == 1
def test_backoffice_submission_agent_column(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
agent = pub.user_class(name='agent')
agent.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.geolocations = {'base': 'Geolocation'}
formdef.fields = []
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert 'submission_agent' not in resp.forms['listing-settings'].fields
formdef.backoffice_submission_roles = [role]
formdef.store()
resp = app.get('/backoffice/management/form-title/')
assert resp.text.count('</th>') == 6 # four columns
resp.forms['listing-settings']['submission_agent'].checked = True
resp = resp.forms['listing-settings'].submit()
assert resp.text.count('</th>') == 7 # five columns
assert resp.text.count('data-link') == 1 # 1 row
assert '>agent<' not in resp.text
resp = resp.click('Export a Spreadsheet')
resp.form['format'] = 'csv'
resp = resp.form.submit('submit')
assert len(resp.text.splitlines()) == 2 # 1 + header line
assert ',"agent",' not in resp.text
for formdata in formdef.data_class().select():
formdata.submission_agent_id = str(agent.id)
formdata.store()
resp = app.get('/backoffice/management/form-title/')
resp.forms['listing-settings']['submission_agent'].checked = True
resp = resp.forms['listing-settings'].submit()
assert resp.text.count('>agent<') == 1
resp = resp.click('Export a Spreadsheet')
resp.form['format'] = 'csv'
resp = resp.form.submit('submit')
assert len(resp.text.splitlines()) == 2 # 1 + header line
assert resp.text.count(',"agent"') == 1
def test_backoffice_image_column(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.geolocations = {'base': 'Geolocation'}
formdef.fields = [
fields.FileField(
id='4', label='file field', type='file', display_locations=['validation', 'summary', 'listings']
)
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
upload = PicklableUpload('test.jpeg', 'image/jpeg')
with open(os.path.join(os.path.dirname(__file__), '..', 'image-with-gps-data.jpeg'), 'rb') as fd:
upload.receive([fd.read()])
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {'4': upload}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert 'download?f=4&thumbnail=1' not in resp.text
def test_backoffice_file_column(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.geolocations = {'base': 'Geolocation'}
formdef.fields = [
fields.FileField(
id='4', label='file field', type='file', display_locations=['validation', 'summary', 'listings']
)
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
upload = PicklableUpload('a filename that is too long "and" will be ellipsised.txt', 'text/plain')
upload.receive([b'text'])
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {'4': upload}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert 'title="a filename that is too long &quot;and&quot; will be ellipsised.txt"' in resp
assert '<span>a filename that is too(…).txt</span>' in resp
def test_backoffice_user_columns(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
user_formdef = UserFieldsFormDef(pub)
user_formdef.fields.append(fields.StringField(id='_first_name', label='name', type='string'))
user_formdef.fields.append(fields.StringField(id='3', label='test', type='string'))
user_formdef.store()
pub.cfg['users']['field_name'] = ['3', '4']
pub.write_cfg()
user1 = pub.user_class(name='userA')
user1.form_data = {'_first_name': 'toto', '3': 'nono'}
user1.set_attributes_from_formdata(user1.form_data)
user1.store()
user2 = pub.user_class(name='userB')
user2.form_data = {'_first_name': 'tutu', '3': 'nunu'}
user2.set_attributes_from_formdata(user2.form_data)
user2.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.geolocations = {'base': 'Geolocation'}
formdef.fields = []
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
for i in range(0, 2):
formdata = data_class()
formdata.data = {}
formdata.user_id = user1.id if bool(i % 2) else user2.id
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert resp.text.count('</th>') == 6 # four columns
resp.forms['listing-settings']['user-label$3'].checked = True
resp = resp.forms['listing-settings'].submit()
assert resp.text.count('</th>') == 7
assert '<td>nono</td' in resp
def test_backoffice_card_field_columns(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
datasource = {'type': 'formula', 'value': repr([('A', 'aa'), ('B', 'bb'), ('C', 'cc')])}
CardDef.wipe()
carddef = CardDef()
carddef.name = 'foo'
carddef.fields = [
fields.CommentField(id='0', label='...', type='comment'),
fields.StringField(id='1', label='Test', type='string', varname='foo'),
fields.DateField(id='2', label='Date', type='date'),
fields.BoolField(id='3', label='Bool', type='bool'),
fields.ItemField(id='4', label='Item', type='item', data_source=datasource),
]
carddef.digest_templates = {'default': 'card {{ form_var_foo }}'}
carddef.store()
carddef.data_class().wipe()
card = carddef.data_class()()
card.data = {
'1': 'plop',
'2': time.strptime('2020-04-24', '%Y-%m-%d'),
'3': True,
'4': 'A',
'4_display': 'aa',
}
card.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.geolocations = {'base': 'Geolocation'}
formdef.fields = [
fields.ItemField(
id='4', label='card field', type='item', data_source={'type': 'carddef:foo', 'value': ''}
)
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {
'4': str(card.id),
}
formdata.data['4_display'] = formdef.fields[-1].store_display_value(formdata.data, '4')
formdata.data['4_structured'] = formdef.fields[-1].store_structured_value(formdata.data, '4')
formdata.geolocations = {'base': {'lat': 48.83, 'lon': 2.32}}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert resp.text.count('</th>') == 6 # four columns
assert '4$0' not in resp.forms['listing-settings'].fields
resp.forms['listing-settings']['4$1'].checked = True
resp.forms['listing-settings']['4$2'].checked = True
resp.forms['listing-settings']['4$3'].checked = True
resp.forms['listing-settings']['4$4'].checked = True
resp = resp.forms['listing-settings'].submit()
assert resp.text.count('</th>') == 10
assert resp.text.count('data-link') == 1 # 1 row
assert resp.text.count('<td>plop</td>') == 1
assert resp.text.count('<td>2020-04-24</td>') == 1
assert resp.text.count('<td>Yes</td>') == 1
assert resp.text.count('<td>aa</td>') == 1
resp_csv = resp.click('Export a Spreadsheet')
resp_csv.form['format'] = 'csv'
resp_csv = resp_csv.form.submit('submit')
assert resp_csv.text.splitlines()[1].endswith(',"plop","2020-04-24","Yes","aa"')
resp_map = resp.click('Plot on a Map')
geojson_url = re.findall(r'data-geojson-url="(.*?)"', resp_map.text)[0]
resp_geojson = app.get(geojson_url)
assert {
'varname': None,
'label': 'card field - Test',
'value': 'plop',
'html_value': 'plop',
} in resp_geojson.json['features'][0]['properties']['display_fields']
def test_backoffice_block_columns(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
CardDef.wipe()
carddef = CardDef()
carddef.name = 'foo'
carddef.fields = [
fields.StringField(id='1', label='First Name', type='string', varname='first_name'),
fields.StringField(id='2', label='Last Name', type='string', varname='last_name'),
]
carddef.digest_templates = {'default': '{{ form_var_first_name }} {{ form_var_last_name }}'}
carddef.store()
carddef.data_class().wipe()
card = carddef.data_class()()
card.data = {
'1': 'Foo',
'2': 'Bar',
}
card.store()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.StringField(id='123', required=True, label='Test', type='string'),
fields.ItemField(id='456', label='card field', type='item', data_source={'type': 'carddef:foo'}),
]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.fields = [
fields.BlockField(id='8', label='Block', type='block:foobar', varname='data', max_items=3),
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {
'8': {
'data': [{'123': 'blah', '456': card.id, '456_display': card.default_digest}],
'schema': {}, # not important here
},
'8_display': 'blah',
}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [
'Number',
'Created',
'Last Modified',
'User Label',
'Status',
'Block',
'Block / Test',
'Block / card field',
'Anonymised',
]
resp.forms['listing-settings']['8-123'].checked = True
resp.forms['listing-settings']['8-456'].checked = True
resp = resp.forms['listing-settings'].submit()
assert '<th><span>Block / Test</span></th>' in resp
assert '<th><span>Block / card field</span></th>' in resp
assert resp.text.count('<tr') == 2
assert '<td>blah</td>' in resp
assert '<td>Foo Bar</td>' in resp
formdef.fields[0].max_items = 1
formdef.store()
resp = app.get('/backoffice/management/form-title/')
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [
'Number',
'Created',
'Last Modified',
'User Label',
'Status',
'Block',
'Block / Test',
'Block / card field',
'Anonymised',
]
resp.forms['listing-settings']['8-123'].checked = True
resp.forms['listing-settings']['8-456'].checked = True
resp = resp.forms['listing-settings'].submit()
assert '<th data-field-sort-key="f8-123"><span>Block / Test</span></th>' in resp
assert '<th data-field-sort-key="f8-456"><span>Block / card field</span></th>' in resp
def test_backoffice_block_email_column(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.EmailField(id='123', required=True, label='Test', type='email'),
]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.fields = [
fields.BlockField(id='8', label='Block', type='block:foobar', varname='data', max_items=3),
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {
'8': {
'data': [{'123': 'blah@example.invalid'}, {'123': 'blah2@example.invalid'}],
'schema': {}, # not important here
},
'8_display': 'blah',
}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [
'Number',
'Created',
'Last Modified',
'User Label',
'Status',
'Block',
'Block / Test',
'Anonymised',
]
resp.forms['listing-settings']['8-123'].checked = True
resp = resp.forms['listing-settings'].submit()
assert '<th><span>Block / Test</span></th>' in resp
# check email addresses are displayed as links
assert [(x.attrib['href'], x.text) for x in resp.pyquery('td a')][1:] == [
('mailto:blah@example.invalid', 'blah@example.invalid'),
('mailto:blah2@example.invalid', 'blah2@example.invalid'),
]
def test_backoffice_block_bool_column(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.BoolField(id='123', required=True, label='Test', type='bool'),
]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.fields = [
fields.BlockField(id='8', label='Block', type='block:foobar', varname='data', max_items=3),
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {
'8': {
'data': [
{'123': True},
{'123': False},
],
'schema': {'123': 'bool'},
},
'8_display': 'blah',
}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [
'Number',
'Created',
'Last Modified',
'User Label',
'Status',
'Block',
'Block / Test',
'Anonymised',
]
resp.forms['listing-settings']['8-123'].checked = True
resp = resp.forms['listing-settings'].submit()
assert '<th><span>Block / Test</span></th>' in resp
assert resp.text.count('<td>Yes, No</td>') == 1
def test_backoffice_block_date_column(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.DateField(id='123', required=True, label='Test', type='date'),
]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.fields = [
fields.BlockField(id='8', label='Block', type='block:foobar', varname='data', max_items=3),
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {
'8': {
'data': [
{'123': time.strptime('2020-04-24', '%Y-%m-%d')},
{'123': time.strptime('2020-04-25', '%Y-%m-%d')},
],
'schema': {'123': 'date'},
},
'8_display': 'blah',
}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [
'Number',
'Created',
'Last Modified',
'User Label',
'Status',
'Block',
'Block / Test',
'Anonymised',
]
resp.forms['listing-settings']['8-123'].checked = True
resp = resp.forms['listing-settings'].submit()
assert '<th><span>Block / Test</span></th>' in resp
assert resp.text.count('<td>2020-04-24, 2020-04-25</td>') == 1
def test_backoffice_block_file_column(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.FileField(id='123', required=True, label='Test', type='file'),
]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.fields = [
fields.BlockField(id='8', label='Block', type='block:foobar', varname='data', max_items=3),
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
upload = PicklableUpload('test.txt', 'text/plain')
upload.receive([b'text'])
formdata = data_class()
formdata.data = {
'8': {
'data': [
{'123': upload},
{'123': upload},
],
'schema': {'123': 'file'},
},
'8_display': 'blah',
}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [
'Number',
'Created',
'Last Modified',
'User Label',
'Status',
'Block',
'Block / Test',
'Anonymised',
]
resp.forms['listing-settings']['8-123'].checked = True
resp = resp.forms['listing-settings'].submit()
assert '<th><span>Block / Test</span></th>' in resp
assert resp.text.count('<span>test.txt</span>') == 2
def test_backoffice_block_column_position(pub):
pub.user_class.wipe()
create_superuser(pub)
pub.role_class.wipe()
role = pub.role_class(name='test')
role.store()
BlockDef.wipe()
block = BlockDef()
block.name = 'foobar'
block.fields = [
fields.StringField(id='123', required=True, label='Test', type='string'),
]
block.store()
FormDef.wipe()
formdef = FormDef()
formdef.name = 'form-title'
formdef.fields = [
fields.BlockField(id='8', label='Block', type='block:foobar', varname='data', max_items=3),
]
formdef.workflow_roles = {'_receiver': role.id}
formdef.store()
data_class = formdef.data_class()
data_class.wipe()
formdata = data_class()
formdata.data = {
'8': {
'data': [
{'123': 'foo'},
],
'schema': {'123': 'string'}, # not important here
},
'8_display': 'blah',
}
formdata.just_created()
formdata.jump_status('new')
formdata.store()
app = login(get_app(pub))
resp = app.get('/backoffice/management/form-title/')
assert [x.text_content() for x in resp.pyquery('#columns-filter label')] == [
'Number',
'Created',
'Last Modified',
'User Label',
'Status',
'Block',
'Block / Test',
'Anonymised',
]
resp.forms['listing-settings']['time'].checked = False
resp.forms['listing-settings']['last_update_time'].checked = False
resp.forms['listing-settings']['8-123'].checked = True
resp = resp.forms['listing-settings'].submit()
assert '<th><span>Block / Test</span></th>' in resp
assert resp.text.count('<td>foo</td>') == 1
assert resp.forms['listing-settings']['columns-order'].value == 'id,user-label,status,8-123'
assert resp.pyquery('tbody tr td').text().strip() == '1-1 - New foo' # block value is last
resp.forms['listing-settings']['columns-order'].value = 'id,user-label,8-123,status'
resp = resp.forms['listing-settings'].submit()
assert resp.pyquery('tbody tr td').text().strip() == '1-1 - foo New' # status is last