3
0
Fork 0

fix: remove session param from some form schema, widget classes

this was originally used for injecting the test session, but i wound
up using mock instead elsewhere, so this is just for consistency
This commit is contained in:
Lance Edgar 2025-01-02 21:09:31 -06:00
parent a612bf3846
commit a219f3e30d
4 changed files with 214 additions and 201 deletions

View file

@ -181,21 +181,16 @@ class WuttaSet(colander.Set):
""" """
Custom schema type for :class:`python:set` fields. Custom schema type for :class:`python:set` fields.
This is a subclass of :class:`colander.Set`, but adds This is a subclass of :class:`colander.Set`.
Wutta-related params to the constructor.
:param request: Current :term:`request` object. :param request: Current :term:`request` object.
:param session: Optional :term:`db session` to use instead of
:class:`wuttaweb.db.sess.Session`.
""" """
def __init__(self, request, session=None): def __init__(self, request):
super().__init__() super().__init__()
self.request = request self.request = request
self.config = self.request.wutta_config self.config = self.request.wutta_config
self.app = self.config.get_app() self.app = self.config.get_app()
self.session = session or Session()
class ObjectRef(colander.SchemaType): class ObjectRef(colander.SchemaType):
@ -231,7 +226,6 @@ class ObjectRef(colander.SchemaType):
self, self,
request, request,
empty_option=None, empty_option=None,
session=None,
*args, *args,
**kwargs, **kwargs,
): ):
@ -240,7 +234,7 @@ class ObjectRef(colander.SchemaType):
self.config = self.request.wutta_config self.config = self.request.wutta_config
self.app = self.config.get_app() self.app = self.config.get_app()
self.model_instance = None self.model_instance = None
self.session = session or Session() self.session = Session()
if empty_option: if empty_option:
if empty_option is True: if empty_option is True:
@ -472,7 +466,7 @@ class RoleRefs(WuttaSet):
:returns: Instance of :returns: Instance of
:class:`~wuttaweb.forms.widgets.RoleRefsWidget`. :class:`~wuttaweb.forms.widgets.RoleRefsWidget`.
""" """
kwargs.setdefault('session', self.session) session = kwargs.setdefault('session', Session())
if 'values' not in kwargs: if 'values' not in kwargs:
model = self.app.model model = self.app.model
@ -480,20 +474,20 @@ class RoleRefs(WuttaSet):
# avoid built-ins which cannot be assigned to users # avoid built-ins which cannot be assigned to users
avoid = { avoid = {
auth.get_role_authenticated(self.session), auth.get_role_authenticated(session),
auth.get_role_anonymous(self.session), auth.get_role_anonymous(session),
} }
avoid = set([role.uuid for role in avoid]) avoid = set([role.uuid for role in avoid])
# also avoid admin unless current user is root # also avoid admin unless current user is root
if not self.request.is_root: if not self.request.is_root:
avoid.add(auth.get_role_administrator(self.session).uuid) avoid.add(auth.get_role_administrator(session).uuid)
# everything else can be (un)assigned for users # everything else can be (un)assigned for users
roles = self.session.query(model.Role)\ roles = session.query(model.Role)\
.filter(~model.Role.uuid.in_(avoid))\ .filter(~model.Role.uuid.in_(avoid))\
.order_by(model.Role.name)\ .order_by(model.Role.name)\
.all() .all()
values = [(role.uuid.hex, role.name) for role in roles] values = [(role.uuid.hex, role.name) for role in roles]
kwargs['values'] = values kwargs['values'] = values
@ -518,7 +512,7 @@ class UserRefs(WuttaSet):
:returns: Instance of :returns: Instance of
:class:`~wuttaweb.forms.widgets.UserRefsWidget`. :class:`~wuttaweb.forms.widgets.UserRefsWidget`.
""" """
kwargs.setdefault('session', self.session) kwargs.setdefault('session', Session())
return widgets.UserRefsWidget(self.request, **kwargs) return widgets.UserRefsWidget(self.request, **kwargs)
@ -548,7 +542,7 @@ class Permissions(WuttaSet):
:returns: Instance of :returns: Instance of
:class:`~wuttaweb.forms.widgets.PermissionsWidget`. :class:`~wuttaweb.forms.widgets.PermissionsWidget`.
""" """
kwargs.setdefault('session', self.session) kwargs.setdefault('session', Session())
kwargs.setdefault('permissions', self.permissions) kwargs.setdefault('permissions', self.permissions)
if 'values' not in kwargs: if 'values' not in kwargs:

View file

@ -136,26 +136,21 @@ class WuttaCheckboxChoiceWidget(CheckboxChoiceWidget):
Custom widget for :class:`python:set` fields. Custom widget for :class:`python:set` fields.
This is a subclass of This is a subclass of
:class:`deform:deform.widget.CheckboxChoiceWidget`, but adds :class:`deform:deform.widget.CheckboxChoiceWidget`.
Wutta-related params to the constructor.
:param request: Current :term:`request` object. :param request: Current :term:`request` object.
:param session: Optional :term:`db session` to use instead of
:class:`wuttaweb.db.sess.Session`.
It uses these Deform templates: It uses these Deform templates:
* ``checkbox_choice`` * ``checkbox_choice``
* ``readonly/checkbox_choice`` * ``readonly/checkbox_choice``
""" """
def __init__(self, request, session=None, *args, **kwargs): def __init__(self, request, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.request = request self.request = request
self.config = self.request.wutta_config self.config = self.request.wutta_config
self.app = self.config.get_app() self.app = self.config.get_app()
self.session = session or Session()
class WuttaDateTimeWidget(DateTimeInputWidget): class WuttaDateTimeWidget(DateTimeInputWidget):

View file

@ -155,9 +155,10 @@ class TestObjectRef(DataTestCase):
self.session.commit() self.session.commit()
self.assertIsNotNone(person.uuid) self.assertIsNotNone(person.uuid)
with patch.object(mod.ObjectRef, 'model_class', new=model.Person): with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
typ = mod.ObjectRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
value = typ.deserialize(node, person.uuid) typ = mod.ObjectRef(self.request)
self.assertIs(value, person) value = typ.deserialize(node, person.uuid)
self.assertIs(value, person)
def test_dictify(self): def test_dictify(self):
model = self.app.model model = self.app.model
@ -181,42 +182,46 @@ class TestObjectRef(DataTestCase):
value = typ.objectify(None) value = typ.objectify(None)
self.assertIsNone(value) self.assertIsNone(value)
# model instance with patch.object(mod, 'Session', return_value=self.session):
person = model.Person(full_name="Betty Boop")
self.session.add(person)
self.session.commit()
self.assertIsNotNone(person.uuid)
with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
# can specify as uuid # model instance
typ = mod.ObjectRef(self.request, session=self.session) person = model.Person(full_name="Betty Boop")
value = typ.objectify(person.uuid) self.session.add(person)
self.assertIs(value, person) self.session.commit()
self.assertIsNotNone(person.uuid)
with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
# or can specify object proper # can specify as uuid
typ = mod.ObjectRef(self.request, session=self.session) typ = mod.ObjectRef(self.request)
value = typ.objectify(person) value = typ.objectify(person.uuid)
self.assertIs(value, person) self.assertIs(value, person)
# error if not found # or can specify object proper
with patch.object(mod.ObjectRef, 'model_class', new=model.Person): typ = mod.ObjectRef(self.request)
typ = mod.ObjectRef(self.request, session=self.session) value = typ.objectify(person)
self.assertRaises(ValueError, typ.objectify, 'WRONG-UUID') self.assertIs(value, person)
# error if not found
with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
typ = mod.ObjectRef(self.request)
self.assertRaises(ValueError, typ.objectify, 'WRONG-UUID')
def test_get_query(self): def test_get_query(self):
model = self.app.model model = self.app.model
with patch.object(mod.ObjectRef, 'model_class', new=model.Person): with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
typ = mod.ObjectRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
query = typ.get_query() typ = mod.ObjectRef(self.request)
self.assertIsInstance(query, orm.Query) query = typ.get_query()
self.assertIsInstance(query, orm.Query)
def test_sort_query(self): def test_sort_query(self):
model = self.app.model model = self.app.model
with patch.object(mod.ObjectRef, 'model_class', new=model.Person): with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
typ = mod.ObjectRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
query = typ.get_query() typ = mod.ObjectRef(self.request)
sorted_query = typ.sort_query(query) query = typ.get_query()
self.assertIs(sorted_query, query) sorted_query = typ.sort_query(query)
self.assertIs(sorted_query, query)
def test_widget_maker(self): def test_widget_maker(self):
model = self.app.model model = self.app.model
@ -226,90 +231,98 @@ class TestObjectRef(DataTestCase):
# basic # basic
with patch.object(mod.ObjectRef, 'model_class', new=model.Person): with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
typ = mod.ObjectRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
widget = typ.widget_maker() typ = mod.ObjectRef(self.request)
self.assertEqual(len(widget.values), 1) widget = typ.widget_maker()
self.assertEqual(widget.values[0][1], "Betty Boop") self.assertEqual(len(widget.values), 1)
self.assertEqual(widget.values[0][1], "Betty Boop")
# empty option # empty option
with patch.object(mod.ObjectRef, 'model_class', new=model.Person): with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
typ = mod.ObjectRef(self.request, session=self.session, empty_option=True) with patch.object(mod, 'Session', return_value=self.session):
widget = typ.widget_maker() typ = mod.ObjectRef(self.request, empty_option=True)
self.assertEqual(len(widget.values), 2) widget = typ.widget_maker()
self.assertEqual(widget.values[0][1], "(none)") self.assertEqual(len(widget.values), 2)
self.assertEqual(widget.values[1][1], "Betty Boop") self.assertEqual(widget.values[0][1], "(none)")
self.assertEqual(widget.values[1][1], "Betty Boop")
class TestPersonRef(WebTestCase): class TestPersonRef(WebTestCase):
def test_sort_query(self): def test_sort_query(self):
typ = mod.PersonRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
query = typ.get_query() typ = mod.PersonRef(self.request)
self.assertIsInstance(query, orm.Query) query = typ.get_query()
sorted_query = typ.sort_query(query) self.assertIsInstance(query, orm.Query)
self.assertIsInstance(sorted_query, orm.Query) sorted_query = typ.sort_query(query)
self.assertIsNot(sorted_query, query) self.assertIsInstance(sorted_query, orm.Query)
self.assertIsNot(sorted_query, query)
def test_get_object_url(self): def test_get_object_url(self):
self.pyramid_config.add_route('people.view', '/people/{uuid}') self.pyramid_config.add_route('people.view', '/people/{uuid}')
model = self.app.model model = self.app.model
typ = mod.PersonRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
typ = mod.PersonRef(self.request)
person = model.Person(full_name="Barney Rubble") person = model.Person(full_name="Barney Rubble")
self.session.add(person) self.session.add(person)
self.session.commit() self.session.commit()
url = typ.get_object_url(person) url = typ.get_object_url(person)
self.assertIsNotNone(url) self.assertIsNotNone(url)
self.assertIn(f'/people/{person.uuid}', url) self.assertIn(f'/people/{person.uuid}', url)
class TestRoleRef(WebTestCase): class TestRoleRef(WebTestCase):
def test_sort_query(self): def test_sort_query(self):
typ = mod.RoleRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
query = typ.get_query() typ = mod.RoleRef(self.request)
self.assertIsInstance(query, orm.Query) query = typ.get_query()
sorted_query = typ.sort_query(query) self.assertIsInstance(query, orm.Query)
self.assertIsInstance(sorted_query, orm.Query) sorted_query = typ.sort_query(query)
self.assertIsNot(sorted_query, query) self.assertIsInstance(sorted_query, orm.Query)
self.assertIsNot(sorted_query, query)
def test_get_object_url(self): def test_get_object_url(self):
self.pyramid_config.add_route('roles.view', '/roles/{uuid}') self.pyramid_config.add_route('roles.view', '/roles/{uuid}')
model = self.app.model model = self.app.model
typ = mod.RoleRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
typ = mod.RoleRef(self.request)
role = model.Role(name='Manager') role = model.Role(name='Manager')
self.session.add(role) self.session.add(role)
self.session.commit() self.session.commit()
url = typ.get_object_url(role) url = typ.get_object_url(role)
self.assertIsNotNone(url) self.assertIsNotNone(url)
self.assertIn(f'/roles/{role.uuid}', url) self.assertIn(f'/roles/{role.uuid}', url)
class TestUserRef(WebTestCase): class TestUserRef(WebTestCase):
def test_sort_query(self): def test_sort_query(self):
typ = mod.UserRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
query = typ.get_query() typ = mod.UserRef(self.request)
self.assertIsInstance(query, orm.Query) query = typ.get_query()
sorted_query = typ.sort_query(query) self.assertIsInstance(query, orm.Query)
self.assertIsInstance(sorted_query, orm.Query) sorted_query = typ.sort_query(query)
self.assertIsNot(sorted_query, query) self.assertIsInstance(sorted_query, orm.Query)
self.assertIsNot(sorted_query, query)
def test_get_object_url(self): def test_get_object_url(self):
self.pyramid_config.add_route('users.view', '/users/{uuid}') self.pyramid_config.add_route('users.view', '/users/{uuid}')
model = self.app.model model = self.app.model
typ = mod.UserRef(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
typ = mod.UserRef(self.request)
user = model.User(username='barney') user = model.User(username='barney')
self.session.add(user) self.session.add(user)
self.session.commit() self.session.commit()
url = typ.get_object_url(user) url = typ.get_object_url(user)
self.assertIsNotNone(url) self.assertIsNotNone(url)
self.assertIn(f'/users/{user.uuid}', url) self.assertIn(f'/users/{user.uuid}', url)
class TestUserRefs(DataTestCase): class TestUserRefs(DataTestCase):
@ -320,9 +333,10 @@ class TestUserRefs(DataTestCase):
def test_widget_maker(self): def test_widget_maker(self):
model = self.app.model model = self.app.model
typ = mod.UserRefs(self.request, session=self.session) with patch.object(mod, 'Session', return_value=self.session):
widget = typ.widget_maker() typ = mod.UserRefs(self.request)
self.assertIsInstance(widget, widgets.UserRefsWidget) widget = typ.widget_maker()
self.assertIsInstance(widget, widgets.UserRefsWidget)
class TestRoleRefs(DataTestCase): class TestRoleRefs(DataTestCase):
@ -341,20 +355,22 @@ class TestRoleRefs(DataTestCase):
self.session.add(blokes) self.session.add(blokes)
self.session.commit() self.session.commit()
# with root access, default values include: admin, blokes with patch.object(mod, 'Session', return_value=self.session):
self.request.is_root = True
typ = mod.RoleRefs(self.request, session=self.session)
widget = typ.widget_maker()
self.assertEqual(len(widget.values), 2)
self.assertEqual(widget.values[0][1], "Administrator")
self.assertEqual(widget.values[1][1], "Blokes")
# without root, default values include: blokes # with root access, default values include: admin, blokes
self.request.is_root = False self.request.is_root = True
typ = mod.RoleRefs(self.request, session=self.session) typ = mod.RoleRefs(self.request)
widget = typ.widget_maker() widget = typ.widget_maker()
self.assertEqual(len(widget.values), 1) self.assertEqual(len(widget.values), 2)
self.assertEqual(widget.values[0][1], "Blokes") self.assertEqual(widget.values[0][1], "Administrator")
self.assertEqual(widget.values[1][1], "Blokes")
# without root, default values include: blokes
self.request.is_root = False
typ = mod.RoleRefs(self.request)
widget = typ.widget_maker()
self.assertEqual(len(widget.values), 1)
self.assertEqual(widget.values[0][1], "Blokes")
class TestPermissions(DataTestCase): class TestPermissions(DataTestCase):

View file

@ -10,6 +10,7 @@ from pyramid import testing
from wuttaweb import grids from wuttaweb import grids
from wuttaweb.forms import widgets as mod from wuttaweb.forms import widgets as mod
from wuttaweb.forms import schema
from wuttaweb.forms.schema import (FileDownload, PersonRef, RoleRefs, UserRefs, Permissions, from wuttaweb.forms.schema import (FileDownload, PersonRef, RoleRefs, UserRefs, Permissions,
WuttaDateTime, EmailRecipients) WuttaDateTime, EmailRecipients)
from tests.util import WebTestCase from tests.util import WebTestCase
@ -32,31 +33,33 @@ class TestObjectRefWidget(WebTestCase):
self.session.add(person) self.session.add(person)
self.session.commit() self.session.commit()
# standard (editable) with patch.object(schema, 'Session', return_value=self.session):
node = colander.SchemaNode(PersonRef(self.request, session=self.session))
widget = self.make_widget()
field = self.make_field(node)
html = widget.serialize(field, person.uuid)
self.assertIn('<b-select ', html)
# readonly # standard (editable)
node = colander.SchemaNode(PersonRef(self.request, session=self.session)) node = colander.SchemaNode(PersonRef(self.request))
node.model_instance = person widget = self.make_widget()
widget = self.make_widget() field = self.make_field(node)
field = self.make_field(node) html = widget.serialize(field, person.uuid)
html = widget.serialize(field, person.uuid, readonly=True) self.assertIn('<b-select ', html)
self.assertIn('Betty Boop', html)
self.assertNotIn('<a', html)
# with hyperlink # readonly
node = colander.SchemaNode(PersonRef(self.request, session=self.session)) node = colander.SchemaNode(PersonRef(self.request))
node.model_instance = person node.model_instance = person
widget = self.make_widget(url=lambda p: '/foo') widget = self.make_widget()
field = self.make_field(node) field = self.make_field(node)
html = widget.serialize(field, person.uuid, readonly=True) html = widget.serialize(field, person.uuid, readonly=True)
self.assertIn('Betty Boop', html) self.assertIn('Betty Boop', html)
self.assertIn('<a', html) self.assertNotIn('<a', html)
self.assertIn('href="/foo"', html)
# with hyperlink
node = colander.SchemaNode(PersonRef(self.request))
node.model_instance = person
widget = self.make_widget(url=lambda p: '/foo')
field = self.make_field(node)
html = widget.serialize(field, person.uuid, readonly=True)
self.assertIn('Betty Boop', html)
self.assertIn('<a', html)
self.assertIn('href="/foo"', html)
def test_get_template_values(self): def test_get_template_values(self):
model = self.app.model model = self.app.model
@ -64,22 +67,24 @@ class TestObjectRefWidget(WebTestCase):
self.session.add(person) self.session.add(person)
self.session.commit() self.session.commit()
# standard with patch.object(schema, 'Session', return_value=self.session):
node = colander.SchemaNode(PersonRef(self.request, session=self.session))
widget = self.make_widget()
field = self.make_field(node)
values = widget.get_template_values(field, person.uuid, {})
self.assertIn('cstruct', values)
self.assertNotIn('url', values)
# readonly w/ empty option # standard
node = colander.SchemaNode(PersonRef(self.request, session=self.session, node = colander.SchemaNode(PersonRef(self.request))
empty_option=('_empty_', '(empty)'))) widget = self.make_widget()
widget = self.make_widget(readonly=True, url=lambda obj: '/foo') field = self.make_field(node)
field = self.make_field(node) values = widget.get_template_values(field, person.uuid, {})
values = widget.get_template_values(field, '_empty_', {}) self.assertIn('cstruct', values)
self.assertIn('cstruct', values) self.assertNotIn('url', values)
self.assertNotIn('url', values)
# readonly w/ empty option
node = colander.SchemaNode(PersonRef(self.request,
empty_option=('_empty_', '(empty)')))
widget = self.make_widget(readonly=True, url=lambda obj: '/foo')
field = self.make_field(node)
values = widget.get_template_values(field, '_empty_', {})
self.assertIn('cstruct', values)
self.assertNotIn('url', values)
class TestWuttaDateTimeWidget(WebTestCase): class TestWuttaDateTimeWidget(WebTestCase):
@ -230,28 +235,29 @@ class TestRoleRefsWidget(WebTestCase):
self.session.commit() self.session.commit()
# nb. we let the field construct the widget via our type # nb. we let the field construct the widget via our type
node = colander.SchemaNode(RoleRefs(self.request, session=self.session)) with patch.object(schema, 'Session', return_value=self.session):
field = self.make_field(node) node = colander.SchemaNode(RoleRefs(self.request))
widget = field.widget field = self.make_field(node)
widget = field.widget
# readonly values list includes admin # readonly values list includes admin
html = widget.serialize(field, {admin.uuid, blokes.uuid}, readonly=True) html = widget.serialize(field, {admin.uuid, blokes.uuid}, readonly=True)
self.assertIn(admin.name, html) self.assertIn(admin.name, html)
self.assertIn(blokes.name, html) self.assertIn(blokes.name, html)
# editable values list *excludes* admin (by default) # editable values list *excludes* admin (by default)
html = widget.serialize(field, {admin.uuid, blokes.uuid}) html = widget.serialize(field, {admin.uuid, blokes.uuid})
self.assertNotIn(str(admin.uuid.hex), html) self.assertNotIn(str(admin.uuid.hex), html)
self.assertIn(str(blokes.uuid.hex), html) self.assertIn(str(blokes.uuid.hex), html)
# but admin is included for root user # but admin is included for root user
self.request.is_root = True self.request.is_root = True
node = colander.SchemaNode(RoleRefs(self.request, session=self.session)) node = colander.SchemaNode(RoleRefs(self.request))
field = self.make_field(node) field = self.make_field(node)
widget = field.widget widget = field.widget
html = widget.serialize(field, {admin.uuid, blokes.uuid}) html = widget.serialize(field, {admin.uuid, blokes.uuid})
self.assertIn(str(admin.uuid.hex), html) self.assertIn(str(admin.uuid.hex), html)
self.assertIn(str(blokes.uuid.hex), html) self.assertIn(str(blokes.uuid.hex), html)
class TestUserRefsWidget(WebTestCase): class TestUserRefsWidget(WebTestCase):
@ -266,35 +272,37 @@ class TestUserRefsWidget(WebTestCase):
model = self.app.model model = self.app.model
# nb. we let the field construct the widget via our type # nb. we let the field construct the widget via our type
node = colander.SchemaNode(UserRefs(self.request, session=self.session)) # node = colander.SchemaNode(UserRefs(self.request, session=self.session))
field = self.make_field(node) with patch.object(schema, 'Session', return_value=self.session):
widget = field.widget node = colander.SchemaNode(UserRefs(self.request))
field = self.make_field(node)
widget = field.widget
# readonly is required # readonly is required
self.assertRaises(NotImplementedError, widget.serialize, field, set()) self.assertRaises(NotImplementedError, widget.serialize, field, set())
self.assertRaises(NotImplementedError, widget.serialize, field, set(), readonly=False) self.assertRaises(NotImplementedError, widget.serialize, field, set(), readonly=False)
# empty # empty
html = widget.serialize(field, set(), readonly=True) html = widget.serialize(field, set(), readonly=True)
self.assertEqual(html, '<span></span>') self.assertEqual(html, '<span></span>')
# with data, no actions # with data, no actions
user = model.User(username='barney') user = model.User(username='barney')
self.session.add(user) self.session.add(user)
self.session.commit() self.session.commit()
html = widget.serialize(field, {user.uuid}, readonly=True)
self.assertIn('<b-table ', html)
self.assertNotIn('Actions', html)
self.assertNotIn('View', html)
self.assertNotIn('Edit', html)
# with view/edit actions
with patch.object(self.request, 'is_root', new=True):
html = widget.serialize(field, {user.uuid}, readonly=True) html = widget.serialize(field, {user.uuid}, readonly=True)
self.assertIn('<b-table ', html) self.assertIn('<b-table ', html)
self.assertIn('Actions', html) self.assertNotIn('Actions', html)
self.assertIn('View', html) self.assertNotIn('View', html)
self.assertIn('Edit', html) self.assertNotIn('Edit', html)
# with view/edit actions
with patch.object(self.request, 'is_root', new=True):
html = widget.serialize(field, {user.uuid}, readonly=True)
self.assertIn('<b-table ', html)
self.assertIn('Actions', html)
self.assertIn('View', html)
self.assertIn('Edit', html)
class TestPermissionsWidget(WebTestCase): class TestPermissionsWidget(WebTestCase):
@ -318,7 +326,7 @@ class TestPermissionsWidget(WebTestCase):
} }
# nb. we let the field construct the widget via our type # nb. we let the field construct the widget via our type
node = colander.SchemaNode(Permissions(self.request, permissions, session=self.session)) node = colander.SchemaNode(Permissions(self.request, permissions))
field = self.make_field(node) field = self.make_field(node)
widget = field.widget widget = field.widget