Projet

Général

Profil

0001-formdef-add-internal-identifier-attribute-separated-.patch

Frédéric Péters, 20 juillet 2017 09:20

Télécharger (10,7 ko)

Voir les différences:

Subject: [PATCH 1/2] formdef: add internal identifier attribute, separated
 from url_name (#15663)

This will allow changing url name behaviour without impacting on storage
matters.
 tests/test_admin_pages.py | 18 +++++++++------
 tests/test_formdef.py     |  8 ++++---
 tests/test_sql.py         |  2 +-
 wcs/admin/forms.py        |  5 ++--
 wcs/formdef.py            | 58 +++++++++++++++++++++++++++++++++++------------
 5 files changed, 64 insertions(+), 27 deletions(-)
tests/test_admin_pages.py
328 328
    assert resp.location == 'http://example.net/backoffice/forms/1/'
329 329
    resp = resp.follow()
330 330
    assert FormDef.get(1).name == 'new title'
331
    assert FormDef.get(1).url_name == 'new-title'
331
    assert FormDef.get(1).url_name == 'form-title'
332
    assert FormDef.get(1).internal_identifier == 'new-title'
332 333

  
333 334
def test_form_category(pub):
334 335
    create_superuser(pub)
......
745 746
    resp = resp.forms[0].submit()
746 747
    assert FormDef.count() == 1
747 748

  
748
    # import the same formdef a second time, make sure the urlname is not
749
    # reused
749
    # import the same formdef a second time, make sure url name and internal
750
    # identifier are not reused
750 751
    resp = app.get('/backoffice/forms/')
751 752
    resp = resp.click(href='import')
752 753
    resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
......
754 755
    assert FormDef.count() == 2
755 756
    assert FormDef.get(1).url_name == 'form-title'
756 757
    assert FormDef.get(2).url_name == 'form-title-1'
758
    assert FormDef.get(1).internal_identifier == 'form-title'
759
    assert FormDef.get(2).internal_identifier == 'form-title-1'
757 760

  
758
    # import a formdef with an url_name that doesn't match its title,
759
    # it should be updated to match.
761
    # import a formdef with an url name that doesn't match its title,
762
    # it should be kept intact.
760 763
    formdef.url_name = 'xxx-other-form-title'
761 764
    formdef_xml = ET.tostring(formdef.export_to_xml(include_id=True))
762 765

  
......
764 767
    resp = resp.click(href='import')
765 768
    resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
766 769
    resp = resp.forms[0].submit()
767
    assert FormDef.get(3).url_name == 'form-title-2'
770
    assert FormDef.get(3).url_name == 'xxx-other-form-title'
771
    assert FormDef.get(3).internal_identifier == 'form-title-2'
768 772

  
769 773
    # import an invalid file
770 774
    resp = app.get('/backoffice/forms/')
......
1418 1422

  
1419 1423
    app = login(get_app(pub))
1420 1424
    resp = app.get('/backoffice/forms/%s/' % formdef_id)
1421
    resp = resp.click(href='overwrite')
1425
    resp = resp.click(href='overwrite', index=0)
1422 1426
    resp.forms[0]['file'] = Upload('formdef.wcs', formdef_xml)
1423 1427
    resp = resp.forms[0].submit()
1424 1428
    assert 'The form removes and changes fields' in resp.body
tests/test_formdef.py
83 83
    formdef.store()
84 84
    assert FormDef.get(formdef.id).name == 'foo'
85 85
    assert FormDef.get(formdef.id).url_name == 'foo'
86
    assert FormDef.get(formdef.id).internal_identifier == 'foo'
86 87

  
87 88
    formdef.name = 'bar'
88 89
    formdef.store()
89 90
    assert FormDef.get(formdef.id).name == 'bar'
90
    assert FormDef.get(formdef.id).url_name == 'bar'
91
    assert FormDef.get(formdef.id).url_name == 'foo'
92
    assert FormDef.get(formdef.id).internal_identifier == 'bar'
91 93

  
92
    # makes sure the url_name doesn't change if there are submitted forms
94
    # makes sure the internal_name doesn't change if there are submitted forms
93 95
    formdef.data_class()().store()
94 96
    formdef.name = 'baz'
95 97
    formdef.store()
96 98
    assert FormDef.get(formdef.id).name == 'baz'
97
    assert FormDef.get(formdef.id).url_name == 'bar' # didn't change
99
    assert FormDef.get(formdef.id).internal_identifier == 'bar' # didn't change
98 100

  
99 101
def test_substitution_variables():
100 102
    formdef = FormDef()
tests/test_sql.py
569 569

  
570 570
    formdef.name = 'tests2'
571 571
    formdef.store()
572
    assert formdef.url_name == 'tests2'
572
    assert formdef.url_name == 'tests'
573 573

  
574 574
    formdef.name = 'tests'
575 575
    formdef.store()
wcs/admin/forms.py
949 949
        return redirect('.')
950 950

  
951 951
    def overwrite_by_formdef(self, new_formdef):
952
        # keep current formdef id, url_name and sql table name
952
        # keep current formdef id, url_name, internal identifier and sql table name
953 953
        new_formdef.id = self.formdef.id
954
        new_formdef.internal_identifier = self.formdef.internal_identifier
954 955
        new_formdef.url_name = self.formdef.url_name
955 956
        new_formdef.table_name = self.formdef.table_name
956 957
        # keep currently assigned category and workflow
......
1552 1553
                form.set_error('file', msg)
1553 1554
            raise ValueError()
1554 1555

  
1555
        formdef.url_name = None # a new one will be set in .store()
1556
        formdef.internal_identifier = None # a new one will be set in .store()
1556 1557
        formdef.disabled = True
1557 1558
        formdef.store()
1558 1559
        get_session().message = ('info',
wcs/formdef.py
69 69
    description = None
70 70
    keywords = None
71 71
    url_name = None
72
    internal_identifier = None # mostly for pickle
72 73
    table_name = None # for SQL only
73 74
    fields = None
74 75
    category_id = None
......
101 102

  
102 103
    # declarations for serialization
103 104
    TEXT_ATTRIBUTES = ['name', 'url_name', 'description', 'keywords',
104
            'publication_date', 'expiration_date',
105
            'publication_date', 'expiration_date', 'internal_identifier',
105 106
            'disabled_redirection',]
106 107
    BOOLEAN_ATTRIBUTES = ['discussion', 'detailed_emails', 'disabled',
107 108
            'only_allow_one', 'enable_tracking_codes', 'confirmation',
......
173 174
            self.table_name = sql.get_formdef_table_name(self)
174 175
            changed = True
175 176

  
177
        if not self.internal_identifier:
178
            self.internal_identifier = self.url_name
179
            changed = True
180

  
176 181
        if self.max_field_id is None and self.fields:
177 182
            self.max_field_id = max([lax_int(x.id) for x in self.fields])
178 183
            changed = True
......
238 243
            actions = sql.do_formdef_tables(self)
239 244
        else:
240 245
            cls = new.classobj(self.url_name.title(), (FormData,),
241
                        {'_names': 'form-%s' % self.url_name,
246
                        {'_names': 'form-%s' % self.internal_identifier,
242 247
                         '_formdef': self})
243 248
            actions = []
244 249
        setattr(sys.modules['formdef'], self.url_name.title(), cls)
......
264 269
        suffix_no = 0
265 270
        while True:
266 271
            try:
267
                formdef = self.get_by_urlname(new_url_name, ignore_migration=True)
272
                obj = self.get_on_index(new_url_name, 'url_name', ignore_migration=True)
268 273
            except KeyError:
269 274
                break
270
            if formdef.id == self.id:
275
            if obj.id == self.id:
271 276
                break
272 277
            suffix_no += 1
273 278
            new_url_name = '%s-%s' % (base_new_url_name, suffix_no)
274 279
        return new_url_name
275 280

  
281
    def get_new_internal_identifier(self):
282
        new_internal_identifier = simplify(self.name)
283
        base_new_internal_identifier = new_internal_identifier
284
        suffix_no = 0
285
        while True:
286
            try:
287
                formdef = self.get_by_urlname(new_internal_identifier, ignore_migration=True)
288
            except KeyError:
289
                break
290
            if formdef.id == self.id:
291
                break
292
            suffix_no += 1
293
            new_internal_identifier = '%s-%s' % (base_new_internal_identifier, suffix_no)
294
        return new_internal_identifier
295

  
276 296
    @classmethod
277 297
    def get_new_id(cls, create=False):
278 298
        keys = cls.keys()
......
303 323
            sql.formdef_wipe()
304 324

  
305 325
    def store(self):
306
        new_url_name = self.get_new_url_name()
307
        if not self.url_name:
308
            self.url_name = new_url_name
309
        if new_url_name != self.url_name:
310
            # title changed, url will be changed only if the formdef is
311
            # currently being imported (self.id is None) or if there are not
312
            # yet any submitted forms
313
            data_class = self.data_class()
314
            if self.id is None or data_class().count() == 0:
315
                self.url_name = new_url_name
326
        if self.url_name is None:
327
            # set url name if it's not yet there
328
            self.url_name = self.get_new_url_name()
329
        new_internal_identifier = self.get_new_internal_identifier()
330
        if not self.internal_identifier:
331
            self.internal_identifier = new_internal_identifier
332
        if new_internal_identifier != self.internal_identifier:
333
            # title changed, internal identifier will be changed only if
334
            # the formdef is currently being imported (self.id is None)
335
            # or if there are not yet any submitted forms
336
            if self.id is None or self.data_class().count() == 0:
337
                self.internal_identifier = new_internal_identifier
316 338
        self.last_modification_time = time.localtime()
317 339
        if get_request() and get_request().user:
318 340
            self.last_modification_user_id = str(get_request().user.id)
......
846 868
        formdef = cls.import_from_xml_tree(tree, charset=charset,
847 869
                include_id=include_id)
848 870

  
871
        if formdef.url_name:
872
            try:
873
                obj = cls.get_on_index(formdef.url_name, 'url_name', ignore_migration=True)
874
            except KeyError:
875
                pass
876
            else:
877
                formdef.url_name = formdef.get_new_url_name()
878

  
849 879
        # fix max_field_id if necessary
850 880
        if formdef.max_field_id is not None:
851 881
            max_field_id = max([lax_int(x.id) for x in formdef.fields])
852
-