Projet

Général

Profil

0001-tracking_code-add-tests-on-formdata-access-38073.patch

Nicolas Roche, 04 février 2020 13:46

Télécharger (15,8 ko)

Voir les différences:

Subject: [PATCH] tracking_code: add tests on formdata access (#38073)

 tests/test_tracking_code.py | 368 +++++++++++++++++++++++++++++++++++-
 1 file changed, 364 insertions(+), 4 deletions(-)
tests/test_tracking_code.py
1 1
import pytest
2 2

  
3
from quixote import cleanup
4
from wcs import fields
5
from wcs.admin.settings import UserFieldsFormDef
6
from wcs.wf.form import FormWorkflowStatusItem, WorkflowFormFieldsFormDef
3 7
from wcs.formdef import FormDef
8
from wcs.qommon.ident.password_accounts import PasswordAccount
9
from wcs.roles import Role
10
from wcs.workflows import Workflow, ChoiceWorkflowStatusItem
4 11

  
5
from utilities import create_temporary_pub, clean_temporary_pub
12
from utilities import get_app, login, create_temporary_pub, clean_temporary_pub
6 13

  
7 14

  
8 15
def pytest_generate_tests(metafunc):
9 16
    if 'pub' in metafunc.fixturenames:
10 17
        metafunc.parametrize('pub', ['pickle', 'sql'], indirect=True)
11 18

  
19
def teardown_module(module):
20
    clean_temporary_pub()
12 21

  
13 22
@pytest.fixture
14 23
def pub(request):
15
    return create_temporary_pub(sql_mode=(request.param == 'sql'))
24
    cleanup()
25
    pub = create_temporary_pub(sql_mode=(request.param == 'sql'))
26
    pub.cfg['identification'] = {'methods': ['password']}
27
    pub.cfg['language'] = {'language': 'en'}
28
    pub.write_cfg()
29
    return pub
16 30

  
31
@pytest.fixture
32
def users(pub):
33
    def create_user(name):
34
        user = pub.user_class()
35
        user.email = '%s@example.net' % name
36
        user.name = name
37
        user.store()
38
        account = PasswordAccount(id=name)
39
        account.set_password(name)
40
        account.user_id = user.id
41
        account.store()
17 42

  
18
def teardown_module(module):
19
    clean_temporary_pub()
43
        user_formdef = UserFieldsFormDef(pub)
44
        user_formdef.fields = [
45
            fields.StringField(
46
                id='_first_name', label='first name',
47
                type='string', extra_css_class='autocomplete-given-name'),
48
        ]
49
        user_formdef.store()
50
        user.form_data = {'_first_name': name}
51
        user.set_attributes_from_formdata(user.form_data)
52
        user.store()
53
        return user
54

  
55
    pub.user_class.wipe()
56
    PasswordAccount.wipe()
57
    user1 = create_user('user1')
58
    user2 = create_user('user2')
59
    agent1 = create_user('agent1')
60
    agent2 = create_user('agent2')
61
    admin1 = create_user('admin1')
62
    Role.wipe()
63
    role1 = Role(name='Submiters')
64
    role1.allows_backoffice_access = True
65
    role1.store()
66
    role2 = Role(name='Receivers')
67
    role2.store()
68
    agent1.roles = [role1.id]
69
    agent1.store()
70
    agent2.roles = [role2.id]
71
    agent2.store()
72
    admin1.is_admin = True
73
    admin1.store()
74
    return {
75
        'anonymous': None,
76
        'user1': user1,
77
        'user2': user2,
78
        'agent1': agent1,
79
        'agent2': agent2,
80
        'admin1': admin1,
81
    }
82

  
83
@pytest.fixture
84
def prefill_formdef(users):
85
    FormDef.wipe()
86
    formdef = FormDef()
87
    formdef.name = 'test'
88
    formdef.fields = [
89
        fields.PageField(id='0', label='1st page', type='page'),
90
        fields.CommentField(
91
            id='2', type='comment', display_locations=['validation', 'summary'],
92
            label='{{form_user_display_name}}'),
93
        fields.StringField(
94
            id='3', label='prefill-string-page1', required=False,
95
            prefill={'type': 'string', 'value': '{{form_user_display_name}}'}),
96
        fields.StringField(
97
            id='p3', label='prefill-user-page1', required=False,
98
            prefill={'type': 'user', 'value': '_first_name'}),
99

  
100
        # updated on draft using tracking code
101
        fields.PageField(id='4', label='2nd page', type='page'),
102
        fields.StringField(
103
            id='4', label='prefill-string-page2', required=False,
104
            prefill={'type': 'string', 'value': '{{form_user_display_name}}'}),
105
        fields.StringField(
106
            id='p4', label='prefill-user-page2', required=False,
107
            prefill={'type': 'user', 'value': '_first_name'}),
108
    ]
109
    formdef.backoffice_submission_roles = users['agent1'].roles[:]
110
    formdef.workflow_roles = {'_receiver': users['agent2'].roles[0]}
111
    formdef.enable_tracking_codes = True
112
    formdef.store()
113

  
114
    Workflow.wipe()
115
    workflow = Workflow(name='test')
116
    st1 = workflow.add_status('Status1')
117
    st2 = workflow.add_status('Status2')
118

  
119
    display_form = FormWorkflowStatusItem()
120
    display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
121
    display_form.formdef.fields = [
122
        # updated on workflow using tracking code
123
        fields.StringField(
124
            id='5', label='prefill-string-workflow', required=False,
125
            prefill={'type': 'string', 'value': '{{form_user_display_name}}'}),
126
        fields.StringField(
127
            id='p5', label='prefill-user-workflow', required=False,
128
            prefill={'type': 'user', 'value': '_first_name'}),
129
    ]
130
    display_form.by = ['_submitter']
131
    display_form.parent = st2
132

  
133
    jump = ChoiceWorkflowStatusItem()
134
    jump.id = '_jump'
135
    jump.label = 'Go form'
136
    jump.by = ['_submitter']
137
    jump.status = st2.id
138
    jump.parent = st1
139

  
140
    st1.items.append(jump)
141
    st2.items.append(display_form)
142
    workflow.store()
143

  
144
    formdef.workflow_id = workflow.id
145
    formdef.store()
146
    return formdef
147

  
148
def get_displayed_tracking_code(resp):
149
    tracking_code = None
150
    if 'Forms - test' in resp.text:
151
        # frontoffice
152
        for a_tag in resp.html.findAll('a'):
153
            if 'code/' in a_tag['href']:
154
                tracking_code = a_tag.text
155
                break
156
    elif 'Back Office of wcs - test' in resp.text:
157
        # backoffice
158
        for h3_tag in resp.html.findAll('h3'):
159
            if h3_tag.text == 'Tracking Code':
160
                tracking_code = h3_tag.next_sibling.next_element
161
                break
162
    assert tracking_code
163
    return tracking_code
164

  
165
def submit_prefill_demand(pub, formdef, is_draft, user, is_front=True):
166
    """submit form or draft"""
167
    app = get_app(pub)
168

  
169
    if user:
170
        app = login(app, username=user.name, password=user.name)
171
    if is_front:
172
        resp = app.get('/test/')
173
        assert '<h3>Tracking code</h3>' in resp.text
174
    else:
175
        resp = app.get('/backoffice/submission/test/')
176
        assert '<h3>Tracking Code</h3>' in resp.text
177

  
178
    formdef.data_class().wipe()
179
    resp = resp.form.submit('submit')  # submit page 1
180
    tracking_code = get_displayed_tracking_code(resp)
181

  
182
    if not is_draft:
183
        resp = resp.form.submit('submit')  # submit page 2
184
        resp = resp.form.submit('submit')  # submit form
185

  
186
    assert formdef.data_class().count() == 1
187
    formdata = formdef.data_class().select()[0]
188
    assert formdata.is_draft() == is_draft
189
    assert formdata.tracking_code == tracking_code
190
    return (tracking_code, formdata.id)
20 191

  
21 192

  
22 193
def test_tracking_code(pub):
......
79 250

  
80 251
    assert marker.get('done') # makes sure we got to the real new id code
81 252
    assert klass.count() == 2
253

  
254

  
255
@pytest.mark.parametrize("is_draft, submiter, is_front, assessor, access", [
256
    (True, 'anonymous', True, 'anonymous', 'login'),
257
    (True, 'anonymous', True, 'user1', 'deny'),
258
    (True, 'anonymous', True, 'user2', 'deny'),
259
    (True, 'anonymous', True, 'agent1', 'deny'),
260
    (True, 'anonymous', True, 'agent2', 'deny'),
261
    (True, 'anonymous', True, 'admin1', 'deny'),
262
    (True, 'agent1', False, 'anonymous', 'login'),
263
    (True, 'agent1', False, 'user1', 'deny'),
264
    (True, 'agent1', False, 'user2', 'deny'),
265
    (True, 'agent1', False, 'agent1', 'deny'),
266
    (True, 'agent1', False, 'agent2', 'deny'),
267
    (True, 'agent1', False, 'admin1', 'deny'),
268
    (True, 'user1', True, 'anonymous', 'login'),
269
    (True, 'user1', True, 'user1', 'front'),
270
    (True, 'user1', True, 'user2', 'deny'),
271
    (True, 'user1', True, 'agent1', 'deny'),
272
    (True, 'user1', True, 'agent2', 'deny'),
273
    (True, 'user1', True, 'admin1', 'deny'),
274
    (False, 'anonymous', True, 'anonymous', 'login'),
275
    (False, 'anonymous', True, 'user1', 'deny'),
276
    (False, 'anonymous', True, 'user2', 'deny'),
277
    (False, 'anonymous', True, 'agent1', 'deny'),
278
    (False, 'anonymous', True, 'agent2', 'back'),
279
    (False, 'anonymous', True, 'admin1', 'back'),
280
    (False, 'agent1', False, 'anonymous', 'login'),
281
    (False, 'agent1', False, 'user1', 'deny'),
282
    (False, 'agent1', False, 'user2', 'deny'),
283
    (False, 'agent1', False, 'agent1', 'deny'),
284
    (False, 'agent1', False, 'agent2', 'back'),
285
    (False, 'agent1', False, 'admin1', 'back'),
286
    (False, 'user1', True, 'anonymous', 'login'),
287
    (False, 'user1', True, 'user1', 'front'),
288
    (False, 'user1', True, 'user2', 'deny'),
289
    (False, 'user1', True, 'agent1', 'deny'),
290
    (False, 'user1', True, 'agent2', 'back'),
291
    (False, 'user1', True, 'admin1', 'back'),
292
])
293
def test_direct_access_to_formdata(nocache, pub, users, prefill_formdef,
294
                                   is_draft, submiter, is_front, assessor, access):
295
    (tracking_code, formdata_id) = submit_prefill_demand(
296
        pub, prefill_formdef, is_draft, users[submiter], is_front)
297

  
298
    app = get_app(pub)
299
    if assessor != 'anonymous':
300
        app = login(app, username=users[assessor].name, password=users[assessor].name)
301
    if is_draft:
302
        resp = app.get('/test/%s' % formdata_id)
303
        if access == 'deny':
304
            assert resp.follow(status=403)
305
        elif access == 'login':
306
            resp = resp.follow()
307
            assert resp.location.startswith('http://example.net/login/?next=')
308
        elif access == 'front':
309
            resp = resp.follow()
310
            assert 'http://example.net/test/?mt=' in resp.location
311
            resp = resp.follow()
312
            assert '<title>Forms - test</title>' in resp.text
313
            assert get_displayed_tracking_code(resp) == tracking_code
314
        else:
315
            assert access in ('login', 'deny', 'front')
316
    else:
317
        resp = app.get('/test/%s' % formdata_id)
318
        assert resp.location == 'http://example.net/test/%s/' % formdata_id
319
        if access == 'deny':
320
            assert resp.follow(status=403)
321
        elif access == 'login':
322
            resp = resp.follow()
323
            assert resp.location.startswith('http://example.net/login/?next=')
324
        elif access == 'front':
325
            resp = resp.follow()
326
            assert '<title>Forms - test</title>' in resp.text
327
            assert get_displayed_tracking_code(resp) == tracking_code
328
        elif access == 'back':
329
            resp = resp.follow()
330
            assert '/backoffice/management/test/%s/' % formdata_id in resp.location
331
            resp = resp.follow()
332
            assert ' <title>Back Office of wcs - test - %s</title>' % formdata_id in resp.text
333
        else:
334
            assert access in ('login', 'deny', 'front', 'back')
335

  
336

  
337
@pytest.mark.parametrize("is_draft, submiter, is_front, assessor, owner", [
338
    (True, 'anonymous', True, 'anonymous', 'anonymous'),
339
    (True, 'anonymous', True, 'user1', 'anonymous'),
340
    (True, 'anonymous', True, 'user2', 'anonymous'),
341
    (True, 'anonymous', True, 'agent1', 'anonymous'),
342
    (True, 'anonymous', True, 'agent2', 'anonymous'),
343
    (True, 'anonymous', True, 'admin1', 'anonymous'),
344
    (True, 'agent1', False, 'anonymous', 'anonymous'),
345
    (True, 'agent1', False, 'user1', 'anonymous'),
346
    (True, 'agent1', False, 'user2', 'anonymous'),
347
    (True, 'agent1', False, 'agent1', 'anonymous'),
348
    (True, 'agent1', False, 'agent2', 'anonymous'),
349
    (True, 'agent1', False, 'admin1', 'anonymous'),
350
    (True, 'user1', True, 'anonymous', 'user1'),
351
    (True, 'user1', True, 'user1', 'user1'),
352
    (True, 'user1', True, 'user2', 'user1'),
353
    (True, 'user1', True, 'agent1', 'user1'),
354
    (True, 'user1', True, 'agent2', 'user1'),
355
    (True, 'user1', True, 'admin1', 'user1'),
356
    (False, 'anonymous', True, 'anonymous', 'anonymous'),
357
    (False, 'anonymous', True, 'user1', 'anonymous'),
358
    (False, 'anonymous', True, 'user2', 'anonymous'),
359
    (False, 'anonymous', True, 'agent1', 'anonymous'),
360
    (False, 'anonymous', True, 'agent2', 'anonymous'),
361
    (False, 'anonymous', True, 'admin1', 'anonymous'),
362
    (False, 'agent1', False, 'anonymous', 'anonymous'),
363
    (False, 'agent1', False, 'user1', 'anonymous'),
364
    (False, 'agent1', False, 'user2', 'anonymous'),
365
    (False, 'agent1', False, 'agent1', 'anonymous'),
366
    (False, 'agent1', False, 'agent2', 'anonymous'),
367
    (False, 'agent1', False, 'admin1', 'anonymous'),
368
    (False, 'user1', True, 'anonymous', 'user1'),
369
    (False, 'user1', True, 'user1', 'user1'),
370
    (False, 'user1', True, 'user2', 'user1'),
371
    (False, 'user1', True, 'agent1', 'user1'),
372
    (False, 'user1', True, 'agent2', 'user1'),
373
    (False, 'user1', True, 'admin1', 'user1'),
374
])
375
def test_indirect_access_to_formdata(nocache, pub, users, prefill_formdef,
376
                                     is_draft, submiter, is_front, assessor, owner):
377
    (tracking_code, formdata_id) = submit_prefill_demand(
378
        pub, prefill_formdef, is_draft, users[submiter], is_front)
379
    user = users[assessor]
380
    owner = users[owner]
381
    new_owner = user
382

  
383
    app = get_app(pub)
384
    if user:
385
        app = login(app, username=user.name, password=user.name)
386
    resp = app.get('/')
387
    resp.forms[0]['code'] = tracking_code
388
    resp = resp.forms[0].submit()
389
    resp = resp.follow()
390
    resp = resp.follow()
391
    if is_draft:
392
        resp = resp.follow()
393
    assert '<title>Forms - test</title>' in resp.text
394

  
395
    if is_draft:
396
        resp = resp.forms[1].submit('submit')  # submit page 2
397
    else:
398
        resp = resp.form.submit('button_jump')  # go to display_form
399
        resp = resp.follow()
400

  
401
    def get_comment_value():
402
        html = resp.html.find('div', attrs={'class': 'comment-field'})
403
        if html:
404
            return html.p.text
405
        else:  # empty comment is not displayed in summary
406
            return ''
407

  
408
    def get_field_value(field_label):
409
        # validation page
410
        for html in resp.html.find_all('div', attrs={'class': 'WcsExtraStringWidget'}):
411
            if html.label.text == field_label:
412
                return html.input.get('value') or ''
413
        # summary
414
        for html in resp.html.find_all('div', attrs={'class': 'field'}):
415
            if html.span.text == field_label:
416
                return html.div.text
417
        return ''  # empty field is not displayed in summary
418

  
419
    formdata = prefill_formdef.data_class().select()[0]
420
    assert formdata.id == formdata_id  # formdata must be reloaded here
421
    formdata_user = getattr(formdata.user, 'name', '')
422
    expected_owner = getattr(owner, 'name', '')
423
    expected_new_owner = getattr(new_owner, 'name', '')
424

  
425
    if is_draft:
426
        if new_owner:
427
            assert formdata_user == expected_new_owner
428
        else:  # formdata_user is not overidden by anonymous user
429
            assert formdata_user == expected_owner
430
        assert get_comment_value() == expected_new_owner
431
        assert get_field_value('prefill-string-page1') == expected_owner
432
        assert get_field_value('prefill-user-page1') == expected_owner
433
        assert get_field_value('prefill-string-page2') == expected_new_owner
434
        assert get_field_value('prefill-user-page2') == expected_new_owner
435
    else:
436
        assert formdata_user == expected_owner
437
        assert get_comment_value() == expected_owner
438
        assert get_field_value('prefill-string-page1') == expected_owner
439
        assert get_field_value('prefill-user-page1') == expected_owner
440
        assert get_field_value('prefill-string-workflow') == expected_owner
441
        assert get_field_value('prefill-user-workflow') == expected_new_owner
82
-