Projet

Général

Profil

0002-misc-speed-up-backoffice-export-tests.patch

Lauréline Guérin, 23 octobre 2020 16:28

Télécharger (16 ko)

Voir les différences:

Subject: [PATCH 2/3] misc: speed up backoffice export tests

 tests/backoffice_pages/test_export.py | 226 +++++++++++++++++++-------
 wcs/backoffice/management.py          |   9 +-
 2 files changed, 171 insertions(+), 64 deletions(-)
tests/backoffice_pages/test_export.py
23 23
from wcs import fields
24 24

  
25 25
from utilities import get_app, login, create_temporary_pub, clean_temporary_pub
26
from test_all import create_superuser, create_environment
26
from test_all import create_superuser
27 27

  
28 28

  
29 29
def pytest_generate_tests(metafunc):
......
59 59

  
60 60
def test_backoffice_csv(pub):
61 61
    create_superuser(pub)
62
    create_environment(pub)
62

  
63
    datasource = {
64
        'type': 'formula',
65
        'value': repr([('A', 'aa'), ('B', 'bb'), ('C', 'cc')])
66
    }
67
    FormDef.wipe()
68
    formdef = FormDef()
69
    formdef.name = 'form title'
70
    formdef.fields = [
71
        fields.StringField(
72
            id='1', label='1st field', type='string',
73
            display_locations=['validation', 'summary', 'listings']),
74
        fields.ItemField(
75
            id='2', label='2nd field', type='item',
76
            items=['foo', 'bar', 'baz'],
77
            display_locations=['validation', 'summary', 'listings']),
78
        fields.ItemField(
79
            id='3', label='3rd field', type='item',
80
            data_source=datasource, varname='foo'),
81
    ]
82
    formdef.workflow_roles = {'_receiver': 1}
83
    formdef.store()
84

  
85
    formdef.data_class().wipe()
86
    for i in range(3):
87
        formdata = formdef.data_class()()
88
        formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
89
        formdata.data = {'1': 'FOO BAR %d' % i}
90
        if i == 0:
91
            formdata.data['2'] = 'foo'
92
            formdata.data['2_display'] = 'foo'
93
            formdata.data['3'] = 'A'
94
            formdata.data['3_display'] = 'aa'
95
        else:
96
            formdata.data['2'] = 'baz'
97
            formdata.data['2_display'] = 'baz'
98
            formdata.data['3'] = 'C'
99
            formdata.data['3_display'] = 'cc'
100
        if i < 2:
101
            formdata.jump_status('new')
102
        formdata.store()
103

  
63 104
    app = login(get_app(pub))
64 105
    resp = app.get('/backoffice/management/form-title/')
65 106
    resp = resp.click('Export as CSV File')
66 107
    assert resp.headers['content-type'].startswith('text/')
67
    assert len(resp.text.splitlines()) == 18 # 17 + header line
108
    assert len(resp.text.splitlines()) == 3  # 3 + header line
68 109
    assert len(resp.text.splitlines()[0].split(',')) == 7
69 110

  
70 111
    formdef = FormDef.get_by_urlname('form-title')
......
76 117

  
77 118
    # check item fields with datasources get two columns (id & text)
78 119
    assert resp.text.splitlines()[0].split(',')[6] == '3rd field'
79
    assert resp.text.splitlines()[0].split(',')[7] == '' # 3rd field, continue
80
    assert resp.text.splitlines()[1].split(',')[6] == 'A'
81
    assert resp.text.splitlines()[1].split(',')[7] == 'aa'
120
    assert resp.text.splitlines()[0].split(',')[7] == ''  # 3rd field, continue
121
    assert resp.text.splitlines()[1].split(',')[6] == 'C'
122
    assert resp.text.splitlines()[1].split(',')[7] == 'cc'
82 123

  
83 124
    resp = app.get('/backoffice/management/form-title/')
84 125
    resp.forms['listing-settings']['filter'] = 'all'
85 126
    resp = resp.forms['listing-settings'].submit()
86 127
    resp_csv = resp.click('Export as CSV File')
87
    assert len(resp_csv.text.splitlines()) == 51
128
    assert len(resp_csv.text.splitlines()) == 4
88 129

  
89 130
    # test status filter
90 131
    resp.forms['listing-settings']['filter'] = 'pending'
......
93 134
    resp.forms['listing-settings']['filter-2-value'] = 'baz'
94 135
    resp = resp.forms['listing-settings'].submit()
95 136
    resp_csv = resp.click('Export as CSV File')
96
    assert len(resp_csv.text.splitlines()) == 9
137
    assert len(resp_csv.text.splitlines()) == 2
97 138

  
98 139
    # test criteria filters
99 140
    resp.forms['listing-settings']['filter-start'].checked = True
......
108 149
    resp.forms['listing-settings']['filter-2-value'] = 'baz'
109 150
    resp = resp.forms['listing-settings'].submit()
110 151
    resp_csv = resp.click('Export as CSV File')
111
    assert len(resp_csv.text.splitlines()) == 9
152
    assert len(resp_csv.text.splitlines()) == 2
112 153
    assert 'Created' in resp_csv.text.splitlines()[0]
113 154

  
114 155
    # test column selection
......
118 159
    assert 'Created' not in resp_csv.text.splitlines()[0]
119 160

  
120 161

  
121
def test_backoffice_export_long_listings(pub):
162
@pytest.fixture
163
def threshold():
164
    from wcs.backoffice.management import FormPage
165
    FormPage.WCS_SYNC_EXPORT_LIMIT = 1
166
    yield
167
    FormPage.WCS_SYNC_EXPORT_LIMIT = 100
168

  
169

  
170
def test_backoffice_export_long_listings(pub, threshold):
122 171
    create_superuser(pub)
123
    create_environment(pub)
124
    formdef = FormDef.get_by_urlname('form-title')
125
    for i in range(100):
172

  
173
    FormDef.wipe()
174
    formdef = FormDef()
175
    formdef.name = 'form title'
176
    formdef.fields = [
177
        fields.StringField(
178
            id='1', label='1st field', type='string',
179
            display_locations=['validation', 'summary', 'listings']),
180
    ]
181
    formdef.workflow_roles = {'_receiver': 1}
182
    formdef.store()
183

  
184
    formdef.data_class().wipe()
185
    for i in range(2):
126 186
        formdata = formdef.data_class()()
127
        formdata.just_created()
128 187
        formdata.receipt_time = datetime.datetime(2015, 1, 1).timetuple()
129 188
        formdata.data = {'1': 'BAZ BAZ %d' % i}
130 189
        formdata.jump_status('new')
......
138 197
    assert 'completed' in resp.text
139 198
    resp = resp.click('Download Export')
140 199
    resp_lines = resp.text.splitlines()
141
    assert resp_lines[0] == 'Number,Created,Last Modified,User Label,1st field,2nd field,Status'
142
    assert len(resp_lines) == 118
200
    assert resp_lines[0] == 'Number,Created,Last Modified,User Label,1st field,Status'
201
    assert len(resp_lines) == 3
143 202
    assert resp_lines[1].split(',')[1].startswith(
144 203
            time.strftime('%Y-%m-%d', formdata.receipt_time))
145 204
    assert resp_lines[1].split(',')[2].startswith(
......
171 230
    fd.close()
172 231

  
173 232
    create_superuser(pub)
174
    create_environment(pub)
233

  
234
    FormDef.wipe()
235
    formdef = FormDef()
236
    formdef.name = 'form title'
237
    formdef.fields = []
238
    formdef.workflow_roles = {'_receiver': 1}
239
    formdef.store()
240

  
241
    formdef.data_class().wipe()
242
    formdata = formdef.data_class()()
243
    formdata.jump_status('new')
244
    formdata.store()
245

  
175 246
    app = login(get_app(pub))
176 247
    resp = app.get('/backoffice/management/form-title/')
177 248
    resp_csv = resp.click('Export as CSV File')
......
191 262
    fd.close()
192 263

  
193 264
    create_superuser(pub)
194
    create_environment(pub)
265

  
266
    FormDef.wipe()
267
    formdef = FormDef()
268
    formdef.name = 'form title'
269
    formdef.fields = []
270
    formdef.workflow_roles = {'_receiver': 1}
271
    formdef.store()
272

  
273
    formdef.data_class().wipe()
274
    formdata = formdef.data_class()()
275
    formdata.jump_status('new')
276
    formdata.store()
277

  
195 278
    app = login(get_app(pub))
196 279
    resp = app.get('/backoffice/management/form-title/')
197 280
    resp_csv = resp.click('Export as CSV File')
......
207 290

  
208 291
def test_backoffice_csv_export_block(pub):
209 292
    create_superuser(pub)
210
    create_environment(pub)
211 293

  
212 294
    block = BlockDef()
213 295
    block.name = 'foobar'
......
218 300
    block.digest_template = 'X{{foobar_var_foo}}Y'
219 301
    block.store()
220 302

  
221
    formdef = FormDef.get_by_urlname('form-title')
222
    formdef.fields = []
223
    formdef.store()  # make sure sql columns are removed
224

  
303
    FormDef.wipe()
304
    formdef = FormDef()
305
    formdef.name = 'form title'
225 306
    formdef.fields = [
226 307
        fields.BlockField(id='1', label='test', type='block:foobar', max_items=3),
227 308
    ]
309
    formdef.workflow_roles = {'_receiver': 1}
228 310
    formdef.store()
229 311

  
230 312
    formdef.data_class().wipe()
231 313
    formdata = formdef.data_class()()
232
    formdata.data = {}
233
    formdata.data['1'] = {
234
        'data': [
235
            {'123': 'foo', '234': 'bar'},
236
            {'123': 'foo2', '234': 'bar2'},
237
        ],
238
        'schema': {'123': 'string', '234': 'string'},
314
    formdata.data = {
315
        '1': {
316
            'data': [
317
                {'123': 'foo', '234': 'bar'},
318
                {'123': 'foo2', '234': 'bar2'},
319
            ],
320
            'schema': {'123': 'string', '234': 'string'},
321
        }
239 322
    }
240 323
    formdata.just_created()
241 324
    formdata.jump_status('new')
......
253 336

  
254 337
def test_backoffice_ods(pub):
255 338
    create_superuser(pub)
256
    create_environment(pub)
339

  
340
    FormDef.wipe()
341
    formdef = FormDef()
342
    formdef.name = 'form title'
343
    formdef.fields = [
344
        fields.FileField(
345
            id='4', label='file field', type='file',
346
            display_locations=['validation', 'summary', 'listings']),
347
        fields.DateField(
348
            id='5', label='date field', type='date',
349
            display_locations=['validation', 'summary', 'listings']),
350
        fields.StringField(
351
            id='6', label='number field', type='string',
352
            display_locations=['validation', 'summary', 'listings']),
353
        fields.StringField(
354
            id='7', label='phone field', type='string',
355
            display_locations=['validation', 'summary', 'listings']),
356
        fields.DateField(
357
            id='8', label='very old field', type='date',
358
            display_locations=['validation', 'summary', 'listings']),
359
        fields.StringField(
360
            id='9', label='string field', type='string',
361
            display_locations=['validation', 'summary', 'listings']),
362
        fields.StringField(
363
            id='10', label='number with comma field', type='string',
364
            display_locations=['validation', 'summary', 'listings']),
365
    ]
366
    formdef.workflow_roles = {'_receiver': 1}
367
    formdef.store()
368

  
257 369
    app = login(get_app(pub))
258 370
    resp = app.get('/backoffice/management/form-title/')
259 371
    resp = resp.click('Export a Spreadsheet')
260 372
    assert resp.headers['content-type'] == 'application/vnd.oasis.opendocument.spreadsheet'
261 373
    assert 'filename=form-title.ods' in resp.headers['content-disposition']
262
    assert resp.body[:2] == b'PK' # ods has a zip container
374
    assert resp.body[:2] == b'PK'  # ods has a zip container
263 375

  
264
    formdef = FormDef.get_by_urlname('form-title')
265
    formdef.fields.append(fields.FileField(id='4', label='file field', type='file',
266
        display_locations=['validation', 'summary', 'listings']))
267
    formdef.fields.append(fields.DateField(id='5', label='date field', type='date',
268
        display_locations=['validation', 'summary', 'listings']))
269
    formdef.fields.append(fields.StringField(id='6', label='number field', type='string',
270
        display_locations=['validation', 'summary', 'listings']))
271
    formdef.fields.append(fields.StringField(id='7', label='phone field', type='string',
272
        display_locations=['validation', 'summary', 'listings']))
273
    formdef.fields.append(fields.DateField(id='8', label='very old field', type='date',
274
        display_locations=['validation', 'summary', 'listings']))
275
    formdef.fields.append(fields.StringField(id='9', label='string field', type='string',
276
        display_locations=['validation', 'summary', 'listings']))
277
    formdef.fields.append(fields.StringField(id='10', label='number with comma field', type='string',
278
        display_locations=['validation', 'summary', 'listings']))
279
    formdef.store()
280

  
281
    formdata = formdef.data_class().select(lambda x: x.status == 'wf-new')[0]
282
    formdata.data['4'] = PicklableUpload('/foo/bar', content_type='text/plain')
376
    formdef.data_class().wipe()
377
    formdata = formdef.data_class()()
378
    formdata.data = {
379
        '4': PicklableUpload('/foo/bar', content_type='text/plain'),
380
        '5': time.strptime('2015-05-12', '%Y-%m-%d'),
381
        '6': '12345',
382
        '7': '0102030405',
383
        '8': time.strptime('1871-03-18', '%Y-%m-%d'),
384
        '9': 'plop\npl\x1dop',  # with control characters
385
        '10': '123,45',
386
    }
283 387
    formdata.data['4'].receive([b'hello world'])
284
    formdata.data['5'] = time.strptime('2015-05-12', '%Y-%m-%d')
285
    formdata.data['6'] = '12345'
286
    formdata.data['7'] = '0102030405'
287
    formdata.data['8'] = time.strptime('1871-03-18', '%Y-%m-%d')
288
    formdata.data['9'] = 'plop\npl\x1dop'  # with control characters
289
    formdata.data['10'] = '123,45'
388
    formdata.just_created()
389
    formdata.jump_status('new')
290 390
    formdata.store()
291 391

  
292 392
    resp = app.get('/backoffice/management/form-title/')
293 393
    resp = resp.click('Export a Spreadsheet')
294 394
    assert resp.headers['content-type'] == 'application/vnd.oasis.opendocument.spreadsheet'
295 395
    assert 'filename=form-title.ods' in resp.headers['content-disposition']
296
    assert resp.body[:2] == b'PK' # ods has a zip container
396
    assert resp.body[:2] == b'PK'  # ods has a zip container
297 397

  
298 398
    zipf = zipfile.ZipFile(BytesIO(resp.body))
299 399
    ods_sheet = ET.parse(zipf.open('content.xml'))
......
346 446
@pytest.mark.skipif('xlwt is None')
347 447
def test_backoffice_xls(pub):
348 448
    create_superuser(pub)
349
    create_environment(pub)
449

  
450
    FormDef.wipe()
451
    formdef = FormDef()
452
    formdef.name = 'form title'
453
    formdef.fields = []
454
    formdef.store()
455

  
350 456
    app = login(get_app(pub))
351 457
    resp = app.get('/backoffice/management/form-title/')
352
    assert not 'Excel Export' in resp.text
458
    assert 'Excel Export' not in resp.text
353 459

  
354 460
    if not pub.site_options.has_section('options'):
355 461
        pub.site_options.add_section('options')
wcs/backoffice/management.py
28 28
except ImportError:
29 29
    xlwt = None
30 30

  
31
from django.conf import settings
31 32
from django.utils import six
32 33
from django.utils.encoding import force_text
33 34
from django.utils.six.moves.urllib import parse as urllib
......
1033 1034
    admin_permission = 'forms'
1034 1035
    formdef_class = FormDef
1035 1036
    search_label = N_('Search in form content')
1037
    WCS_SYNC_EXPORT_LIMIT = 100  # Arbitrary threshold
1036 1038

  
1037 1039
    def __init__(self, component=None, formdef=None, view=None, update_breadcrumbs=True):
1038 1040
        self.view_type = None
......
2062 2064

  
2063 2065
        count = self.formdef.data_class().count()
2064 2066
        exporter = Exporter(self, self.formdef, fields, selected_filter)
2065
        if count > 100: # Arbitrary threshold
2067
        if count > self.WCS_SYNC_EXPORT_LIMIT:
2066 2068
            job = get_response().add_after_job(
2067 2069
                str(N_('Exporting forms in CSV')),
2068 2070
                exporter.export)
......
2172 2174

  
2173 2175
        count = self.formdef.data_class().count()
2174 2176
        exporter = Exporter(self, self.formdef, fields, selected_filter)
2175
        if count > 100: # Arbitrary threshold
2177
        if count > self.WCS_SYNC_EXPORT_LIMIT:
2176 2178
            job = get_response().add_after_job(
2177 2179
                str(N_('Exporting forms in Excel format')),
2178 2180
                exporter.export)
......
2235 2237

  
2236 2238
        count = self.formdef.data_class().count()
2237 2239
        exporter = Exporter(self, self.formdef, fields, selected_filter)
2238
        if count > 100 and not get_request().is_api_url():
2239
            # The "100" threshold is arbitrary
2240
        if count > self.WCS_SYNC_EXPORT_LIMIT and not get_request().is_api_url():
2240 2241
            job = get_response().add_after_job(
2241 2242
                str(N_('Exporting forms in Open Document format')),
2242 2243
                exporter.export)
2243
-