870 lines
29 KiB
Python
870 lines
29 KiB
Python
import datetime
|
|
import io
|
|
import os
|
|
import time
|
|
import urllib.parse
|
|
import xml.etree.ElementTree as ET
|
|
import zipfile
|
|
|
|
import pytest
|
|
|
|
from wcs import fields
|
|
from wcs.blocks import BlockDef
|
|
from wcs.formdef import FormDef
|
|
from wcs.qommon import ods
|
|
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(emails):
|
|
pub = create_temporary_pub()
|
|
|
|
req = HTTPRequest(None, {'SCRIPT_NAME': '/', 'SERVER_NAME': 'example.net'})
|
|
pub.set_app_dir(req)
|
|
pub.cfg['identification'] = {'methods': ['password']}
|
|
pub.cfg['language'] = {'language': 'en'}
|
|
pub.write_cfg()
|
|
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
|
fd.write(
|
|
'''
|
|
[api-secrets]
|
|
coucou = 1234
|
|
'''
|
|
)
|
|
|
|
return pub
|
|
|
|
|
|
def teardown_module(module):
|
|
clean_temporary_pub()
|
|
|
|
|
|
def test_backoffice_csv(pub):
|
|
create_superuser(pub)
|
|
|
|
datasource = {'type': 'formula', 'value': repr([('A', 'aa'), ('B', 'bb'), ('C', 'cc')])}
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.StringField(
|
|
id='1', label='1st field', type='string', display_locations=['validation', 'summary', 'listings']
|
|
),
|
|
fields.ItemField(
|
|
id='2',
|
|
label='2nd field',
|
|
type='item',
|
|
items=['foo', 'bar', 'baz'],
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.ItemField(id='3', label='3rd field', type='item', data_source=datasource, varname='foo'),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
for i in range(3):
|
|
formdata = formdef.data_class()()
|
|
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
|
|
formdata.data = {'1': 'FOO BAR %d' % i}
|
|
if i == 0:
|
|
formdata.data['2'] = 'foo'
|
|
formdata.data['2_display'] = 'foo'
|
|
formdata.data['3'] = 'A'
|
|
formdata.data['3_display'] = 'aa'
|
|
else:
|
|
formdata.data['2'] = 'baz'
|
|
formdata.data['2_display'] = 'baz'
|
|
formdata.data['3'] = 'C'
|
|
formdata.data['3_display'] = 'cc'
|
|
if i < 2:
|
|
formdata.jump_status('new')
|
|
else:
|
|
formdata.status = 'draft'
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Export a Spreadsheet')
|
|
resp.form['format'] = 'csv'
|
|
resp = resp.form.submit('submit')
|
|
assert resp.headers['content-type'].startswith('text/')
|
|
assert len(resp.text.splitlines()) == 3 # 3 + header line
|
|
assert len(resp.text.splitlines()[0].split(',')) == 7
|
|
|
|
formdef = FormDef.get_by_urlname('form-title')
|
|
formdef.fields[-1].display_locations = ['validation', 'summary', 'listings']
|
|
formdef.store()
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Export a Spreadsheet')
|
|
resp.form['format'] = 'csv'
|
|
resp = resp.form.submit('submit')
|
|
assert len(resp.text.splitlines()[0].split(',')) == 9
|
|
|
|
# check item fields with datasources get two columns (id & text)
|
|
assert resp.text.splitlines()[0].split(',')[6] == '"3rd field (identifier)"'
|
|
assert resp.text.splitlines()[0].split(',')[7] == '"3rd field"'
|
|
assert resp.text.splitlines()[1].split(',')[6] == '"C"'
|
|
assert resp.text.splitlines()[1].split(',')[7] == '"cc"'
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp.forms['listing-settings']['filter'] = 'all'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert len(resp_csv.text.splitlines()) == 3
|
|
|
|
# test status filter
|
|
resp.forms['listing-settings']['filter'] = 'pending'
|
|
resp.forms['listing-settings']['filter-2'].checked = True
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp.forms['listing-settings']['filter-2-value'] = 'baz'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert len(resp_csv.text.splitlines()) == 2
|
|
|
|
# test criteria filters
|
|
resp.forms['listing-settings']['filter-start'].checked = True
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp.forms['listing-settings']['filter-start-value'] = datetime.datetime(2015, 2, 1).strftime('%Y-%m-%d')
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert len(resp_csv.text.splitlines()) == 1
|
|
|
|
resp.forms['listing-settings']['filter-start-value'] = datetime.datetime(2014, 2, 1).strftime('%Y-%m-%d')
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp.forms['listing-settings']['filter-2-value'] = 'baz'
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert len(resp_csv.text.splitlines()) == 2
|
|
assert 'Created' in resp_csv.text.splitlines()[0]
|
|
|
|
# test column selection
|
|
resp.forms['listing-settings']['time'].checked = False
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert 'Created' not in resp_csv.text.splitlines()[0]
|
|
|
|
# test no quote when exporting a single column
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {
|
|
# check characters commonly used as separators don't break the export
|
|
'1': 'delimiters ,;\t#',
|
|
'2': 'foo',
|
|
'3': 'foo',
|
|
}
|
|
formdata.store()
|
|
formdata.jump_status('new')
|
|
|
|
listing_settings = resp.forms['listing-settings']
|
|
|
|
# uncheck everything
|
|
for _, field in listing_settings.field_order:
|
|
if field.attrs.get('type', None) == 'checkbox':
|
|
field.checked = False
|
|
|
|
# check a single column
|
|
listing_settings['1'].checked = True
|
|
listing_settings['filter'] = 'all'
|
|
|
|
resp = listing_settings.submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert sorted(resp_csv.text.splitlines()) == [
|
|
'1st field',
|
|
'FOO BAR 0',
|
|
'FOO BAR 1',
|
|
'delimiters ,;\t#',
|
|
]
|
|
|
|
|
|
@pytest.fixture
|
|
def threshold():
|
|
from wcs.backoffice.management import FormPage
|
|
|
|
FormPage.WCS_SYNC_EXPORT_LIMIT = 1
|
|
yield
|
|
FormPage.WCS_SYNC_EXPORT_LIMIT = 100
|
|
|
|
|
|
def test_backoffice_export_long_listings(pub, threshold):
|
|
create_superuser(pub)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.StringField(
|
|
id='1', label='1st field', type='string', display_locations=['validation', 'summary', 'listings']
|
|
),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
for i in range(2):
|
|
formdata = formdef.data_class()()
|
|
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
|
|
formdata.data = {'1': 'BAZ BAZ %d' % i}
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Export a Spreadsheet')
|
|
resp.form['format'] = 'csv'
|
|
resp = resp.form.submit('submit')
|
|
assert resp.location.startswith('http://example.net/backoffice/processing?job=')
|
|
resp = resp.follow()
|
|
assert 'completed' in resp.text
|
|
resp = resp.click('Download Export')
|
|
resp_lines = resp.text.splitlines()
|
|
assert resp_lines[0] == '"Number","Created","Last Modified","User Label","1st field","Status"'
|
|
assert len(resp_lines) == 3
|
|
assert resp_lines[1].split(',')[1].startswith('"' + time.strftime('%Y-%m-%d', formdata.receipt_time))
|
|
assert resp_lines[1].split(',')[2].startswith('"' + time.strftime('%Y-%m-%d', formdata.last_update_time))
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Export a Spreadsheet')
|
|
resp.form['format'] = 'ods'
|
|
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')
|
|
assert resp.content_type == 'application/vnd.oasis.opendocument.spreadsheet'
|
|
|
|
# check afterjob ajax call
|
|
status_resp = app.get('/afterjobs/' + job_id)
|
|
assert status_resp.text == 'completed|completed 2/2 (100%)'
|
|
|
|
# check error handling
|
|
app.get('/afterjobs/whatever', status=404)
|
|
|
|
|
|
def test_backoffice_csv_export_channel(pub):
|
|
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)
|
|
|
|
create_superuser(pub)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
formdata = formdef.data_class()()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert 'Channel' not in resp_csv.text.splitlines()[0]
|
|
|
|
# add submission channel column
|
|
resp.forms['listing-settings']['submission_channel'].checked = True
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert resp_csv.text.splitlines()[0].split(',')[-1] == '"Channel"'
|
|
assert resp_csv.text.splitlines()[1].split(',')[-1] == '"Web"'
|
|
|
|
|
|
def test_backoffice_csv_export_anonymised(pub):
|
|
with open(os.path.join(pub.app_dir, 'site-options.cfg'), 'w') as fd:
|
|
pub.site_options.write(fd)
|
|
|
|
create_superuser(pub)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = []
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
formdata = formdef.data_class()()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert resp_csv.text.splitlines()[0].split(',')[-1] != '"Anonymised"'
|
|
|
|
# add anonymised column
|
|
resp.forms['listing-settings']['anonymised'].checked = True
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert resp_csv.text.splitlines()[0].split(',')[-1] == '"Anonymised"'
|
|
assert resp_csv.text.splitlines()[1].split(',')[-1] == '"No"'
|
|
|
|
|
|
def test_backoffice_csv_export_fields(pub):
|
|
create_superuser(pub)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string', varname='foo'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string', varname='bar'),
|
|
fields.EmailField(id='345', required=True, label='Test3', type='email', varname='email'),
|
|
fields.DateField(id='456', required=True, label='Test4', type='date', varname='date'),
|
|
fields.FileField(id='567', required=True, label='Test5', type='file', varname='file'),
|
|
fields.BoolField(id='678', required=True, label='Test6', type='bool', varname='bool'),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
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()])
|
|
|
|
formdef.data_class().wipe()
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {
|
|
'123': 'foo',
|
|
'234': 'bar',
|
|
'345': 'blah@example.invalid',
|
|
'456': time.strptime('2020-04-24', '%Y-%m-%d'),
|
|
'567': upload,
|
|
'678': True,
|
|
}
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {
|
|
'123': 'foo2',
|
|
'234': 'bar2',
|
|
'345': 'blah2@example.invalid',
|
|
'456': time.strptime('2020-04-25', '%Y-%m-%d'),
|
|
'567': upload,
|
|
'678': False,
|
|
}
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
resp.forms['listing-settings']['345'].checked = True
|
|
resp.forms['listing-settings']['456'].checked = True
|
|
resp.forms['listing-settings']['567'].checked = True
|
|
resp.forms['listing-settings']['678'].checked = True
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert resp_csv.text.splitlines()[0].split(',')[-4:] == [
|
|
'"Test3"',
|
|
'"Test4"',
|
|
'"Test5"',
|
|
'"Test6"',
|
|
]
|
|
line1 = resp_csv.text.splitlines()[1].split(',')[-4:]
|
|
line2 = resp_csv.text.splitlines()[2].split(',')[-4:]
|
|
if line1[0] == '"blah2@example.invalid"':
|
|
line1, line2 = line2, line1
|
|
assert line1 == [
|
|
'"blah@example.invalid"',
|
|
'"2020-04-24"',
|
|
'"test.jpeg"',
|
|
'"Yes"',
|
|
]
|
|
assert line2 == [
|
|
'"blah2@example.invalid"',
|
|
'"2020-04-25"',
|
|
'"test.jpeg"',
|
|
'"No"',
|
|
]
|
|
|
|
# export as ods
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv = resp_csv.form.submit('submit') # no error
|
|
|
|
|
|
def test_backoffice_csv_export_block(pub):
|
|
create_superuser(pub)
|
|
|
|
block = BlockDef()
|
|
block.name = 'foobar'
|
|
block.fields = [
|
|
fields.StringField(id='123', required=True, label='Test', type='string', varname='foo'),
|
|
fields.StringField(id='234', required=True, label='Test2', type='string', varname='bar'),
|
|
fields.EmailField(id='345', required=True, label='Test3', type='email', varname='email'),
|
|
fields.DateField(id='456', required=True, label='Test4', type='date', varname='date'),
|
|
fields.FileField(id='567', required=True, label='Test5', type='file', varname='file'),
|
|
fields.BoolField(id='678', required=True, label='Test6', type='bool', varname='bool'),
|
|
]
|
|
block.digest_template = 'X{{foobar_var_foo}}Y'
|
|
block.store()
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.BlockField(id='1', label='test', type='block:foobar', max_items=3),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
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()])
|
|
|
|
formdef.data_class().wipe()
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {
|
|
'1': {
|
|
'data': [
|
|
{
|
|
'123': 'foo',
|
|
'234': 'bar',
|
|
'345': 'blah@example.invalid',
|
|
'456': time.strptime('2020-04-24', '%Y-%m-%d'),
|
|
'567': upload,
|
|
'678': True,
|
|
},
|
|
{
|
|
'123': 'foo2',
|
|
'234': 'bar2',
|
|
'345': 'blah2@example.invalid',
|
|
'456': time.strptime('2020-04-25', '%Y-%m-%d'),
|
|
'567': upload,
|
|
'678': False,
|
|
},
|
|
],
|
|
'schema': {
|
|
'123': 'string',
|
|
'234': 'string',
|
|
'345': 'email',
|
|
'456': 'date',
|
|
'567': 'file',
|
|
'678': 'bool',
|
|
},
|
|
},
|
|
}
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
resp.forms['listing-settings']['1'].checked = True
|
|
resp.forms['listing-settings']['1-345'].checked = True
|
|
resp.forms['listing-settings']['1-456'].checked = True
|
|
resp.forms['listing-settings']['1-567'].checked = True
|
|
resp.forms['listing-settings']['1-678'].checked = True
|
|
resp = resp.forms['listing-settings'].submit()
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert resp_csv.text.splitlines()[0].split(',')[-15:] == [
|
|
'"test - 1"',
|
|
'"test - 2"',
|
|
'"test - 3"',
|
|
'"test - Test3 - 1"',
|
|
'"test - Test3 - 2"',
|
|
'"test - Test3 - 3"',
|
|
'"test - Test4 - 1"',
|
|
'"test - Test4 - 2"',
|
|
'"test - Test4 - 3"',
|
|
'"test - Test5 - 1"',
|
|
'"test - Test5 - 2"',
|
|
'"test - Test5 - 3"',
|
|
'"test - Test6 - 1"',
|
|
'"test - Test6 - 2"',
|
|
'"test - Test6 - 3"',
|
|
]
|
|
assert resp_csv.text.splitlines()[1].split(',')[-15:] == [
|
|
'"XfooY"',
|
|
'"Xfoo2Y"',
|
|
'""',
|
|
'"blah@example.invalid"',
|
|
'"blah2@example.invalid"',
|
|
'""',
|
|
'"2020-04-24"',
|
|
'"2020-04-25"',
|
|
'""',
|
|
'"test.jpeg"',
|
|
'"test.jpeg"',
|
|
'""',
|
|
'"Yes"',
|
|
'"No"',
|
|
'""',
|
|
]
|
|
|
|
# export as ods
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv = resp_csv.form.submit('submit') # no error
|
|
|
|
|
|
def test_backoffice_csv_export_table(pub):
|
|
create_superuser(pub)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.TableField(
|
|
id='1',
|
|
label='table field',
|
|
type='table',
|
|
rows=['row1', 'row2'],
|
|
columns=['col1', 'col2'],
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
)
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'1': [['a', 'b'], ['c', 'd']]}
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv.form['format'] = 'csv'
|
|
resp_csv = resp_csv.form.submit('submit')
|
|
assert resp_csv.text.splitlines()[0].split(',')[-5:] == [
|
|
'"table field - col1 / row1"',
|
|
'"col1 / row2"',
|
|
'"col2 / row1"',
|
|
'"col2 / row2"',
|
|
'"Status"',
|
|
]
|
|
assert resp_csv.text.splitlines()[1].split(',')[-5:] == [
|
|
'"a"',
|
|
'"c"',
|
|
'"b"',
|
|
'"d"',
|
|
'"New"',
|
|
]
|
|
|
|
# export as ods
|
|
resp_csv = resp.click('Export a Spreadsheet')
|
|
resp_csv = resp_csv.form.submit('submit') # no error
|
|
|
|
|
|
def test_backoffice_csv_export_ordering(pub):
|
|
create_superuser(pub)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.ItemField(
|
|
id='1',
|
|
label='field 1',
|
|
type='item',
|
|
items=['foo', 'bar', 'baz'],
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'1': 'foo', '1_display': 'foo'}
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {'1': 'bar', '1_display': 'bar'}
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp_csv = app.get('/backoffice/management/form-title/csv')
|
|
assert resp_csv.text.splitlines()[1].split(',')[-3:] == ['"-"', '"bar"', '"New"']
|
|
assert resp_csv.text.splitlines()[2].split(',')[-3:] == ['"-"', '"foo"', '"New"']
|
|
resp_csv = app.get('/backoffice/management/form-title/csv?order_by=id')
|
|
assert resp_csv.text.splitlines()[1].split(',')[-3:] == ['"-"', '"foo"', '"New"']
|
|
assert resp_csv.text.splitlines()[2].split(',')[-3:] == ['"-"', '"bar"', '"New"']
|
|
|
|
|
|
def test_backoffice_ods(pub):
|
|
create_superuser(pub)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.FileField(
|
|
id='4', label='file field', type='file', display_locations=['validation', 'summary', 'listings']
|
|
),
|
|
fields.DateField(
|
|
id='5', label='date field', type='date', display_locations=['validation', 'summary', 'listings']
|
|
),
|
|
fields.StringField(
|
|
id='6',
|
|
label='number field',
|
|
type='string',
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.StringField(
|
|
id='7',
|
|
label='phone field',
|
|
type='string',
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.DateField(
|
|
id='8',
|
|
label='very old field',
|
|
type='date',
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.StringField(
|
|
id='9',
|
|
label='string field',
|
|
type='string',
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.StringField(
|
|
id='10',
|
|
label='number with comma field',
|
|
type='string',
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.StringField(
|
|
id='11',
|
|
label='not a number, with underscore',
|
|
type='string',
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
fields.StringField(
|
|
id='12',
|
|
label='number field with zero',
|
|
type='string',
|
|
display_locations=['validation', 'summary', 'listings'],
|
|
),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Export a Spreadsheet')
|
|
resp = resp.form.submit('submit')
|
|
assert resp.headers['content-type'] == 'application/vnd.oasis.opendocument.spreadsheet'
|
|
assert 'filename=form-title.ods' in resp.headers['content-disposition']
|
|
assert resp.body[:2] == b'PK' # ods has a zip container
|
|
|
|
formdef.data_class().wipe()
|
|
formdata = formdef.data_class()()
|
|
formdata.data = {
|
|
'4': PicklableUpload('/foo/bar', content_type='text/plain'),
|
|
'5': time.strptime('2015-05-12', '%Y-%m-%d'),
|
|
'6': '12345',
|
|
'7': '0102030405',
|
|
'8': time.strptime('1871-03-18', '%Y-%m-%d'),
|
|
'9': 'plop\npl\x1dop', # with control characters
|
|
'10': ' 123,45',
|
|
'11': '1_000_000',
|
|
'12': '0',
|
|
}
|
|
formdata.data['4'].receive([b'hello world'])
|
|
formdata.just_created()
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Export a Spreadsheet')
|
|
resp = resp.form.submit('submit')
|
|
assert resp.headers['content-type'] == 'application/vnd.oasis.opendocument.spreadsheet'
|
|
assert 'filename=form-title.ods' in resp.headers['content-disposition']
|
|
assert resp.body[:2] == b'PK' # ods has a zip container
|
|
|
|
with zipfile.ZipFile(io.BytesIO(resp.body)) as zipf:
|
|
with zipf.open('content.xml') as fd:
|
|
ods_sheet = ET.parse(fd)
|
|
# check the ods contains a link to the document
|
|
elem = ods_sheet.findall('.//{%s}a' % ods.NS['text'])[0]
|
|
assert (
|
|
elem.attrib['{%s}href' % ods.NS['xlink']]
|
|
== 'http://example.net/backoffice/management/form-title/%s/files/4/bar' % formdata.id
|
|
)
|
|
resp = app.get(elem.attrib['{%s}href' % ods.NS['xlink']])
|
|
assert resp.text == 'hello world'
|
|
|
|
all_texts = [
|
|
x.text for x in ods_sheet.findall('.//{%s}table-row//{%s}p' % (ods.NS['table'], ods.NS['text']))
|
|
]
|
|
created_column = all_texts.index('Created')
|
|
date_column = all_texts.index('date field')
|
|
number_column = all_texts.index('number field')
|
|
phone_column = all_texts.index('phone field')
|
|
old_column = all_texts.index('very old field')
|
|
string_column = all_texts.index('string field')
|
|
comma_number_column = all_texts.index('number with comma field')
|
|
not_number_column = all_texts.index('not a number, with underscore')
|
|
zero_number_column = all_texts.index('number field with zero')
|
|
|
|
for row in ods_sheet.findall('.//{%s}table-row' % ods.NS['table']):
|
|
if (
|
|
row.findall('.//{%s}table-cell/{%s}p' % (ods.NS['table'], ods.NS['text']))[0].text
|
|
== formdata.get_display_id()
|
|
):
|
|
break
|
|
else:
|
|
assert False, 'failed to find data row'
|
|
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[created_column].attrib[
|
|
'{%s}value-type' % ods.NS['office']
|
|
]
|
|
== 'date'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[created_column].attrib[
|
|
'{%s}style-name' % ods.NS['table']
|
|
]
|
|
== 'DateTime'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[date_column].attrib[
|
|
'{%s}value-type' % ods.NS['office']
|
|
]
|
|
== 'date'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[date_column].attrib[
|
|
'{%s}style-name' % ods.NS['table']
|
|
]
|
|
== 'Date'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[number_column].attrib[
|
|
'{%s}value-type' % ods.NS['office']
|
|
]
|
|
== 'float'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[number_column].attrib[
|
|
'{%s}value' % ods.NS['office']
|
|
]
|
|
== '12345'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[phone_column].attrib[
|
|
'{%s}value-type' % ods.NS['office']
|
|
]
|
|
== 'string'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[old_column].attrib[
|
|
'{%s}value-type' % ods.NS['office']
|
|
]
|
|
== 'date'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[old_column].attrib[
|
|
'{%s}date-value' % ods.NS['office']
|
|
]
|
|
== '1871-03-18'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[string_column].find('{%s}p' % ods.NS['text']).text
|
|
== 'plop\nplop'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[comma_number_column].attrib[
|
|
'{%s}value' % ods.NS['office']
|
|
]
|
|
== '123.45'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[not_number_column].attrib[
|
|
'{%s}value-type' % ods.NS['office']
|
|
]
|
|
== 'string'
|
|
)
|
|
assert (
|
|
row.findall('.//{%s}table-cell' % ods.NS['table'])[zero_number_column].attrib[
|
|
'{%s}value' % ods.NS['office']
|
|
]
|
|
== '0'
|
|
)
|
|
|
|
|
|
def test_backoffice_header_line(pub):
|
|
create_superuser(pub)
|
|
|
|
FormDef.wipe()
|
|
formdef = FormDef()
|
|
formdef.name = 'form title'
|
|
formdef.fields = [
|
|
fields.StringField(
|
|
id='1', label='1st field', type='string', display_locations=['validation', 'summary', 'listings']
|
|
),
|
|
]
|
|
formdef.workflow_roles = {'_receiver': 1}
|
|
formdef.store()
|
|
|
|
formdef.data_class().wipe()
|
|
for i in range(3):
|
|
formdata = formdef.data_class()()
|
|
formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
|
|
formdata.data = {'1': 'FOO BAR %d' % i}
|
|
formdata.jump_status('new')
|
|
formdata.store()
|
|
|
|
app = login(get_app(pub))
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Export a Spreadsheet')
|
|
resp.form['format'] = 'csv'
|
|
assert resp.form['include_header_line'].checked is True
|
|
resp = resp.form.submit('submit')
|
|
assert resp.headers['content-type'].startswith('text/')
|
|
assert len(resp.text.splitlines()) == 4
|
|
|
|
resp = app.get('/backoffice/management/form-title/')
|
|
resp = resp.click('Export a Spreadsheet')
|
|
resp.form['format'] = 'csv'
|
|
resp.form['include_header_line'].checked = False
|
|
resp = resp.form.submit('submit')
|
|
assert resp.headers['content-type'].startswith('text/')
|
|
assert len(resp.text.splitlines()) == 3
|