0001-snapshots-detail-status-action-update-comments-47367.patch
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 |
- |