Projet

Général

Profil

0001-snapshots-detail-status-action-update-comments-47367.patch

Nicolas Roche, 18 octobre 2020 13:25

Télécharger (12 ko)

Voir les différences:

Subject: [PATCH] snapshots: detail status action update comments (#47367)

 tests/test_snapshots.py   | 106 ++++++++++++++++++++++++++++++++++++++
 wcs/admin/workflows.py    |  14 +++--
 wcs/wf/export_to_model.py |  10 ++++
 wcs/workflows.py          |  38 ++++++++++++++
 4 files changed, 165 insertions(+), 3 deletions(-)
tests/test_snapshots.py
1 1
import pytest
2
from webtest import Upload
2 3

  
3 4
from wcs.blocks import BlockDef
4 5
from wcs.carddef import CardDef
5 6
from wcs.data_sources import NamedDataSource
6 7
from wcs.formdef import FormDef
7 8
from wcs.workflows import Workflow
8 9
from wcs.wscalls import NamedWsCall
9 10

  
......
335 336
    for i in range(10, 15):
336 337
        formdef.description = 'this is a description (%s)' % i
337 338
        formdef.store()
338 339

  
339 340
    resp = app.get('/backoffice/forms/%s/history/' % formdef_with_history.id)
340 341
    assert [x.attrib['class'] for x in resp.pyquery.find('ul.snapshots-list li')] == [
341 342
            'new-day', 'collapsed', 'collapsed', 'collapsed', 'collapsed', 'has-label',
342 343
            'collapsed', 'collapsed', 'collapsed', 'collapsed', 'collapsed', 'collapsed']
344

  
345

  
346
def test_workflow_status_item_history_comments(pub):
347
    create_superuser(pub)
348
    create_role()
349

  
350
    Workflow.wipe()
351
    workflow = Workflow(name='test')
352
    workflow.add_status(name='baz')
353
    workflow.store()
354

  
355
    app = login(get_app(pub))
356
    resp = app.get('/backoffice/workflows/1/')
357
    resp = resp.click('baz')
358

  
359
    resp.forms[0]['action-formdata-action'] = 'Document Creation'
360
    resp = resp.forms[0].submit()
361
    resp = resp.follow()
362

  
363
    resp = resp.click('Edit', href='items/1/')
364
    resp = resp.forms[0].submit('submit')
365
    resp = resp.follow()
366
    resp = resp.follow()
367
    assert 'No change was introduced' in \
368
        resp.html.find('ul', {'class', 'messages'}).find('li', {'class': 'warning'}).text
369

  
370
    resp = resp.click('Edit', href='items/1/')
371
    resp.form['model_file$file'] = Upload(
372
        'test.odt', b'foobar', 'application/vnd.oasis.opendocument.text')
373
    resp = resp.forms[0].submit('submit')
374
    resp = resp.follow()
375
    resp = resp.follow()
376

  
377
    resp = resp.click('Edit', href='items/1/')
378
    resp.form['convert_to_pdf'] = False
379
    resp.form['attach_to_history'] = True
380
    resp = resp.forms[0].submit('submit')
381
    resp = resp.follow()
382
    resp = resp.follow()
383

  
384
    resp = resp.click(href='items/1/delete')
385
    resp = resp.form.submit('submit')
386

  
387
    resp = app.get('/backoffice/workflows/%s/history/' % workflow.id)
388
    comments = [x.text[18:x.text.find('\n')]
389
                for x in resp.html.find('ul', {'class': 'snapshots-list'}).find_all('li')]
390
    assert comments == [
391
        'Deletion of action Document Creation in status "baz"',
392
        'Change in action Document Creation in status "baz": set 2 parameters'
393
        ' (Convert generated file to PDF, Include generated file in the form history)',
394
        'Change in action Document Creation in status "baz": Model set to test.odt',
395
        'New action: Document Creation" in status "baz"',
396
        '']
397

  
398

  
399
def test_workflow_status_item_history_comments_label(pub):
400
    create_superuser(pub)
401
    create_role()
402

  
403
    Workflow.wipe()
404
    workflow = Workflow(name='test')
405
    workflow.add_status(name='baz')
406
    workflow.store()
407

  
408
    app = login(get_app(pub))
409
    resp = app.get('/backoffice/workflows/1/')
410
    resp = resp.click('baz')
411

  
412
    resp.forms[0]['action-interaction'] = 'Webservice'
413
    resp = resp.forms[0].submit()
414
    resp = resp.follow()
415

  
416
    resp = resp.click('Edit', href='items/1/')
417
    resp.form['label'] = 'foo'
418
    resp = resp.forms[0].submit('submit')
419
    resp = resp.follow()
420
    resp = resp.follow()
421

  
422
    resp = resp.click('Edit', href='items/1/')
423
    resp.form['url'] = 'http://example.org'
424
    resp = resp.forms[0].submit('submit')
425
    resp = resp.follow()
426
    resp = resp.follow()
427

  
428
    resp = resp.click('Edit', href='items/1/')
429
    resp.form['notify_on_errors'] = True
430
    resp.form['record_on_errors'] = False
431
    resp = resp.forms[0].submit('submit')
432
    resp = resp.follow()
433
    resp = resp.follow()
434

  
435
    resp = resp.click(href='items/1/delete')
436
    resp = resp.form.submit('submit')
437

  
438
    resp = app.get('/backoffice/workflows/%s/history/' % workflow.id)
439
    comments = [x.text[18:x.text.find('\n')]
440
                for x in resp.html.find('ul', {'class': 'snapshots-list'}).find_all('li')]
441
    assert comments == [
442
        'Deletion of action Webservice "foo" in status "baz"',
443
        'Change in action Webservice "foo" in status "baz": set 2 parameters'
444
        ' (Notify on errors, Record on errors)',
445
        'Change in action Webservice "foo" in status "baz": URL set to http://example.org',
446
        'Change in action Webservice in status "baz": Label set to foo',
447
        'New action: Webservice" in status "baz"',
448
        '']
wcs/admin/workflows.py
289 289
            self.html_top('%s - %s' % (_('Workflow'), self.workflow.name))
290 290
            r = TemplateIO(html=True)
291 291
            r += htmltext('<h2>%s</h2>') % _(self.item.description)
292 292
            r += form.render()
293 293
            if self.item.support_substitution_variables:
294 294
                r += get_publisher().substitutions.get_substitution_html_table()
295 295
            return r.getvalue()
296 296
        else:
297
            comment = self.item.comment_submition(form)
298
            if not comment:
299
                get_session().message = ('warning', _('No change was introduced'))
300
                return redirect('..')
301

  
297 302
            self.item.submit_admin_form(form)
298
            self.workflow.store(comment=_('Change in action "%s"') % _(self.item.description))
303
            self.workflow.store(comment)
299 304
            return redirect('..')
300 305

  
301 306
    def delete(self):
302 307
        form = Form(enctype='multipart/form-data')
303 308
        form.widgets.append(HtmlWidget('<p>%s</p>' % _('You are about to remove an item.')))
304 309
        form.add_submit('delete', _('Delete'))
305 310
        form.add_submit('cancel', _('Cancel'))
306 311
        if form.get_widget('cancel').parse():
......
309 314
            get_response().breadcrumb.append(('delete', _('Delete')))
310 315
            self.html_top(title = _('Delete Item'))
311 316
            r = TemplateIO(html=True)
312 317
            r += htmltext('<h2>%s</h2>') % _('Deleting Item')
313 318
            r += form.render()
314 319
            return r.getvalue()
315 320
        else:
316 321
            del self.parent.items[self.parent.items.index(self.item)]
317
            self.workflow.store(comment=_('Deletion of action "%s"') % _(self.item.description))
322
            self.workflow.store(comment=self.item.comment_deletion())
318 323
            return redirect('../../')
319 324

  
320 325
    def _q_lookup(self, component):
321 326
        t = self.item.q_admin_lookup(self.workflow, self.parent, component,
322 327
                self.html_top)
323 328
        if t:
324 329
            return t
325 330
        return Directory._q_lookup(self, component)
......
566 571
        if not form.is_submitted() or form.has_errors():
567 572
            get_session().message = ('error', _('Submitted form was not filled properly.'))
568 573
            return redirect('.')
569 574

  
570 575
        for category in ('status-change', 'interaction', 'formdata-action', 'user-action'):
571 576
            action_type = form.get_widget('action-%s' % category).parse()
572 577
            if action_type:
573 578
                self.status.append_item(action_type)
574
                self.workflow.store(comment=_('New action'))
579
                description = next((x.description for x in item_classes
580
                              if x.key == action_type), None)
581
                self.workflow.store(comment=_('New action: %s" in status "%s"') % (
582
                    _(description), self.status.name))
575 583
                return redirect('.')
576 584

  
577 585
        get_session().message = ('error', _('Submitted form was not filled properly.'))
578 586
        return redirect('.')
579 587

  
580 588

  
581 589
    def delete(self):
582 590
        form = Form(enctype="multipart/form-data")
wcs/wf/export_to_model.py
385 385
                     attrs={
386 386
                         'data-dynamic-display-child-of': '%smethod' % prefix,
387 387
                         'data-dynamic-display-value': methods.get('interactive'),
388 388
                     })
389 389
        if 'filename' in parameters:
390 390
            form.add(ComputedExpressionWidget, name='%sfilename' % prefix, title=_('File name'),
391 391
                     value=self.filename)
392 392

  
393
    def get_admin_form_changes(self, form):
394
        changes = super(ExportToModel, self).get_admin_form_changes(form)
395
        for change in changes:
396
            if change[0] == 'model_file':
397
                for idx in 2, 3:
398
                    if hasattr(change[idx], 'base_filename'):
399
                        change[idx] = change[idx].base_filename
400
            break
401
        return changes
402

  
393 403
    def get_model_file_parameter_view_value(self):
394 404
        return htmltext('<a href="status/%s/items/%s/?file=model_file">%s</a>') % (
395 405
            self.parent.id, self.id, self.model_file.base_filename)
396 406

  
397 407
    def get_filename(self):
398 408
        filename = None
399 409
        if self.filename:
400 410
            filename = self.compute(self.filename)
wcs/workflows.py
1931 1931
            return '-'
1932 1932
        else:
1933 1933
            return str(value)
1934 1934

  
1935 1935
    def fill_admin_form(self, form):
1936 1936
        for parameter in self.get_parameters():
1937 1937
            self.add_parameters_widgets(form, [parameter])
1938 1938

  
1939
    def get_admin_form_changes(self, form):
1940
        changes = []
1941
        for f in self.get_parameters():
1942
            widget = form.get_widget(f)
1943
            if widget:
1944
                old_value = getattr(self, f)
1945
                value = widget.parse()
1946
                if hasattr(self, '%s_parse' % f):
1947
                    value = getattr(self, '%s_parse' % f)(value)
1948
                changes.append([f, widget.title, old_value, value])
1949
        return changes
1950

  
1951
    def comment_submition(self, form):
1952
        changes = [x for x in self.get_admin_form_changes(form) if x[2] != x[3]]
1953
        if not changes:
1954
            return None
1955
        if len(changes) == 1:
1956
            comment = _("%s set to %s") % (changes[0][1], changes[0][3])
1957
        else:
1958
            comment = _("set %s parameters (%s)") % (
1959
                len(changes), ', '.join(x[1] for x in changes))
1960
        if getattr(self, 'label', None):
1961
            comment = _('Change in action %s "%s" in status "%s": %s') % (
1962
                _(self.description), self.label, self.parent.name, comment)
1963
        else:
1964
            comment = _('Change in action %s in status "%s": %s') % (
1965
                _(self.description), self.parent.name, comment)
1966
        return comment
1967

  
1968
    def comment_deletion(self):
1969
        if getattr(self, 'label', None):
1970
            comment=_('Deletion of action %s "%s" in status "%s"') % (
1971
                _(self.description), self.label, self.parent.name)
1972
        else:
1973
            comment=_('Deletion of action %s in status "%s"') % (
1974
                _(self.description), self.parent.name)
1975
        return comment
1976

  
1939 1977
    def submit_admin_form(self, form):
1940 1978
        for f in self.get_parameters():
1941 1979
            widget = form.get_widget(f)
1942 1980
            if widget:
1943 1981
                value = widget.parse()
1944 1982
                if hasattr(self, '%s_parse' % f):
1945 1983
                    value = getattr(self, '%s_parse' % f)(value)
1946 1984
                setattr(self, f, value)
1947
-