This commit is contained in:
parent
70805be37d
commit
45cc6f7d5c
|
@ -1721,3 +1721,53 @@ def test_tests_test_users_management(pub):
|
|||
assert 'Some already existing users were not imported.' in resp.text
|
||||
assert 'User test 2' in resp.text
|
||||
assert pub.user_class.count([NotNull('test_uuid')]) == 2
|
||||
|
||||
|
||||
def test_tests_test_users_history_page(pub):
|
||||
create_superuser(pub)
|
||||
|
||||
test_user = pub.user_class(name='Test User')
|
||||
test_user.email = 'jane@example.com'
|
||||
test_user.test_uuid = '42'
|
||||
test_user.form_data = {
|
||||
'1': 'Jane',
|
||||
'2': 'Doe',
|
||||
'3': 'jane@example.com',
|
||||
}
|
||||
# create one snapshot
|
||||
test_user.store()
|
||||
|
||||
# create second snapshot
|
||||
test_user.name = 'Modified User'
|
||||
test_user.store()
|
||||
|
||||
app = login(get_app(pub))
|
||||
|
||||
resp = app.get('/backoffice/forms/test-users/%s/' % test_user.id)
|
||||
resp = resp.click('History')
|
||||
assert [x.attrib['class'] for x in resp.pyquery.find('.snapshots-list tr')] == [
|
||||
'new-day',
|
||||
'collapsed',
|
||||
]
|
||||
|
||||
# export snapshot
|
||||
resp_export = resp.click('Export', index=1)
|
||||
assert resp_export.content_type == 'application/x-wcs-snapshot'
|
||||
assert '>Test User<' in resp_export.text
|
||||
|
||||
# view snapshot
|
||||
resp = resp.click('View', index=1)
|
||||
assert resp.form['name'].value == 'Test User'
|
||||
assert '>Submit<' not in resp.text
|
||||
|
||||
# restore
|
||||
assert pub.user_class.count([NotNull('test_uuid')]) == 1
|
||||
|
||||
resp = resp.click('Restore version')
|
||||
assert 'Restore as a new item' not in resp.text
|
||||
resp = resp.form.submit('submit').follow()
|
||||
|
||||
assert pub.user_class.count([NotNull('test_uuid')]) == 1
|
||||
|
||||
test_user = pub.user_class.get(test_user.id)
|
||||
assert test_user.name == 'Test User'
|
||||
|
|
|
@ -31,7 +31,7 @@ from wcs.admin.workflow_tests import WorkflowTestsDirectory
|
|||
from wcs.api import posted_json_data_to_formdata_data
|
||||
from wcs.backoffice.management import FormBackofficeEditPage, FormBackOfficeStatusPage
|
||||
from wcs.backoffice.pagination import pagination_links
|
||||
from wcs.backoffice.snapshots import SnapshotsDirectory
|
||||
from wcs.backoffice.snapshots import SnapshotDirectory, SnapshotsDirectory
|
||||
from wcs.carddef import CardDef
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.forms.common import FormStatusPage
|
||||
|
@ -993,18 +993,29 @@ class WebserviceResponseDirectory(Directory):
|
|||
return redirect('.')
|
||||
|
||||
|
||||
class TestUserPage(Directory):
|
||||
_q_exports = ['', 'delete', 'export']
|
||||
class TestUserSnapshotDirectory(SnapshotDirectory):
|
||||
allow_restore_as_new = False
|
||||
|
||||
def __init__(self, component):
|
||||
|
||||
class TestUserPage(Directory):
|
||||
_q_exports = ['', 'delete', 'export', ('history', 'snapshots_dir')]
|
||||
|
||||
def __init__(self, component, instance=None):
|
||||
try:
|
||||
self.user = get_publisher().user_class.get(component)
|
||||
self.user = instance or get_publisher().user_class.get(component)
|
||||
except IndexError:
|
||||
raise TraversalError()
|
||||
|
||||
if not self.user.test_uuid:
|
||||
raise TraversalError()
|
||||
|
||||
self.snapshots_dir = SnapshotsDirectory(self.user)
|
||||
self.snapshots_dir.snapshot_directory_class = TestUserSnapshotDirectory
|
||||
|
||||
def _q_traverse(self, path):
|
||||
get_response().breadcrumb.append((str(self.user.id) + '/', self.user.name))
|
||||
return super()._q_traverse(path)
|
||||
|
||||
def _q_index(self):
|
||||
form = Form(enctype='multipart/form-data')
|
||||
|
||||
|
@ -1028,7 +1039,8 @@ class TestUserPage(Directory):
|
|||
)
|
||||
formdef.add_fields_to_form(form, form_data=self.user.form_data)
|
||||
|
||||
form.add_submit('submit', _('Submit'))
|
||||
if not self.user.is_readonly():
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
form.add_media()
|
||||
|
||||
|
@ -1048,17 +1060,24 @@ class TestUserPage(Directory):
|
|||
else:
|
||||
self.user.name = form.get_widget('name').parse()
|
||||
self.user.roles = form.get_widget('roles').parse()
|
||||
self.user.store()
|
||||
self.user.store(comment=_('Change in attribute values'))
|
||||
|
||||
return redirect('..')
|
||||
|
||||
get_response().breadcrumb.append(('edit', _('Edit test user')))
|
||||
if self.user.is_readonly():
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<div class="infonotice"><p>%s</p></div>') % _('This user is readonly.')
|
||||
r += utils.snapshot_info_block(self.user.snapshot_object)
|
||||
get_response().filter['sidebar'] = r.getvalue()
|
||||
|
||||
r = TemplateIO(html=True)
|
||||
r += htmltext('<div id="appbar">')
|
||||
r += htmltext('<h2>%s</h2>') % (_('Edit test user'))
|
||||
r += htmltext('<span class="actions">')
|
||||
r += htmltext('<a href="export">%s</a>') % _('Export')
|
||||
r += htmltext('</span>')
|
||||
if not self.user.is_readonly():
|
||||
r += htmltext('<span class="actions">')
|
||||
r += htmltext('<a href="export">%s</a>') % _('Export')
|
||||
r += htmltext('<a href="history/">%s</a>') % _('History')
|
||||
r += htmltext('</span>')
|
||||
r += htmltext('</div>')
|
||||
r += form.render()
|
||||
return r.getvalue()
|
||||
|
@ -1151,7 +1170,7 @@ class TestUsersDirectory(Directory):
|
|||
|
||||
if not form.has_errors():
|
||||
user.name = form.get_widget('name').parse()
|
||||
user.store()
|
||||
user.store(comment=_('Creation'))
|
||||
return redirect('.')
|
||||
|
||||
get_response().breadcrumb.append(('new', _('New')))
|
||||
|
@ -1221,7 +1240,7 @@ class TestUsersDirectory(Directory):
|
|||
users.append(user)
|
||||
|
||||
for user in users:
|
||||
user.store()
|
||||
user.store(comment=_('Creation (from import)'))
|
||||
|
||||
if users_were_ignored:
|
||||
get_session().message = ('warning', _('Some already existing users were not imported.'))
|
||||
|
|
|
@ -283,12 +283,15 @@ class SnapshotsDirectory(Directory):
|
|||
snapshot = get_publisher().snapshot_class.get(component, ignore_errors=True)
|
||||
if not snapshot or not snapshot.is_from_object(self.obj):
|
||||
raise errors.TraversalError()
|
||||
return SnapshotDirectory(self.obj, snapshot)
|
||||
snapshot_directory_class = getattr(self, 'snapshot_directory_class', SnapshotDirectory)
|
||||
return snapshot_directory_class(self.obj, snapshot)
|
||||
|
||||
|
||||
class SnapshotDirectory(Directory):
|
||||
_q_exports = ['', 'export', 'restore', 'view', 'inspect']
|
||||
|
||||
allow_restore_as_new = True
|
||||
|
||||
def __init__(self, instance, snapshot):
|
||||
self.obj = instance
|
||||
self.snapshot = snapshot
|
||||
|
@ -320,14 +323,15 @@ class SnapshotDirectory(Directory):
|
|||
from wcs.blocks import BlockdefImportError
|
||||
|
||||
form = Form(enctype='multipart/form-data')
|
||||
action_options = (
|
||||
('as-new', _('Restore as a new item'), 'as-new'),
|
||||
('overwrite', _('Overwrite current content'), 'overwrite'),
|
||||
)
|
||||
action = form.add(
|
||||
RadiobuttonsWidget,
|
||||
'action',
|
||||
options=(
|
||||
('as-new', _('Restore as a new item'), 'as-new'),
|
||||
('overwrite', _('Overwrite current content'), 'overwrite'),
|
||||
),
|
||||
value='as-new',
|
||||
options=action_options if self.allow_restore_as_new else action_options[1:],
|
||||
value='as-new' if self.allow_restore_as_new else 'overwrite',
|
||||
)
|
||||
form.add_submit('submit', _('Submit'))
|
||||
form.add_submit('cancel', _('Cancel'))
|
||||
|
|
|
@ -590,6 +590,7 @@ class WcsPublisher(QommonPublisher):
|
|||
from wcs.data_sources import NamedDataSource
|
||||
from wcs.formdef import FormDef
|
||||
from wcs.mail_templates import MailTemplate
|
||||
from wcs.sql import SqlUser
|
||||
from wcs.testdef import TestDef
|
||||
from wcs.workflows import Workflow
|
||||
from wcs.wscalls import NamedWsCall
|
||||
|
@ -611,6 +612,7 @@ class WcsPublisher(QommonPublisher):
|
|||
CommentTemplateCategory,
|
||||
DataSourceCategory,
|
||||
TestDef,
|
||||
SqlUser,
|
||||
):
|
||||
if klass.xml_root_node == object_type:
|
||||
return klass
|
||||
|
|
|
@ -2943,7 +2943,7 @@ class SqlUser(SqlMixin, wcs.users.User):
|
|||
return super().select(clause=clause, **kwargs)
|
||||
|
||||
@invalidate_substitution_cache
|
||||
def store(self):
|
||||
def store(self, comment=None):
|
||||
sql_dict = {
|
||||
'name': self.name,
|
||||
'ascii_name': self.ascii_name,
|
||||
|
@ -3037,6 +3037,9 @@ class SqlUser(SqlMixin, wcs.users.User):
|
|||
|
||||
cur.close()
|
||||
|
||||
if self.test_uuid and get_publisher().snapshot_class:
|
||||
get_publisher().snapshot_class.snap(instance=self, comment=comment)
|
||||
|
||||
@classmethod
|
||||
def _row2ob(cls, row, **kwargs):
|
||||
o = cls()
|
||||
|
|
|
@ -60,6 +60,8 @@ class User(XmlStorableObject):
|
|||
{% if user_var_zipcode %} {{ user_var_zipcode }}{% endif %}
|
||||
{% if user_var_city %} {{ user_var_city }}{% endif %}"""
|
||||
|
||||
backoffice_class = 'wcs.admin.tests.TestUserPage'
|
||||
|
||||
XML_NODES = [
|
||||
# fields to be included in xml export
|
||||
('name', 'str'),
|
||||
|
@ -409,6 +411,9 @@ class User(XmlStorableObject):
|
|||
if status != 200:
|
||||
get_publisher().record_error(_('Failed to call keepalive API (status: %s)') % status)
|
||||
|
||||
def get_admin_url(self):
|
||||
return '%s/forms/test-users/%s/' % (get_publisher().get_backoffice_url(), self.id)
|
||||
|
||||
|
||||
Substitutions.register(
|
||||
'session_user_display_name',
|
||||
|
|
Loading…
Reference in New Issue