general: update .store() calls with comments (#4960)

This commit is contained in:
Frédéric Péters 2020-08-11 17:28:37 +02:00
parent 619c5fbb57
commit 8384cedeec
7 changed files with 88 additions and 59 deletions

View File

@ -5,6 +5,7 @@ from wcs.formdef import FormDef
from wcs.data_sources import NamedDataSource
from utilities import get_app, login, create_temporary_pub, clean_temporary_pub
from test_admin_pages import create_superuser, create_role
@pytest.fixture
@ -13,6 +14,11 @@ def pub(request, emails):
pub.cfg['identification'] = {'methods': ['password']}
pub.cfg['language'] = {'language': 'en'}
pub.write_cfg()
FormDef.wipe()
CardDef.wipe()
NamedDataSource.wipe()
pub.snapshot_class.wipe()
pub.user_class.wipe()
return pub
@ -21,10 +27,6 @@ def teardown_module(module):
def test_snapshot_basics(pub):
FormDef.wipe()
CardDef.wipe()
NamedDataSource.wipe()
formdef = FormDef()
formdef.name = 'testform'
formdef.fields = []
@ -59,3 +61,29 @@ def test_snapshot_basics(pub):
snapshot = pub.snapshot_class.get_latest('carddef', carddef.id)
assert '>testcard2<' in snapshot.serialization
def test_form_snapshot_comments(pub):
create_superuser(pub)
create_role()
app = login(get_app(pub))
resp = app.get('/backoffice/forms/')
resp = resp.click('New Form')
resp.form['name'] = 'form title'
resp = resp.form.submit().follow()
# .store() then .disabled = True, then .store() again -> 2.
assert pub.snapshot_class.count() == 2
resp = resp.click('Confirmation Page')
assert resp.form['confirmation'].checked
resp.form['confirmation'].checked = False
resp = resp.form.submit().follow()
assert pub.snapshot_class.count() == 3
assert pub.snapshot_class.select(order_by='-timestamp')[0].comment == 'Changed "Confirmation Page" parameters'
resp = resp.click(href='fields/')
resp.forms[0]['label'] = 'foobar'
resp.forms[0]['type'] = 'string'
resp = resp.forms[0].submit().follow()
assert pub.snapshot_class.select(order_by='-timestamp')[0].comment == 'New field "foobar"'

View File

@ -98,7 +98,7 @@ class FieldDefPage(Directory):
if not widget:
continue
setattr(self.field, f.replace('-', '_'), widget.parse())
self.objectdef.store()
self.objectdef.store(comment=_('Modification of field "%s"') % self.field.unhtmled_label)
def get_deletion_extra_warning(self):
return _('Warning: this field data will be permanently deleted.')
@ -159,7 +159,7 @@ class FieldDefPage(Directory):
del self.objectdef.fields[index]
# delete current field
del self.objectdef.fields[current_field_index]
self.objectdef.store()
self.objectdef.store(comment=_('Deletion of field "%s"') % self.field.unhtmled_label)
# redirect to the field that was above this one
if self.objectdef.fields:
if current_field_index == 0:
@ -177,7 +177,7 @@ class FieldDefPage(Directory):
# allocate a new id
new_field.id = self.objectdef.get_new_field_id()
fields.insert(field_pos+1, new_field)
self.objectdef.store()
self.objectdef.store(comment=_('Duplication of field "%s"') % self.field.unhtmled_label)
return self.redirect_field_anchor(new_field)
@ -389,7 +389,7 @@ class FieldsDirectory(Directory):
if set(self.objectdef.fields) != set(new_fields):
return 'ko'
self.objectdef.fields = new_fields
self.objectdef.store()
self.objectdef.store(comment=_('Change in order of fields'))
return 'ok'
def new(self):
@ -433,20 +433,20 @@ class FieldsDirectory(Directory):
label = form.get_widget('label').parse()
if field_type == 'comment' and not label.startswith('<'):
label = '<p>%s</p>' % htmlescape(label)
self.objectdef.fields.insert(insertion_point,
fields.get_field_class_by_type(field_type)(
field = fields.get_field_class_by_type(field_type)(
label=label,
type=field_type,
id =self.objectdef.get_new_field_id()))
id =self.objectdef.get_new_field_id())
self.objectdef.fields.insert(insertion_point, field)
self.objectdef.store(comment=_('New field "%s"') % field.unhtmled_label)
elif form.get_widget('form') and form.get_widget('form').parse():
formdef = FormDef.get(form.get_widget('form').parse())
for j, field in enumerate(formdef.fields):
field.id = self.objectdef.get_new_field_id()
self.objectdef.fields.insert(insertion_point+j, field)
self.objectdef.store(comment=_('Import of fields from "%s"') % formdef.name)
else:
get_session().message = ('error', _('Submitted form was not filled properly.'))
return redirect(redirect_url)
self.objectdef.store()
return redirect(redirect_url)

View File

@ -307,7 +307,7 @@ class OptionsDirectory(Directory):
if getattr(self.formdef, attr, None) != new_value:
self.changed = True
setattr(self.formdef, attr, new_value)
self.formdef.store()
self.formdef.store(comment=_('Changed "%s" parameters') % title)
return redirect('..')
html_top('forms', title=self.formdef.name)
@ -349,7 +349,7 @@ class WorkflowRoleDirectory(Directory):
return r.getvalue()
else:
self.formdef.workflow_roles[component] = form.get_widget('role_id').parse()
self.formdef.store()
self.formdef.store(comment=_('Change in function "%s"') % self.formdef.workflow.roles.get(component))
# instruct formdef to update its security rules
self.formdef.data_class().rebuild_security()
return redirect('..')
@ -682,7 +682,7 @@ class FormDefPage(Directory):
return r.getvalue()
else:
self.formdef.category_id = form.get_widget('category_id').parse()
self.formdef.store()
self.formdef.store(comment=_('Change of category'))
return redirect('.')
def _roles_selection(self, title, attribute, description=None,
@ -727,7 +727,7 @@ class FormDefPage(Directory):
if form.get_widget('required_authentication_contexts'):
self.formdef.required_authentication_contexts = form.get_widget(
'required_authentication_contexts').parse()
self.formdef.store()
self.formdef.store(comment=_('Change of %s') % title)
return redirect('.')
def roles(self):
@ -778,7 +778,7 @@ class FormDefPage(Directory):
if not form.has_errors():
self.formdef.name = new_name
self.formdef.url_name = new_url_name
self.formdef.store()
self.formdef.store(comment=_('Change of title / URL'))
return redirect('.')
if disabled_url_name:
@ -822,7 +822,7 @@ class FormDefPage(Directory):
workflow_id = self.formdef_default_workflow
return redirect('workflow-status-remapping?new=%s' % workflow_id)
self.formdef.workflow_id = workflow_id
self.formdef.store()
self.formdef.store(comment=_('Workflow change'))
return redirect('.')
def workflow_status_remapping(self):
@ -862,7 +862,7 @@ class FormDefPage(Directory):
self.formdef.workflow_id = None
else:
self.formdef.workflow_id = new_workflow.id
self.formdef.store()
self.formdef.store(comment=_('Workflow change'))
# instruct formdef to update its security rules
self.formdef.data_class().rebuild_security()
return redirect('.')
@ -1031,7 +1031,7 @@ class FormDefPage(Directory):
if incompatible_field_ids:
# if there are incompatible field ids, remove them first
self.formdef.fields = [x for x in self.formdef.fields if x.id not in incompatible_field_ids]
self.formdef.store()
self.formdef.store(comment=_('Overwritten (removal of incompatible fields)'))
# keep current formdef id, url_name, internal identifier and sql table name
new_formdef.id = self.formdef.id
@ -1047,7 +1047,7 @@ class FormDefPage(Directory):
new_formdef.backoffice_submission_roles = self.formdef.backoffice_submission_roles
new_formdef.roles = self.formdef.roles
self.formdef = new_formdef
self.formdef.store()
self.formdef.store(comment=_('Overwritten'))
get_session().message = ('info', _(self.overwrite_success_message))
return redirect('.')
@ -1408,7 +1408,7 @@ class FormDefPage(Directory):
def enable(self):
self.formdef.disabled = False
self.formdef.store()
self.formdef.store(comment=_('Enable'))
if get_request().form.get('back') == 'fields':
return redirect('fields/')
return redirect('.')
@ -1427,7 +1427,7 @@ class FormDefPage(Directory):
if form.is_submitted() and not form.has_errors():
self.formdef.set_variable_options(form)
self.formdef.store()
self.formdef.store(comment=_('Change in workflow variables'))
return redirect('.')
r = TemplateIO(html=True)
@ -1483,7 +1483,7 @@ class FormDefPage(Directory):
if widget.name.startswith('_'):
continue
self.formdef.workflow_options[widget.name] = widget.parse()
self.formdef.store()
self.formdef.store(comment=_('Change in workflow options'))
class NamedDataSourcesDirectoryInForms(NamedDataSourcesDirectory):

View File

@ -230,7 +230,7 @@ class UserFieldsFormDef(FormDef):
base_url = get_publisher().get_backoffice_url()
return '%s/settings/users/fields/' % base_url
def store(self):
def store(self, comment=None):
xml_export = self.export_to_xml(include_id=True)
users_cfg = self.publisher.cfg.get('users', {})
users_cfg['formdef'] = ET.tostring(xml_export)

View File

@ -294,7 +294,7 @@ class WorkflowItemPage(Directory):
return r.getvalue()
else:
self.item.submit_admin_form(form)
self.workflow.store()
self.workflow.store(comment=_('Change in action "%s"') % _(self.item.description))
return redirect('..')
def delete(self):
@ -313,7 +313,7 @@ class WorkflowItemPage(Directory):
return r.getvalue()
else:
del self.parent.items[self.parent.items.index(self.item)]
self.workflow.store()
self.workflow.store(comment=_('Deletion of action "%s"') % _(self.item.description))
return redirect('../../')
def _q_lookup(self, component):
@ -349,7 +349,7 @@ class GlobalActionTriggerPage(Directory):
if form.get_submit() == 'submit' and not form.has_errors():
self.trigger.submit_admin_form(form)
if not form.has_errors():
self.workflow.store()
self.workflow.store(comment=_('Change in global action trigger'))
return redirect('../../')
self.html_top('%s - %s' % (_('Workflow'), self.workflow.name))
@ -374,7 +374,7 @@ class GlobalActionTriggerPage(Directory):
return r.getvalue()
else:
del self.action.triggers[self.action.triggers.index(self.trigger)]
self.workflow.store()
self.workflow.store(comment=_('Deletion of global action trigger'))
return redirect('../../')
@ -556,7 +556,7 @@ class WorkflowStatusPage(Directory):
request = get_request()
new_order = request.form['order'].strip(';').split(';')
self.status.items = [ [x for x in self.status.items if x.id == y][0] for y in new_order]
self.workflow.store()
self.workflow.store(comment=_('Change in action order'))
return 'ok'
def newitem(self):
@ -570,7 +570,7 @@ class WorkflowStatusPage(Directory):
action_type = form.get_widget('action-%s' % category).parse()
if action_type:
self.status.append_item(action_type)
self.workflow.store()
self.workflow.store(comment=_('New action'))
return redirect('.')
get_session().message = ('error', _('Submitted form was not filled properly.'))
@ -601,7 +601,7 @@ class WorkflowStatusPage(Directory):
str('status'), 'wf-%s' % self.status.id)):
return redirect('reassign')
del self.workflow.possible_status[ self.workflow.possible_status.index(self.status) ]
self.workflow.store()
self.workflow.store(comment=_('Deletion of status %s') % self.status.name)
return redirect('../../')
def edit(self):
@ -620,7 +620,7 @@ class WorkflowStatusPage(Directory):
_('There is already a status with that name.'))
else:
self.status.name = new_name
self.workflow.store()
self.workflow.store(comment=_('Change name of status %s') % new_name)
return redirect('.')
self.html_top(title = _('Edit Workflow Status'))
@ -675,7 +675,7 @@ class WorkflowStatusPage(Directory):
else:
self.submit_reassign(form)
del self.workflow.possible_status[ self.workflow.possible_status.index(self.status) ]
self.workflow.store()
self.workflow.store(comment=_('Removal of status %s') % self.status.name)
return redirect('../..')
def submit_reassign(self, form):
@ -741,7 +741,7 @@ class WorkflowStatusPage(Directory):
self.status.visibility = None
self.status.colour = form.get_widget('colour').parse() or 'ffffff'
self.status.extra_css_class = form.get_widget('extra_css_class').parse()
self.workflow.store()
self.workflow.store(comment=_('Change in display options'))
return redirect('.')
self.html_top(title = _('Change Display Settings'))
@ -763,7 +763,7 @@ class WorkflowStatusPage(Directory):
if form.is_submitted() and not form.has_errors():
self.status.forced_endpoint = form.get_widget('force_terminal_status').parse()
self.workflow.store()
self.workflow.store(comment=_('Change of terminal status option'))
return redirect('.')
self.html_top(title = _('Edit Terminal Status'))
@ -782,7 +782,7 @@ class WorkflowStatusPage(Directory):
if form.is_submitted() and not form.has_errors():
self.status.backoffice_info_text = form.get_widget('backoffice_info_text').parse()
self.workflow.store()
self.workflow.store(comment=_('Change in backoffice info text'))
return redirect('.')
self.html_top(title = _('Edit Backoffice Information Text'))
@ -988,7 +988,7 @@ class FunctionsDirectory(Directory):
for status in self.workflow.possible_status:
if status.get_visibility_restricted_roles():
status.visibility = list(self.workflow.roles.keys())
self.workflow.store()
self.workflow.store(comment=_('New function "%s"') % name)
return redirect('..')
get_response().breadcrumb.append(('new', _('New Function')))
@ -1020,15 +1020,16 @@ class FunctionsDirectory(Directory):
if form.get_submit() == 'delete':
slug = '_%s' % component
name = self.workflow.roles[slug]
del self.workflow.roles[slug]
self.workflow.store()
self.workflow.store(comment=_('Deletion of function "%s"') % name)
return redirect('..')
if form.is_submitted() and not form.has_errors():
name = form.get_widget('name').parse()
slug = '_%s' % component
self.workflow.roles[slug] = name
self.workflow.store()
self.workflow.store(comment=_('Rename of function "%s"') % name)
return redirect('..')
get_response().breadcrumb.append(('new', _('Edit Function')))
@ -1077,7 +1078,7 @@ class CriticalityLevelsDirectory(Directory):
level.name = form.get_widget('name').parse()
level.colour = form.get_widget('colour').parse()
self.workflow.criticality_levels.append(level)
self.workflow.store()
self.workflow.store(comment=_('New criticality level'))
return redirect('..')
get_response().breadcrumb.append(('new', _('New Criticality Level')))
@ -1108,13 +1109,13 @@ class CriticalityLevelsDirectory(Directory):
if form.get_submit() == 'delete-level':
self.workflow.criticality_levels.remove(level)
self.workflow.store()
self.workflow.store(comment=_('Deletion of criticality level'))
return redirect('..')
if form.is_submitted() and not form.has_errors():
level.name = form.get_widget('name').parse()
level.colour = form.get_widget('colour').parse()
self.workflow.store()
self.workflow.store(comment=_('Change of name of criticality level'))
return redirect('..')
get_response().breadcrumb.append(('new', _('Edit Criticality Level')))
@ -1229,7 +1230,7 @@ class GlobalActionPage(WorkflowStatusPage):
return r.getvalue()
del self.workflow.global_actions[self.workflow.global_actions.index(self.action)]
self.workflow.store()
self.workflow.store(comment=_('Deletion of global action'))
return redirect('../../')
def edit(self):
@ -1248,7 +1249,7 @@ class GlobalActionPage(WorkflowStatusPage):
_('There is already an action with that name.'))
else:
self.action.name = new_name
self.workflow.store()
self.workflow.store(comment=_('Change in global action'))
return redirect('.')
self.html_top(title=_('Edit Action Name'))
@ -1287,7 +1288,7 @@ class GlobalActionPage(WorkflowStatusPage):
request = get_request()
new_order = request.form['order'].strip(';').split(';')
self.action.triggers = [ [x for x in self.action.triggers if x.id == y][0] for y in new_order]
self.workflow.store()
self.workflow.store(comment=_('Change in trigger order'))
return 'ok'
def newtrigger(self):
@ -1303,7 +1304,7 @@ class GlobalActionPage(WorkflowStatusPage):
get_session().message = ('error', _('Submitted form was not filled properly.'))
return redirect('.')
self.workflow.store()
self.workflow.store(comment=_('New global action trigger'))
return redirect('.')
def get_new_trigger_form(self):
@ -1348,7 +1349,7 @@ class GlobalActionsDirectory(Directory):
form.get_widget('name').set_error(
_('There is already an action with that name.'))
else:
self.workflow.store()
self.workflow.store(comment=_('New global action'))
return redirect('%s/' % action.id)
get_response().breadcrumb.append(('new', _('New Global Action')))
@ -1690,7 +1691,7 @@ class WorkflowPage(Directory):
new_order = request.form['order'].strip(';').split(';')
self.workflow.possible_status = [ [x for x in self.workflow.possible_status if \
x.id == y][0] for y in new_order]
self.workflow.store()
self.workflow.store(comment=_('Change in status order'))
return 'ok'
def update_actions_order(self):
@ -1698,7 +1699,7 @@ class WorkflowPage(Directory):
new_order = request.form['order'].strip(';').split(';')
self.workflow.global_actions = [ [x for x in self.workflow.global_actions if
x.id == y][0] for y in new_order]
self.workflow.store()
self.workflow.store(comment=_('Change in global actions order'))
return 'ok'
def update_criticality_levels_order(self):
@ -1706,7 +1707,7 @@ class WorkflowPage(Directory):
new_order = request.form['order'].strip(';').split(';')
self.workflow.criticality_levels = [
[x for x in self.workflow.criticality_levels if x.id == y][0] for y in new_order]
self.workflow.store()
self.workflow.store(comment=_('Change in criticality levels order'))
return 'ok'
def newstatus(self):
@ -1727,7 +1728,7 @@ class WorkflowPage(Directory):
get_session().message = ('error', _('Submitted form was not filled properly.'))
return redirect('.')
self.workflow.store()
self.workflow.store(comment=_('New status "%s"') % form.get_widget('name').parse())
return redirect('.')

View File

@ -59,8 +59,8 @@ class WorkflowFormFieldsFormDef(FormDef):
return '%s/workflows/%s/status/%s/items/%s/fields/' % (
base_url, self.item.parent.parent.id, self.item.parent.id, self.item.id)
def store(self):
self.item.parent.parent.store()
def store(self, comment=None):
self.item.parent.parent.store(comment=comment)
class WorkflowFormFieldDefPage(FieldDefPage):

View File

@ -265,13 +265,13 @@ class WorkflowVariablesFieldsFormDef(FormDef):
base_url = get_publisher().get_backoffice_url()
return '%s/workflows/%s/variables/fields/' % (base_url, self.workflow.id)
def store(self):
def store(self, comment=None):
for field in self.fields:
if hasattr(field, 'widget_class'):
if not field.varname:
field.varname = misc.simplify(field.label, space='_')
self.workflow.variables_formdef = self
self.workflow.store()
self.workflow.store(comment=comment)
class WorkflowBackofficeFieldsFormDef(FormDef):
@ -301,9 +301,9 @@ class WorkflowBackofficeFieldsFormDef(FormDef):
def get_new_field_id(self):
return '%s%s' % (self.field_prefix, str(uuid.uuid4()))
def store(self):
def store(self, comment=None):
self.workflow.backoffice_fields_formdef = self
self.workflow.store()
self.workflow.store(comment=comment)
class Workflow(StorableObject):