Projet

Général

Profil

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

Nicolas Roche, 04 février 2020 19:00

Télécharger (14,3 ko)

Voir les différences:

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

 tests/test_tracking_code.py | 339 +++++++++++++++++++++++++++++++++++-
 1 file changed, 335 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
3 6
from wcs.formdef import FormDef
7
from wcs.qommon.ident.password_accounts import PasswordAccount
8
from wcs.roles import Role
9
from wcs.wf.form import FormWorkflowStatusItem, WorkflowFormFieldsFormDef
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='Submitters')
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, submitter, 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, submitter, is_front, assessor, access):
295
    (tracking_code, formdata_id) = submit_prefill_demand(
296
        pub, prefill_formdef, is_draft, users[submitter], 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("assessor", [
338
    ('anonymous'), ('user1'), ('user2'), ('agent1'), ('agent2'), ('admin1')])
339
@pytest.mark.parametrize("submitter, is_front, expected_owner", [
340
    ('anonymous', True, 'anonymous'),
341
    ('agent1', False, 'anonymous'),
342
    ('user1', True, 'user1'),
343
])
344
@pytest.mark.parametrize("is_draft", [(True), (False)])
345
def test_indirect_access_to_formdata(
346
        nocache, pub, users, prefill_formdef,
347
        is_draft, submitter, is_front, assessor, expected_owner):
348
    (tracking_code, formdata_id) = submit_prefill_demand(
349
        pub, prefill_formdef, is_draft, users[submitter], is_front)
350
    user = users[assessor]
351
    expected_owner = users[expected_owner]
352
    expected_new_owner = user
353

  
354
    app = get_app(pub)
355
    if user:
356
        app = login(app, username=user.name, password=user.name)
357
    resp = app.get('/')
358
    resp.forms[0]['code'] = tracking_code
359
    resp = resp.forms[0].submit()
360
    resp = resp.follow()
361
    resp = resp.follow()
362
    if is_draft:
363
        resp = resp.follow()
364
    assert '<title>Forms - test</title>' in resp.text
365

  
366
    if is_draft:
367
        resp = resp.forms[1].submit('submit')  # submit page 2
368
    else:
369
        resp = resp.form.submit('button_jump')  # go to display_form
370
        resp = resp.follow()
371

  
372
    def get_comment_value():
373
        html = resp.html.find('div', attrs={'class': 'comment-field'})
374
        if html:
375
            return html.p.text
376
        else:  # empty comment is not displayed in summary
377
            return ''
378

  
379
    def get_field_value(field_label):
380
        # validation page
381
        for html in resp.html.find_all('div', attrs={'class': 'WcsExtraStringWidget'}):
382
            if html.label.text == field_label:
383
                return html.input.get('value') or ''
384
        # summary
385
        for html in resp.html.find_all('div', attrs={'class': 'field'}):
386
            if html.span.text == field_label:
387
                return html.div.text
388
        return ''  # empty field is not displayed in summary
389

  
390
    formdata = prefill_formdef.data_class().select()[0]
391
    assert formdata.id == formdata_id  # formdata must be reloaded here
392
    formdata_user = getattr(formdata.user, 'name', '')
393
    owner_value = getattr(expected_owner, 'name', '')
394
    new_owner_value = getattr(expected_new_owner, 'name', '')
395

  
396
    if is_draft:
397
        if expected_new_owner:
398
            assert formdata_user == new_owner_value
399
        else:  # formdata_user is not overidden by anonymous user
400
            assert formdata_user == owner_value
401
        assert get_comment_value() == new_owner_value
402
        assert get_field_value('prefill-string-page1') == owner_value
403
        assert get_field_value('prefill-user-page1') == owner_value
404
        assert get_field_value('prefill-string-page2') == new_owner_value
405
        assert get_field_value('prefill-user-page2') == new_owner_value
406
    else:
407
        assert formdata_user == owner_value
408
        assert get_comment_value() == owner_value
409
        assert get_field_value('prefill-string-page1') == owner_value
410
        assert get_field_value('prefill-user-page1') == owner_value
411
        assert get_field_value('prefill-string-workflow') == owner_value
412
        assert get_field_value('prefill-user-workflow') == new_owner_value
82
-