Projet

Général

Profil

0001-formdata-move-submission-channel-to-its-own-attribut.patch

Frédéric Péters, 08 novembre 2015 19:44

Télécharger (13,8 ko)

Voir les différences:

Subject: [PATCH] formdata: move submission channel to its own attribute
 (#8888)

 tests/test_api.py              |  5 ++--
 tests/test_backoffice_pages.py | 10 ++++----
 tests/test_sql.py              | 54 ++++++++++++++++++++++++++++++++++++++++++
 wcs/api.py                     |  1 +
 wcs/backoffice/management.py   |  9 +++----
 wcs/backoffice/submission.py   |  8 ++-----
 wcs/formdata.py                |  7 ++++++
 wcs/sql.py                     | 15 ++++++++----
 8 files changed, 87 insertions(+), 22 deletions(-)
tests/test_api.py
348 348
    assert data_class.get(resp.json['data']['id']).status == 'draft'
349 349

  
350 350
    resp = get_app(pub).post_json(url, {'meta': {'backoffice-submission': True}, 'data': {},
351
        'context': {'channel': 'mail'} })
351
        'context': {'channel': 'mail', 'comments': 'blah'} })
352 352
    assert data_class.get(resp.json['data']['id']).status == 'wf-new'
353 353
    assert data_class.get(resp.json['data']['id']).backoffice_submission is True
354 354
    assert data_class.get(resp.json['data']['id']).user_id is None
355
    assert data_class.get(resp.json['data']['id']).submission_context == {'channel': 'mail'}
355
    assert data_class.get(resp.json['data']['id']).submission_context == {'comments': 'blah'}
356
    assert data_class.get(resp.json['data']['id']).submission_channel == 'mail'
356 357

  
357 358
    data_class.wipe()
358 359

  
tests/test_backoffice_pages.py
458 458
    # check there's nothing in the sidebar
459 459
    assert not 'Channel' in resp.body
460 460

  
461
    number31.submission_channel = 'mail'
461 462
    number31.submission_context = {
462
            'channel': 'mail',
463 463
            'mail_url': 'http://www.example.com/test.pdf',
464 464
            'thumbnail_url': 'http://www.example.com/thumbnail.png',
465 465
            'user_id': user.id,
......
746 746
    resp = app.get('/backoffice/submission/')
747 747
    assert '%s/%s' % (formdef.url_name, formdata_no) in resp.body
748 748
    assert '>#%s' % formdata_no in resp.body
749
    formdata.submission_context = {'channel': 'mail'}
749
    formdata.submission_channel = 'mail'
750 750
    formdata.store()
751 751
    resp = app.get('/backoffice/submission/')
752 752
    assert '>Mail #%s' % formdata_no in resp.body
......
816 816
    formdata.backoffice_submission = True
817 817
    formdata.status = 'draft'
818 818
    formdata.data = {}
819
    formdata.submission_context = {'channel': 'mail', 'user_id': other_user.id}
819
    formdata.submission_channel = 'mail'
820
    formdata.submission_context = {'user_id': other_user.id}
820 821
    formdata.store()
821 822

  
822 823
    formdata2 = formdef.data_class()()
823 824
    formdata2.backoffice_submission = True
824 825
    formdata2.status = 'draft'
825 826
    formdata2.data = {}
826
    formdata2.submission_context = {'channel': 'mail'}
827
    formdata.submission_channel = 'mail'
828
    formdata2.submission_context = {}
827 829
    formdata2.store()
828 830

  
829 831
    app = login(get_app(pub))
tests/test_sql.py
110 110

  
111 111
    formdata = data_class.get(id)
112 112
    assert formdata.user_id == '5'
113
    assert formdata.status == 'wf-0'
114

  
115
@postgresql
116
def test_sql_store_channel():
117
    data_class = formdef.data_class(mode='sql')
118
    formdata = data_class()
119
    formdata.status = 'wf-0'
120
    formdata.user_id = '5'
121
    formdata.submission_channel = 'mail'
122
    formdata.store()
123

  
124
    assert data_class.get(formdata.id).submission_channel == 'mail'
125

  
126
    formdata.submission_channel = None
127
    formdata.store()
128
    assert data_class.get(formdata.id).submission_channel is None
113 129

  
114 130
@postgresql
115 131
def test_sql_get_missing():
......
721 737
    conn.commit()
722 738
    cur.close()
723 739

  
740
def migration_level(cur):
741
    cur.execute('SELECT value FROM wcs_meta WHERE key = %s', ('sql_level',))
742
    row = cur.fetchone()
743
    return int(row[0])
744

  
724 745
@postgresql
725 746
def test_migration_1_tracking_code():
726 747
    conn, cur = sql.get_connection_and_cursor()
......
729 750
    sql.migrate()
730 751
    assert table_exists(cur, 'tracking_codes')
731 752
    assert table_exists(cur, 'wcs_meta')
753
    assert migration_level(cur) >= 1
732 754
    conn.commit()
733 755
    cur.close()
734 756

  
......
770 792
    sql.migrate()
771 793

  
772 794
    assert column_exists_in_table(cur, 'wcs_all_forms', 'formdef_id')
795
    assert migration_level(cur) >= 2
773 796

  
774 797
    conn.commit()
775 798
    cur.close()
......
794 817
    assert column_exists_in_table(cur, 'formdata_1_tests', 'actions_roles_array')
795 818
    assert column_exists_in_table(cur, 'wcs_view_1_tests', 'actions_roles_array')
796 819
    assert column_exists_in_table(cur, 'wcs_all_forms', 'actions_roles_array')
820
    assert migration_level(cur) >= 6
821

  
822
    conn.commit()
823
    cur.close()
824

  
825
@postgresql
826
def test_migration_10_submission_channel():
827
    conn, cur = sql.get_connection_and_cursor()
828
    cur.execute('UPDATE wcs_meta SET value = 9 WHERE key = %s', ('sql_level',))
829
    cur.execute('DROP VIEW wcs_all_forms')
830

  
831
    # hack a formdef table the wrong way, to check it is reconstructed
832
    # properly before the views are created
833
    formdef.fields[4] = fields.StringField(id='4', label='item')
834
    cur.execute('DROP VIEW wcs_view_1_tests')
835
    cur.execute('ALTER TABLE formdata_1_tests DROP COLUMN submission_channel')
836
    sql.drop_views(formdef, conn, cur)
837
    formdef.fields[4] = fields.ItemField(id='4', label='item', items=('apple', 'pear', 'peach', 'apricot')),
838
    assert not column_exists_in_table(cur, 'formdata_1_tests', 'submission_channel')
839

  
840
    sql.migrate()
841

  
842
    assert column_exists_in_table(cur, 'formdata_1_tests', 'submission_channel')
843
    assert column_exists_in_table(cur, 'wcs_view_1_tests', 'submission_channel')
844
    assert column_exists_in_table(cur, 'wcs_all_forms', 'submission_channel')
845
    assert migration_level(cur) >= 10
797 846

  
798 847
    conn.commit()
799 848
    cur.close()
......
910 959
            # set receipt_time to make sure all entries are unique.
911 960
            formdata.receipt_time = (now + datetime.timedelta(seconds=cnt)).timetuple()
912 961
            formdata.status = ['wf-new', 'wf-accepted', 'wf-rejected', 'wf-finished'][(i+j)%4]
962
            if j < 5:
963
                formdata.submission_channel = 'mail'
913 964
            formdata.store()
914 965
            cnt += 1
915 966

  
......
936 987
    objects2 = sql.AnyFormData.select([st.Equal('is_at_endpoint', True)])
937 988
    assert len(objects2) == len([x for x in objects if x.status in ('wf-rejected', 'wf-finished')])
938 989

  
990
    objects2 = sql.AnyFormData.select([st.Equal('submission_channel', 'mail')])
991
    assert len(objects2) == len([x for x in objects if x.submission_channel == 'mail'])
992

  
939 993
    # test offset/limit
940 994
    objects2 = sql.AnyFormData.select(order_by='receipt_time', limit=10, offset=0)
941 995
    assert [(x.formdef_id, x.id) for x in objects2] == [(x.formdef_id, x.id) for x in objects][:10]
wcs/api.py
234 234
            formdata.user_id = user.id
235 235
        if json_input.get('context'):
236 236
            formdata.submission_context = json_input['context']
237
            formdata.submission_channel = formdata.submission_context.pop('channel')
237 238
        formdata.store()
238 239
        if self.formdef.enable_tracking_codes:
239 240
            code = get_publisher().tracking_code_class()
wcs/backoffice/management.py
1291 1291
        formdata = self.filled
1292 1292

  
1293 1293
        r = TemplateIO(html=True)
1294
        if formdata.submission_context:
1294
        if formdata.submission_context or formdata.submission_channel:
1295 1295
            extra_context = formdata.submission_context or {}
1296 1296
            r += htmltext('<div class="extra-context">')
1297
            if extra_context.get('channel'):
1298
                channel_labels = {
1299
                    'mail': _('Mail'),
1300
                }
1297
            if formdata.submission_channel:
1301 1298
                r += htmltext('<h3>%s</h3>') % '%s: %s' % (
1302
                        _('Channel'), channel_labels.get(extra_context.get('channel'), '?'))
1299
                        _('Channel'), formdata.get_submission_channel_label())
1303 1300
            if extra_context.get('thumbnail_url'):
1304 1301
                r += htmltext('<p class="thumbnail"><img src="%s" alt=""/></p>'
1305 1302
                        ) % extra_context.get('thumbnail_url')
wcs/backoffice/submission.py
206 206
            for formdata in formdatas:
207 207
                r += htmltext('<li class="smallitem">')
208 208
                label = ''
209
                if formdata.submission_context and formdata.submission_context.get('channel'):
210
                    label = {
211
                            'mail': _('Mail'),
212
                        }.get(formdata.submission_context['channel']) or ''
213
                    if label:
214
                        label += ' '
209
                if formdata.submission_channel:
210
                    label = '%s ' % formdata.get_submission_channel_label()
215 211
                label += _('#%s, %s') % (formdata.id,
216 212
                        misc.localstrftime(formdata.receipt_time))
217 213
                r += htmltext('<a href="%s/%s">%s</a>') % (
wcs/formdata.py
162 162
    tracking_code = None
163 163
    backoffice_submission = False
164 164
    submission_context = None
165
    submission_channel = None
165 166

  
166 167
    workflow_data = None
167 168
    workflow_roles = None
......
228 229
            empty &= (self.data.get(key) is None)
229 230
        return empty
230 231

  
232
    def get_submission_channel_label(self):
233
        channel_labels = {
234
            'mail': _('Mail'),
235
        }
236
        return channel_labels.get(self.submission_channel, _('Unknown'))
237

  
231 238
    def just_created(self):
232 239
        self.receipt_time = time.localtime()
233 240
        self.status = 'wf-%s' % self.formdef.workflow.possible_status[0].id
wcs/sql.py
309 309
        'anonymised', 'workflow_roles', 'workflow_roles_array',
310 310
        'concerned_roles_array', 'tracking_code',
311 311
        'actions_roles_array', 'backoffice_submission',
312
        'submission_context'])
312
        'submission_context', 'submission_channel'])
313 313

  
314 314
    # migrations
315 315
    if not 'fts' in existing_fields:
......
341 341
    if not 'submission_context' in existing_fields:
342 342
        cur.execute('''ALTER TABLE %s ADD COLUMN submission_context bytea''' % table_name)
343 343

  
344
    if not 'submission_channel' in existing_fields:
345
        cur.execute('''ALTER TABLE %s ADD COLUMN submission_channel varchar''' % table_name)
346

  
344 347
    # add new fields
345 348
    for field in formdef.fields:
346 349
        assert field.id is not None
......
538 541
    view_fields = []
539 542
    view_fields.append(("int '%s'" % (formdef.category_id or 0), 'category_id'))
540 543
    view_fields.append(("int '%s'" % (formdef.id or 0), 'formdef_id'))
541
    for field in ('id', 'user_id', 'user_hash', 'receipt_time', 'status', 'id_display'):
544
    for field in ('id', 'user_id', 'user_hash', 'receipt_time', 'status',
545
            'id_display', 'submission_channel'):
542 546
        view_fields.append((field, field))
543 547
    return view_fields
544 548

  
......
938 942
        ('tracking_code', 'varchar'),
939 943
        ('backoffice_submission', 'boolean'),
940 944
        ('submission_context', 'bytea'),
945
        ('submission_channel', 'varchar'),
941 946
    ]
942 947

  
943 948
    def __init__(self, id=None):
......
1031 1036
                'tracking_code': self.tracking_code,
1032 1037
                'backoffice_submission': self.backoffice_submission,
1033 1038
                'submission_context': self.submission_context,
1039
                'submission_channel': self.submission_channel,
1034 1040
        }
1035 1041
        if self.receipt_time:
1036 1042
            sql_dict['receipt_time'] = datetime.datetime.fromtimestamp(time.mktime(self.receipt_time)),
......
1679 1685
    return result
1680 1686

  
1681 1687

  
1682
SQL_LEVEL = 8
1688
SQL_LEVEL = 10
1683 1689

  
1684 1690
def migrate_global_views(conn, cur):
1685 1691
    cur.execute('''SELECT COUNT(*) FROM information_schema.tables
......
1728 1734
        migrate_views(conn, cur)
1729 1735
        for formdef in FormDef.select():
1730 1736
            formdef.data_class().rebuild_security()
1731
    if sql_level < 9:
1737
    if sql_level < 10:
1732 1738
        # 7: add backoffice_submission to tables and views
1733 1739
        # 8: add submission_context to tables
1734 1740
        # 9: add last_update_time to views
1741
        # 10: add submission_channel to tables
1735 1742
        migrate_views(conn, cur)
1736 1743

  
1737 1744
    cur.execute('''UPDATE wcs_meta SET value = %s WHERE key = %s''', (
1738
-