Projet

Général

Profil

0001-forms-display-a-tracking-code-on-first-page-8760.patch

Frédéric Péters, 22 octobre 2015 20:42

Télécharger (9,35 ko)

Voir les différences:

Subject: [PATCH] forms: display a tracking code on first page (#8760)

It will only get turned into a proper formdata when data are saved, either by
going to the next page or by the javascript autosave.
 tests/test_form_pages.py | 43 ++++++++++++++++++++++---------
 wcs/forms/root.py        | 66 ++++++++++++++++++++++++++++--------------------
 2 files changed, 70 insertions(+), 39 deletions(-)
tests/test_form_pages.py
511 511
    resp = get_app(pub).get('/test/')
512 512
    assert not '<h3>Tracking code</h3>' in resp.body
513 513

  
514
def get_displayed_tracking_code(resp):
515
    tracking_code = None
516
    for a_tag in resp.html.findAll('a'):
517
        if 'code/' in a_tag['href']:
518
            tracking_code = a_tag.text
519
            break
520
    return tracking_code
521

  
514 522
def test_form_tracking_code(pub):
515 523
    formdef = create_formdef()
516 524
    formdef.fields = [fields.StringField(id='0', label='string')]
......
521 529
    assert '<h3>Tracking code</h3>' in resp.body
522 530
    resp.forms[0]['f0'] = 'foobar'
523 531
    resp = resp.forms[0].submit('submit')
524
    tracking_code = None
525
    for a_tag in resp.html.findAll('a'):
526
        if 'code/' in a_tag['href']:
527
            tracking_code = a_tag.text
528
            break
532
    tracking_code = get_displayed_tracking_code(resp)
529 533
    assert tracking_code is not None
530 534

  
531 535
    assert formdef.data_class().count() == 1
......
577 581
    resp = resp.forms[0].submit()
578 582
    assert formdef.data_class().get(formdata_id).evolution[-1].comment == 'hello world'
579 583

  
580

  
581 584
def test_form_tracking_code_as_user(pub):
582 585
    user = create_user(pub)
583 586
    formdef = create_formdef()
......
588 591
    resp = login(get_app(pub), username='foo', password='foo').get('/test/')
589 592
    formdef.data_class().wipe()
590 593
    assert '<h3>Tracking code</h3>' in resp.body
594
    tracking_code = get_displayed_tracking_code(resp)
595
    assert tracking_code is not None
591 596
    resp.forms[0]['f0'] = 'foobar'
592 597
    resp = resp.forms[0].submit('submit')
593
    tracking_code = None
594
    for a_tag in resp.html.findAll('a'):
595
        if 'code/' in a_tag['href']:
596
            tracking_code = a_tag.text
597
            break
598
    assert tracking_code is not None
598
    tracking_code_2 = get_displayed_tracking_code(resp)
599
    assert tracking_code == tracking_code_2
599 600

  
600 601
    assert formdef.data_class().count() == 1
601 602
    assert formdef.data_class().select()[0].is_draft()
......
655 656
    resp = resp.follow()
656 657
    assert 'form_comment' in resp.body # makes sure user is treated as submitter
657 658

  
659
def test_form_empty_tracking_code(pub):
660
    formdef = create_formdef()
661
    formdef.fields = [fields.StringField(id='0', label='string')]
662
    formdef.enable_tracking_codes = True
663
    formdef.store()
664
    resp = get_app(pub).get('/test/')
665
    formdef.data_class().wipe()
666
    assert '<h3>Tracking code</h3>' in resp.body
667
    tracking_code = get_displayed_tracking_code(resp)
668
    assert tracking_code is not None
669

  
670
    # check we get a 404 if we use the tracking code before it gets any data
671
    app = get_app(pub)
672
    resp = app.get('/')
673
    resp.forms[0]['code'] = tracking_code
674
    resp = resp.forms[0].submit()
675
    assert resp.location == 'http://example.net/code/%s/load' % tracking_code
676
    resp = resp.follow(status=404)
658 677

  
659 678
def test_form_tracking_code_email(pub):
660 679
    formdef = create_formdef()
wcs/forms/root.py
181 181
            tracking_code = get_publisher().tracking_code_class.get(self.code)
182 182
        except KeyError:
183 183
            raise errors.TraversalError()
184
        if tracking_code.formdata_id is None:
185
            # this tracking code was not associated with any data; return a 404
186
            raise errors.TraversalError()
184 187
        formdata = tracking_code.formdata
185 188
        if formdata.formdef.enable_tracking_codes is False:
186 189
            raise errors.TraversalError()
......
348 351
        magictoken = get_request().form.get('magictoken')
349 352
        if magictoken:
350 353
            form_data = session.get_by_magictoken(magictoken, {})
351
            if form_data.get('draft_formdata_id'):
354
            if self.formdef.enable_tracking_codes:
352 355
                form.attrs['data-has-draft'] = 'yes'
353 356
        else:
354 357
            form_data = {}
......
448 451
        '''Create the tracking code box, it displays the current tracking code
449 452
           or a 'save' button if it has not yet been created.'''
450 453
        r = TemplateIO(html=True)
451
        draft_formdata_id = data.get('draft_formdata_id')
452 454
        r += htmltext('<div id="tracking-code">')
453 455
        r += htmltext('<h3>%s</h3>') % _('Tracking code')
456

  
457
        tracking_code = None
458
        draft_formdata_id = data.get('draft_formdata_id')
454 459
        if draft_formdata_id:
455 460
            formdata = self.formdef.data_class().get(draft_formdata_id)
456
            if formdata.tracking_code:
457
                get_response().add_javascript(['jquery.js', 'jquery-ui.js', 'popup.js'])
458
                r += htmltext('<a rel="popup" href="%s">%s</a>') % (
459
                        'code/%s/' % formdata.tracking_code,
460
                        formdata.tracking_code)
461
            tracking_code = formdata.tracking_code
462
        else:
463
            tracking_code = data.get('future_tracking_code')
464

  
465
        if tracking_code:
466
            get_response().add_javascript(['jquery.js', 'jquery-ui.js', 'popup.js'])
467
            r += htmltext('<a rel="popup" href="%s">%s</a>') % (
468
                    'code/%s/' % tracking_code, tracking_code)
461 469
        else:
462 470
            r += htmltext('<button>%s</button>') % _('Save')
463 471
        r += TextsDirectory.get_html_text('tracking-code-short-text')
......
504 512
                            _('Sorry, your session have been lost.'))
505 513
                    return redirect(self.formdef.get_url())
506 514

  
515
        else:
516
            # first hit on first page, if tracking code are enabled and we
517
            # are not editing an existing formdata, generate a new tracking
518
            # code.
519
            if not editing and self.formdef.enable_tracking_codes and not get_request().form.has_key('mt'):
520
                tracking_code = get_publisher().tracking_code_class()
521
                tracking_code.store()
522
                token = randbytes(8)
523
                get_request().form['magictoken'] = token
524
                session.add_magictoken(token, {'future_tracking_code': tracking_code.id})
525

  
507 526
        existing_formdata = None
508 527
        if editing:
509 528
            existing_formdata = editing.data
......
781 800
        if not session:
782 801
            return result_error('missing session')
783 802

  
784
        draft_id = session.get_by_magictoken(magictoken, {}).get('draft_formdata_id')
785
        if not draft_id:
786
            return result_error('missing draft id')
787

  
788
        try:
789
            formdata = self.formdef.data_class().get(draft_id)
790
        except KeyError:
791
            return result_error('missing formdata')
792

  
793
        if not formdata.is_draft():
794
            return result_error('formdata has already been saved')
803
        form_data = session.get_by_magictoken(magictoken, {})
804
        if not form_data:
805
            return result_error('missing data')
795 806

  
796
        formdata.page_no = page_no
797 807
        form = self.formdef.create_form(page_no)
798
        formdata.data.update(self.formdef.get_data(form))
799
        formdata.receipt_time = time.localtime()
800
        session = get_session()
801
        if session and session.user and not str(session.user).startswith('anonymous-'):
802
            formdata.user_id = session.user
803
        formdata.store()
808
        data = self.formdef.get_data(form)
809
        if not data:
810
            return result_error('nothing to save')
811

  
812
        form_data.update(data)
813
        draft_formdata = self.save_draft(form_data, page_no)
804 814

  
805 815
        return json.dumps({'result': 'success'})
806 816

  
......
819 829
            get_session().mark_anonymous_formdata(filled)
820 830

  
821 831
        data['draft_formdata_id'] = filled.id
822
        self.set_tracking_code(filled)
832
        self.set_tracking_code(filled, data)
823 833

  
824 834
        get_logger().info('form %s - saving draft (id: %s)' % (self.formdef.name, filled.id))
825 835

  
......
882 892
                url = filled.get_url()
883 893
        return redirect(url)
884 894

  
885
    def set_tracking_code(self, formdata):
895
    def set_tracking_code(self, formdata, magictoken_data=None):
886 896
        if not self.formdef.enable_tracking_codes:
887 897
            return
888 898
        if formdata.tracking_code:
889 899
            return
890 900
        code = get_publisher().tracking_code_class()
901
        if magictoken_data and 'future_tracking_code' in magictoken_data:
902
            code.id = magictoken_data['future_tracking_code']
891 903
        code.formdata = formdata # this will .store() the code
892 904

  
893 905
    def submitted_existing(self, form, editing):
894
-