Projet

Général

Profil

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

Nicolas Roche, 02 janvier 2020 17:16

Télécharger (15,3 ko)

Voir les différences:

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

 tests/test_tracking_code.py | 343 +++++++++++++++++++++++++++++++++++-
 1 file changed, 341 insertions(+), 2 deletions(-)
tests/test_tracking_code.py
1 1
import pytest
2
import contextlib
3
import re
2 4

  
5
from wcs import fields
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, WorkflowBackofficeFieldsFormDef,
11
      ChoiceWorkflowStatusItem)
4 12

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

  
7 15
def pytest_generate_tests(metafunc):
8 16
    if 'pub' in metafunc.fixturenames:
......
10 18

  
11 19
@pytest.fixture
12 20
def pub(request):
13
    return create_temporary_pub(sql_mode=(request.param == 'sql'))
21
    pub = create_temporary_pub(sql_mode=(request.param == 'sql'))
22
    pub.cfg['identification'] = {'methods': ['password']}
23
    pub.cfg['language'] = {'language': 'en'}
24
    pub.write_cfg()
25
    return pub
14 26

  
15 27
def teardown_module(module):
16 28
    clean_temporary_pub()
17 29

  
30
def create_formdef():
31
    FormDef.wipe()
32
    formdef = FormDef()
33
    formdef.name = 'test'
34
    formdef.fields = []
35
    formdef.store()
36
    return formdef
37

  
38
def create_users(pub):
39
    def create_user(name):
40
        user = pub.user_class()
41
        user.email = '%s@localhost' % name
42
        user.name = name
43
        user.store()
44
        account = PasswordAccount(id=name)
45
        account.set_password(name)
46
        account.user_id = user.id
47
        account.store()
48
        return user
49

  
50
    pub.user_class.wipe()
51
    PasswordAccount.wipe()
52
    user1 = create_user('user1')
53
    user2 = create_user('user2')
54
    agent1 = create_user('agent1')
55
    agent2 = create_user('agent2')
56
    admin1 = create_user('admin1')
57
    Role.wipe()
58
    role1 = Role(name='Submiters')
59
    role1.allows_backoffice_access = True
60
    role1.store()
61
    role2 = Role(name='Receivers')
62
    role2.store()
63
    agent1.roles = [role1.id]
64
    agent1.store()
65
    agent2.roles = [role2.id]
66
    agent2.store()
67
    admin1.is_admin = True
68
    admin1.store()
69
    return None, user1, user2, agent1, agent2, admin1  # None for anonymous
70

  
71
def get_displayed_tracking_code(resp):
72
    tracking_code = None
73
    if 'Forms - test' in resp.text:
74
        # frontoffice
75
        for a_tag in resp.html.findAll('a'):
76
            if 'code/' in a_tag['href']:
77
                tracking_code = a_tag.text
78
                break
79
    elif 'Back Office of wcs - test' in resp.text:
80
        # backoffice
81
        for h3_tag in resp.html.findAll('h3'):
82
            if h3_tag.text == 'Tracking Code':
83
                tracking_code = h3_tag.next_sibling.next_element
84
                break
85
    assert tracking_code
86
    return tracking_code
87

  
18 88
def test_tracking_code(pub):
19 89
    klass = pub.tracking_code_class
20 90
    klass.wipe()
......
74 144

  
75 145
    assert marker.get('done') # makes sure we got to the real new id code
76 146
    assert klass.count() == 2
147

  
148
def test_access_to_formdata(pub, nocache):
149
    """
150
    1-  Direct access to ressources
151
     a-  Drafts
152

  
153
    | sumitter / accesser | anonymous | user1 | user2 | agent1 | agent2 | admin1 |
154
    +---------------------+-----------+-------+-------+--------+--------+--------+
155
    | anonymous           |  login    | deny  | deny  | deny   | deny   | deny   |
156
    | agent1 (submiter))  |  login    | deny  | deny  | deny   | deny   | deny   |
157
    | user1               |  login    | allow | deny  | deny   | deny   | deny   |
158

  
159
     b-  Demands
160

  
161
    | sumitter / accesser | anonymous | user1 | user2 | agent1 | agent2 | admin1 |
162
    +---------------------+-----------+-------+-------+--------+--------+--------+
163
    | anonymous           |  login    | deny  | deny  | deny   | back   | back   |
164
    | agent1 (submiter)   |  login    | deny  | deny  | deny   | back   | back   |
165
    | user1               |  login    | allow | deny  | deny   | back   | back   |
166

  
167
    2- New user on prefill fields when accessing using tracking code :
168
     a-  Drafts
169

  
170
    | sumitter / accesser | anonymous | user1 | user2 | agent1 | agent2 | admin1 |
171
    +---------------------+-----------+-------+-------+--------+--------+--------+
172
    | anonymous           | anonymous | user1 | user2 | agent1 | agent2 | admin  |
173
    | agent1 (submiter)   | anonymous | user1 | user2 | agent1 | agent2 | admin  |
174
    | user1               | anonymous | user1 | user2 | agent1 | agent2 | admin  |
175

  
176
     b-  Demands (evolving into Workflows forms)
177

  
178
    | sumitter / accesser | anonymous | user1 | user2 | agent1 | agent2 | admin1 |
179
    +---------------------+-----------+-------+-------+--------+--------+--------+
180
    | anonymous           | anonymous | anon. | anon. | anony. | anony. | anon.  |
181
    | agent1 (submiter)   | anonymous | anon. | anon. | anony. | anony. | anon.  |
182
    | user1               | user1     | user1 | user1 | user1  | user1  | user1  |
183
    """
184
    users = create_users(pub)
185
    (anonymous, user1, user2, agent1, agent2, admin1) = users
186
    tracking_code = None
187
    formdata_id = None
188
    is_draft = None
189
    formdef = create_formdef()
190
    formdef.fields = [
191
        fields.PageField(id='0', label='1st page', type='page'),
192
        fields.StringField(id='1', label='submiter', varname='submiter'),
193
        fields.CommentField(
194
            id='2', type='comment',
195
            display_locations=['validation', 'summary'],
196
            label='comment: {{form_user_display_name}}'),
197
        fields.StringField(
198
            id='3', label='prefill-1',
199
            prefill={'type': 'string',
200
                     'value': 'prefill-1: {{form_user_display_name}}'}),
201
        fields.PageField(id='4', label='2nd page', type='page'),
202
        fields.StringField(  # updated on draft using tracking code
203
            id='4', label='prefill-2a',
204
            prefill={'type': 'string',
205
                     'value': 'prefill-2a: {{form_user_display_name}}'}),
206
        ]
207
    formdef.backoffice_submission_roles = agent1.roles[:]
208
    formdef.workflow_roles = {'_receiver': agent2.roles[0]}
209
    formdef.enable_tracking_codes = True
210
    formdef.store()
211

  
212
    Workflow.wipe()
213
    workflow = Workflow(name='test')
214
    st1 = workflow.add_status('Status1')
215
    st2 = workflow.add_status('Status2')
216

  
217
    display_form = FormWorkflowStatusItem()
218
    display_form.formdef = WorkflowFormFieldsFormDef(item=display_form)
219
    display_form.formdef.fields = [
220
        fields.StringField(  # updated on workflow using tracking code
221
            id='5', label='prefill-2b',
222
            prefill={'type': 'string',
223
                     'value': 'prefill-2b: {{form_user_display_name}}'}),
224
        ]
225
    display_form.by = ['_submitter']
226
    display_form.parent = st2
227

  
228
    jump = ChoiceWorkflowStatusItem()
229
    jump.id = '_jump'
230
    jump.label = 'Go form'
231
    jump.by = ['_submitter']
232
    jump.status = st2.id
233
    jump.parent = st1
234

  
235
    st1.items.append(jump)
236
    st2.items.append(display_form)
237
    workflow.store()
238

  
239
    formdef.workflow_id = workflow.id
240
    formdef.store()
241

  
242
    @contextlib.contextmanager
243
    def submit(user, is_front=True):
244
        """submit form or draft"""
245
        pub.session_manager.session_class.wipe()
246
        app = get_app(pub)
247

  
248
        if user:
249
            app = login(app, username=user.name, password=user.name)
250
            user_label = user.name
251
        else:
252
            user_label = 'anonymous'
253
        if is_front:
254
            resp = app.get('/test/')
255
            assert '<h3>Tracking code</h3>' in resp.text
256
        else:
257
            resp = app.get('/backoffice/submission/test/')
258
            assert '<h3>Tracking Code</h3>' in resp.text
259

  
260
        formdef.data_class().wipe()
261
        resp.form['f1'] = user_label  # unused reminder
262
        resp = resp.form.submit('submit')  # submit page 1
263
        tracking_code = get_displayed_tracking_code(resp)
264

  
265
        if not is_draft:
266
            resp = resp.form.submit('submit')  # submit page 2
267
            resp = resp.form.submit('submit')  # submit form
268

  
269
        assert formdef.data_class().count() == 1
270
        formdata = formdef.data_class().select()[0]
271
        assert formdata.is_draft() == is_draft
272
        assert formdata.tracking_code == tracking_code
273
        assert user_label in formdata.data['1']
274
        yield (tracking_code, formdata.id)
275

  
276
    def check_direct_access(user, expected=None):
277
        """direct access from the URLs"""
278
        pub.session_manager.session_class.wipe()
279
        app = get_app(pub)
280
        if user:
281
            app = login(app, username=user.name, password=user.name)
282

  
283
        if is_draft:
284
            if expected == 'deny':
285
                resp = app.get('/test/%s' % formdata_id, status=403)
286
                return
287

  
288
            resp = app.get('/test/%s' % formdata_id)
289

  
290
            if expected == 'login':
291
                assert resp.location.startswith('http://example.net/login/?next=')
292
            elif expected == 'front':
293
                assert 'http://example.net/test/?mt=' in resp.location
294
                resp = resp.follow()
295
                assert '<title>Forms - test</title>' in resp.text
296
                assert get_displayed_tracking_code(resp) == tracking_code
297
            else:
298
                assert expected in ('login', 'deny', 'front')
299
        else:
300
            resp = app.get('/test/%s' % formdata_id)
301
            assert resp.location == 'http://example.net/test/%s/' % formdata_id
302

  
303
            if expected == 'deny':
304
                resp = resp.follow(status=403)
305
            elif expected == 'login':
306
                resp = resp.follow()
307
                assert resp.location.startswith('http://example.net/login/?next=')
308
            elif expected == 'front':
309
                resp = resp.follow()
310
                assert '<title>Forms - test</title>' in resp.text
311
                assert get_displayed_tracking_code(resp) == tracking_code
312
            elif expected == 'back':
313
                resp = resp.follow()
314
                assert resp.location == 'http://example.net/backoffice/management/test/%s/' % formdata_id
315
                resp = resp.follow()
316
                assert ' <title>Back Office of wcs - test - %s</title>' % formdata_id in resp.text
317
            else:
318
                assert expected in ('login', 'deny', 'front',  'back')
319

  
320
    def check_tracking_code_access(user, owner=None, new_owner=None):
321
        """
322
        load the formdata using the tracking code and prefill user name fields.
323
        new_owner is used to show that user fields change on drafts.
324
        """
325
        pub.session_manager.session_class.wipe()
326
        app = get_app(pub)
327

  
328
        # access form sumary/draft
329
        if user:
330
            app = login(app, username=user.name, password=user.name)
331
        resp = app.get('/')
332
        resp.forms[0]['code'] = tracking_code
333
        resp = resp.forms[0].submit()
334
        resp = resp.follow()
335
        resp = resp.follow()
336
        resp = resp.follow()
337
        assert '<title>Forms - test</title>' in resp.text
338

  
339
        if is_draft:
340
            resp = resp.forms[1].submit('submit')  # submit page 2
341
        else:
342
            resp = resp.form.submit('button_jump')  # go to display_form
343
            resp = resp.follow()
344

  
345
        regex2 = re.search('[>"]comment: ([^<"]*)', resp.text)
346
        regex3 = re.search('[>"]prefill-1: ([^<"]*)', resp.text)
347
        regex4 = re.search('[>"]prefill-2a: ([^<"]*)', resp.text)  # draft
348
        regex5 = re.search('[>"]prefill-2b: ([^<"]*)', resp.text)  # workflow
349

  
350
        formdata = formdef.data_class().select()[0]
351
        formdata_user = getattr(formdata.user, 'name', '')
352
        expected_owner = getattr(owner, 'name', '')
353
        expected_new_owner = getattr(new_owner, 'name', '')
354

  
355
        if is_draft:
356
            if new_owner:
357
                assert formdata_user == expected_new_owner  # !!
358
            else:  # formdata_user is not overidden by anonymous user
359
                assert formdata_user == expected_owner
360
            assert regex2.group(1) == expected_new_owner  # !!
361
            assert regex3.group(1) == expected_owner
362
            assert regex4.group(1) == expected_new_owner  # !!
363
        else:
364
            assert formdata_user == expected_owner
365
            assert regex2.group(1) == expected_owner
366
            assert regex3.group(1) == expected_owner
367
            assert regex5.group(1) == expected_owner
368

  
369
    # direct access to formdata
370
    is_draft = True  # drafts
371
    with submit(anonymous, is_front=True) as (tracking_code, formdata_id):
372
        expected = ('login', 'deny', 'deny', 'deny', 'deny', 'deny')
373
        for i in range(len(users)):
374
            check_direct_access(users[i], expected[i])
375
    with submit(agent1, is_front=False) as (tracking_code, formdata_id):
376
        expected = ('login', 'deny', 'deny', 'deny', 'deny', 'deny')
377
        for i in range(len(users)):
378
            check_direct_access(users[i], expected[i])
379
    with submit(user1, is_front=True) as (tracking_code, formdata_id):
380
        expected = ('login', 'front', 'deny', 'deny', 'deny', 'deny')
381
        for i in range(len(users)):
382
            check_direct_access(users[i], expected[i])
383

  
384
    is_draft = False  # demands
385
    with submit(anonymous, is_front=True) as (tracking_code, formdata_id):
386
        expected = ('login', 'deny', 'deny', 'deny', 'back', 'back')
387
        for i in range(len(users)):
388
            check_direct_access(users[i], expected[i])
389
    with submit(agent1, is_front=False) as (tracking_code, formdata_id):
390
        expected = ('login', 'deny', 'deny', 'deny', 'back', 'back')
391
        for i in range(len(users)):
392
            check_direct_access(users[i], expected[i])
393
    with submit(user1, is_front=True) as (tracking_code, formdata_id):
394
        expected = ('login', 'front', 'deny', 'deny', 'back', 'back')
395
        for i in range(len(users)):
396
            check_direct_access(users[i], expected[i])
397

  
398
    # access to formdata using the tracking code
399
    is_draft = True  # drafts
400
    for user in users:
401
        with submit(anonymous, is_front=True) as (tracking_code, formdata_id):
402
            check_tracking_code_access(user, owner=anonymous, new_owner=user)
403
        with submit(agent1, is_front=False) as (tracking_code, formdata_id):
404
            check_tracking_code_access(user, owner=anonymous, new_owner=user)
405
        with submit(user1, is_front=True) as (tracking_code, formdata_id):
406
            check_tracking_code_access(user, owner=user1, new_owner=user)
407

  
408
    is_draft = False  # demands
409
    for user in users:
410
        with submit(anonymous, is_front=True) as (tracking_code, formdata_id):
411
            check_tracking_code_access(user, owner=anonymous)
412
        with submit(agent1, is_front=False) as (tracking_code, formdata_id):
413
            check_tracking_code_access(user, owner=anonymous)
414
        with submit(user1, is_front=True) as (tracking_code, formdata_id):
415
            check_tracking_code_access(user, owner=user1)
77
-