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,17 +474,17 @@ 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()
@ -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,7 +155,8 @@ 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):
typ = mod.ObjectRef(self.request)
value = typ.deserialize(node, person.uuid) value = typ.deserialize(node, person.uuid)
self.assertIs(value, person) self.assertIs(value, person)
@ -181,6 +182,8 @@ class TestObjectRef(DataTestCase):
value = typ.objectify(None) value = typ.objectify(None)
self.assertIsNone(value) self.assertIsNone(value)
with patch.object(mod, 'Session', return_value=self.session):
# model instance # model instance
person = model.Person(full_name="Betty Boop") person = model.Person(full_name="Betty Boop")
self.session.add(person) self.session.add(person)
@ -189,31 +192,33 @@ class TestObjectRef(DataTestCase):
with patch.object(mod.ObjectRef, 'model_class', new=model.Person): with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
# can specify as uuid # can specify as uuid
typ = mod.ObjectRef(self.request, session=self.session) typ = mod.ObjectRef(self.request)
value = typ.objectify(person.uuid) value = typ.objectify(person.uuid)
self.assertIs(value, person) self.assertIs(value, person)
# or can specify object proper # or can specify object proper
typ = mod.ObjectRef(self.request, session=self.session) typ = mod.ObjectRef(self.request)
value = typ.objectify(person) value = typ.objectify(person)
self.assertIs(value, person) self.assertIs(value, person)
# error if not found # error if not found
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) typ = mod.ObjectRef(self.request)
self.assertRaises(ValueError, typ.objectify, 'WRONG-UUID') 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):
typ = mod.ObjectRef(self.request)
query = typ.get_query() query = typ.get_query()
self.assertIsInstance(query, orm.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):
typ = mod.ObjectRef(self.request)
query = typ.get_query() query = typ.get_query()
sorted_query = typ.sort_query(query) sorted_query = typ.sort_query(query)
self.assertIs(sorted_query, query) self.assertIs(sorted_query, query)
@ -226,14 +231,16 @@ 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):
typ = mod.ObjectRef(self.request)
widget = typ.widget_maker() widget = typ.widget_maker()
self.assertEqual(len(widget.values), 1) self.assertEqual(len(widget.values), 1)
self.assertEqual(widget.values[0][1], "Betty Boop") 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):
typ = mod.ObjectRef(self.request, empty_option=True)
widget = typ.widget_maker() widget = typ.widget_maker()
self.assertEqual(len(widget.values), 2) self.assertEqual(len(widget.values), 2)
self.assertEqual(widget.values[0][1], "(none)") self.assertEqual(widget.values[0][1], "(none)")
@ -243,7 +250,8 @@ class TestObjectRef(DataTestCase):
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):
typ = mod.PersonRef(self.request)
query = typ.get_query() query = typ.get_query()
self.assertIsInstance(query, orm.Query) self.assertIsInstance(query, orm.Query)
sorted_query = typ.sort_query(query) sorted_query = typ.sort_query(query)
@ -253,7 +261,8 @@ class TestPersonRef(WebTestCase):
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)
@ -267,7 +276,8 @@ class TestPersonRef(WebTestCase):
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):
typ = mod.RoleRef(self.request)
query = typ.get_query() query = typ.get_query()
self.assertIsInstance(query, orm.Query) self.assertIsInstance(query, orm.Query)
sorted_query = typ.sort_query(query) sorted_query = typ.sort_query(query)
@ -277,7 +287,8 @@ class TestRoleRef(WebTestCase):
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)
@ -291,7 +302,8 @@ class TestRoleRef(WebTestCase):
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):
typ = mod.UserRef(self.request)
query = typ.get_query() query = typ.get_query()
self.assertIsInstance(query, orm.Query) self.assertIsInstance(query, orm.Query)
sorted_query = typ.sort_query(query) sorted_query = typ.sort_query(query)
@ -301,7 +313,8 @@ class TestUserRef(WebTestCase):
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)
@ -320,7 +333,8 @@ 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):
typ = mod.UserRefs(self.request)
widget = typ.widget_maker() widget = typ.widget_maker()
self.assertIsInstance(widget, widgets.UserRefsWidget) self.assertIsInstance(widget, widgets.UserRefsWidget)
@ -341,9 +355,11 @@ class TestRoleRefs(DataTestCase):
self.session.add(blokes) self.session.add(blokes)
self.session.commit() self.session.commit()
with patch.object(mod, 'Session', return_value=self.session):
# with root access, default values include: admin, blokes # with root access, default values include: admin, blokes
self.request.is_root = True 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), 2) self.assertEqual(len(widget.values), 2)
self.assertEqual(widget.values[0][1], "Administrator") self.assertEqual(widget.values[0][1], "Administrator")
@ -351,7 +367,7 @@ class TestRoleRefs(DataTestCase):
# without root, default values include: blokes # without root, default values include: blokes
self.request.is_root = False self.request.is_root = False
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), 1)
self.assertEqual(widget.values[0][1], "Blokes") self.assertEqual(widget.values[0][1], "Blokes")

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,15 +33,17 @@ class TestObjectRefWidget(WebTestCase):
self.session.add(person) self.session.add(person)
self.session.commit() self.session.commit()
with patch.object(schema, 'Session', return_value=self.session):
# standard (editable) # standard (editable)
node = colander.SchemaNode(PersonRef(self.request, session=self.session)) node = colander.SchemaNode(PersonRef(self.request))
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)
self.assertIn('<b-select ', html) self.assertIn('<b-select ', html)
# readonly # 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() widget = self.make_widget()
field = self.make_field(node) field = self.make_field(node)
@ -49,7 +52,7 @@ class TestObjectRefWidget(WebTestCase):
self.assertNotIn('<a', html) self.assertNotIn('<a', html)
# with hyperlink # with hyperlink
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(url=lambda p: '/foo')
field = self.make_field(node) field = self.make_field(node)
@ -64,8 +67,10 @@ class TestObjectRefWidget(WebTestCase):
self.session.add(person) self.session.add(person)
self.session.commit() self.session.commit()
with patch.object(schema, 'Session', return_value=self.session):
# standard # standard
node = colander.SchemaNode(PersonRef(self.request, session=self.session)) node = colander.SchemaNode(PersonRef(self.request))
widget = self.make_widget() widget = self.make_widget()
field = self.make_field(node) field = self.make_field(node)
values = widget.get_template_values(field, person.uuid, {}) values = widget.get_template_values(field, person.uuid, {})
@ -73,7 +78,7 @@ class TestObjectRefWidget(WebTestCase):
self.assertNotIn('url', values) self.assertNotIn('url', values)
# readonly w/ empty option # readonly w/ empty option
node = colander.SchemaNode(PersonRef(self.request, session=self.session, node = colander.SchemaNode(PersonRef(self.request,
empty_option=('_empty_', '(empty)'))) empty_option=('_empty_', '(empty)')))
widget = self.make_widget(readonly=True, url=lambda obj: '/foo') widget = self.make_widget(readonly=True, url=lambda obj: '/foo')
field = self.make_field(node) field = self.make_field(node)
@ -230,7 +235,8 @@ 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):
node = colander.SchemaNode(RoleRefs(self.request))
field = self.make_field(node) field = self.make_field(node)
widget = field.widget widget = field.widget
@ -246,7 +252,7 @@ class TestRoleRefsWidget(WebTestCase):
# 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})
@ -266,7 +272,9 @@ 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))
with patch.object(schema, 'Session', return_value=self.session):
node = colander.SchemaNode(UserRefs(self.request))
field = self.make_field(node) field = self.make_field(node)
widget = field.widget widget = field.widget
@ -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