From a219f3e30d1973e72fd761bac7b07bf1f644b799 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Thu, 2 Jan 2025 21:09:31 -0600 Subject: [PATCH] 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 --- src/wuttaweb/forms/schema.py | 32 +++--- src/wuttaweb/forms/widgets.py | 9 +- tests/forms/test_schema.py | 200 ++++++++++++++++++---------------- tests/forms/test_widgets.py | 174 +++++++++++++++-------------- 4 files changed, 214 insertions(+), 201 deletions(-) diff --git a/src/wuttaweb/forms/schema.py b/src/wuttaweb/forms/schema.py index 7591a7a..a7f5de2 100644 --- a/src/wuttaweb/forms/schema.py +++ b/src/wuttaweb/forms/schema.py @@ -181,21 +181,16 @@ class WuttaSet(colander.Set): """ Custom schema type for :class:`python:set` fields. - This is a subclass of :class:`colander.Set`, but adds - Wutta-related params to the constructor. + This is a subclass of :class:`colander.Set`. :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__() self.request = request self.config = self.request.wutta_config self.app = self.config.get_app() - self.session = session or Session() class ObjectRef(colander.SchemaType): @@ -231,7 +226,6 @@ class ObjectRef(colander.SchemaType): self, request, empty_option=None, - session=None, *args, **kwargs, ): @@ -240,7 +234,7 @@ class ObjectRef(colander.SchemaType): self.config = self.request.wutta_config self.app = self.config.get_app() self.model_instance = None - self.session = session or Session() + self.session = Session() if empty_option: if empty_option is True: @@ -472,7 +466,7 @@ class RoleRefs(WuttaSet): :returns: Instance of :class:`~wuttaweb.forms.widgets.RoleRefsWidget`. """ - kwargs.setdefault('session', self.session) + session = kwargs.setdefault('session', Session()) if 'values' not in kwargs: model = self.app.model @@ -480,20 +474,20 @@ class RoleRefs(WuttaSet): # avoid built-ins which cannot be assigned to users avoid = { - auth.get_role_authenticated(self.session), - auth.get_role_anonymous(self.session), + auth.get_role_authenticated(session), + auth.get_role_anonymous(session), } avoid = set([role.uuid for role in avoid]) # also avoid admin unless current user 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 - roles = self.session.query(model.Role)\ - .filter(~model.Role.uuid.in_(avoid))\ - .order_by(model.Role.name)\ - .all() + roles = session.query(model.Role)\ + .filter(~model.Role.uuid.in_(avoid))\ + .order_by(model.Role.name)\ + .all() values = [(role.uuid.hex, role.name) for role in roles] kwargs['values'] = values @@ -518,7 +512,7 @@ class UserRefs(WuttaSet): :returns: Instance of :class:`~wuttaweb.forms.widgets.UserRefsWidget`. """ - kwargs.setdefault('session', self.session) + kwargs.setdefault('session', Session()) return widgets.UserRefsWidget(self.request, **kwargs) @@ -548,7 +542,7 @@ class Permissions(WuttaSet): :returns: Instance of :class:`~wuttaweb.forms.widgets.PermissionsWidget`. """ - kwargs.setdefault('session', self.session) + kwargs.setdefault('session', Session()) kwargs.setdefault('permissions', self.permissions) if 'values' not in kwargs: diff --git a/src/wuttaweb/forms/widgets.py b/src/wuttaweb/forms/widgets.py index 0af8bab..7b3e4be 100644 --- a/src/wuttaweb/forms/widgets.py +++ b/src/wuttaweb/forms/widgets.py @@ -136,26 +136,21 @@ class WuttaCheckboxChoiceWidget(CheckboxChoiceWidget): Custom widget for :class:`python:set` fields. This is a subclass of - :class:`deform:deform.widget.CheckboxChoiceWidget`, but adds - Wutta-related params to the constructor. + :class:`deform:deform.widget.CheckboxChoiceWidget`. :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: * ``checkbox_choice`` * ``readonly/checkbox_choice`` """ - def __init__(self, request, session=None, *args, **kwargs): + def __init__(self, request, *args, **kwargs): super().__init__(*args, **kwargs) self.request = request self.config = self.request.wutta_config self.app = self.config.get_app() - self.session = session or Session() class WuttaDateTimeWidget(DateTimeInputWidget): diff --git a/tests/forms/test_schema.py b/tests/forms/test_schema.py index 564e8c2..117291d 100644 --- a/tests/forms/test_schema.py +++ b/tests/forms/test_schema.py @@ -155,9 +155,10 @@ class TestObjectRef(DataTestCase): self.session.commit() self.assertIsNotNone(person.uuid) with patch.object(mod.ObjectRef, 'model_class', new=model.Person): - typ = mod.ObjectRef(self.request, session=self.session) - value = typ.deserialize(node, person.uuid) - self.assertIs(value, person) + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.ObjectRef(self.request) + value = typ.deserialize(node, person.uuid) + self.assertIs(value, person) def test_dictify(self): model = self.app.model @@ -181,42 +182,46 @@ class TestObjectRef(DataTestCase): value = typ.objectify(None) self.assertIsNone(value) - # model instance - 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): + with patch.object(mod, 'Session', return_value=self.session): - # can specify as uuid - typ = mod.ObjectRef(self.request, session=self.session) - value = typ.objectify(person.uuid) - self.assertIs(value, person) + # model instance + 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): - # or can specify object proper - typ = mod.ObjectRef(self.request, session=self.session) - value = typ.objectify(person) - self.assertIs(value, person) + # can specify as uuid + typ = mod.ObjectRef(self.request) + value = typ.objectify(person.uuid) + self.assertIs(value, person) - # error if not found - with patch.object(mod.ObjectRef, 'model_class', new=model.Person): - typ = mod.ObjectRef(self.request, session=self.session) - self.assertRaises(ValueError, typ.objectify, 'WRONG-UUID') + # or can specify object proper + typ = mod.ObjectRef(self.request) + value = typ.objectify(person) + 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): model = self.app.model with patch.object(mod.ObjectRef, 'model_class', new=model.Person): - typ = mod.ObjectRef(self.request, session=self.session) - query = typ.get_query() - self.assertIsInstance(query, orm.Query) + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.ObjectRef(self.request) + query = typ.get_query() + self.assertIsInstance(query, orm.Query) def test_sort_query(self): model = self.app.model with patch.object(mod.ObjectRef, 'model_class', new=model.Person): - typ = mod.ObjectRef(self.request, session=self.session) - query = typ.get_query() - sorted_query = typ.sort_query(query) - self.assertIs(sorted_query, query) + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.ObjectRef(self.request) + query = typ.get_query() + sorted_query = typ.sort_query(query) + self.assertIs(sorted_query, query) def test_widget_maker(self): model = self.app.model @@ -226,90 +231,98 @@ class TestObjectRef(DataTestCase): # basic with patch.object(mod.ObjectRef, 'model_class', new=model.Person): - typ = mod.ObjectRef(self.request, session=self.session) - widget = typ.widget_maker() - self.assertEqual(len(widget.values), 1) - self.assertEqual(widget.values[0][1], "Betty Boop") + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.ObjectRef(self.request) + widget = typ.widget_maker() + self.assertEqual(len(widget.values), 1) + self.assertEqual(widget.values[0][1], "Betty Boop") # empty option with patch.object(mod.ObjectRef, 'model_class', new=model.Person): - typ = mod.ObjectRef(self.request, session=self.session, empty_option=True) - widget = typ.widget_maker() - self.assertEqual(len(widget.values), 2) - self.assertEqual(widget.values[0][1], "(none)") - self.assertEqual(widget.values[1][1], "Betty Boop") + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.ObjectRef(self.request, empty_option=True) + widget = typ.widget_maker() + self.assertEqual(len(widget.values), 2) + self.assertEqual(widget.values[0][1], "(none)") + self.assertEqual(widget.values[1][1], "Betty Boop") class TestPersonRef(WebTestCase): def test_sort_query(self): - typ = mod.PersonRef(self.request, session=self.session) - query = typ.get_query() - self.assertIsInstance(query, orm.Query) - sorted_query = typ.sort_query(query) - self.assertIsInstance(sorted_query, orm.Query) - self.assertIsNot(sorted_query, query) + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.PersonRef(self.request) + query = typ.get_query() + self.assertIsInstance(query, orm.Query) + sorted_query = typ.sort_query(query) + self.assertIsInstance(sorted_query, orm.Query) + self.assertIsNot(sorted_query, query) def test_get_object_url(self): self.pyramid_config.add_route('people.view', '/people/{uuid}') 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") - self.session.add(person) - self.session.commit() + person = model.Person(full_name="Barney Rubble") + self.session.add(person) + self.session.commit() - url = typ.get_object_url(person) - self.assertIsNotNone(url) - self.assertIn(f'/people/{person.uuid}', url) + url = typ.get_object_url(person) + self.assertIsNotNone(url) + self.assertIn(f'/people/{person.uuid}', url) class TestRoleRef(WebTestCase): def test_sort_query(self): - typ = mod.RoleRef(self.request, session=self.session) - query = typ.get_query() - self.assertIsInstance(query, orm.Query) - sorted_query = typ.sort_query(query) - self.assertIsInstance(sorted_query, orm.Query) - self.assertIsNot(sorted_query, query) + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.RoleRef(self.request) + query = typ.get_query() + self.assertIsInstance(query, orm.Query) + sorted_query = typ.sort_query(query) + self.assertIsInstance(sorted_query, orm.Query) + self.assertIsNot(sorted_query, query) def test_get_object_url(self): self.pyramid_config.add_route('roles.view', '/roles/{uuid}') 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') - self.session.add(role) - self.session.commit() + role = model.Role(name='Manager') + self.session.add(role) + self.session.commit() - url = typ.get_object_url(role) - self.assertIsNotNone(url) - self.assertIn(f'/roles/{role.uuid}', url) + url = typ.get_object_url(role) + self.assertIsNotNone(url) + self.assertIn(f'/roles/{role.uuid}', url) class TestUserRef(WebTestCase): def test_sort_query(self): - typ = mod.UserRef(self.request, session=self.session) - query = typ.get_query() - self.assertIsInstance(query, orm.Query) - sorted_query = typ.sort_query(query) - self.assertIsInstance(sorted_query, orm.Query) - self.assertIsNot(sorted_query, query) + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.UserRef(self.request) + query = typ.get_query() + self.assertIsInstance(query, orm.Query) + sorted_query = typ.sort_query(query) + self.assertIsInstance(sorted_query, orm.Query) + self.assertIsNot(sorted_query, query) def test_get_object_url(self): self.pyramid_config.add_route('users.view', '/users/{uuid}') 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') - self.session.add(user) - self.session.commit() + user = model.User(username='barney') + self.session.add(user) + self.session.commit() - url = typ.get_object_url(user) - self.assertIsNotNone(url) - self.assertIn(f'/users/{user.uuid}', url) + url = typ.get_object_url(user) + self.assertIsNotNone(url) + self.assertIn(f'/users/{user.uuid}', url) class TestUserRefs(DataTestCase): @@ -320,9 +333,10 @@ class TestUserRefs(DataTestCase): def test_widget_maker(self): model = self.app.model - typ = mod.UserRefs(self.request, session=self.session) - widget = typ.widget_maker() - self.assertIsInstance(widget, widgets.UserRefsWidget) + with patch.object(mod, 'Session', return_value=self.session): + typ = mod.UserRefs(self.request) + widget = typ.widget_maker() + self.assertIsInstance(widget, widgets.UserRefsWidget) class TestRoleRefs(DataTestCase): @@ -341,20 +355,22 @@ class TestRoleRefs(DataTestCase): self.session.add(blokes) self.session.commit() - # with root access, default values include: admin, blokes - 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") + with patch.object(mod, 'Session', return_value=self.session): - # without root, default values include: blokes - self.request.is_root = False - typ = mod.RoleRefs(self.request, session=self.session) - widget = typ.widget_maker() - self.assertEqual(len(widget.values), 1) - self.assertEqual(widget.values[0][1], "Blokes") + # with root access, default values include: admin, blokes + self.request.is_root = True + typ = mod.RoleRefs(self.request) + 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 + 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): diff --git a/tests/forms/test_widgets.py b/tests/forms/test_widgets.py index f98210c..3e07902 100644 --- a/tests/forms/test_widgets.py +++ b/tests/forms/test_widgets.py @@ -10,6 +10,7 @@ from pyramid import testing from wuttaweb import grids from wuttaweb.forms import widgets as mod +from wuttaweb.forms import schema from wuttaweb.forms.schema import (FileDownload, PersonRef, RoleRefs, UserRefs, Permissions, WuttaDateTime, EmailRecipients) from tests.util import WebTestCase @@ -32,31 +33,33 @@ class TestObjectRefWidget(WebTestCase): self.session.add(person) self.session.commit() - # standard (editable) - 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('') + # empty + html = widget.serialize(field, set(), readonly=True) + self.assertEqual(html, '') - # with data, no actions - user = model.User(username='barney') - self.session.add(user) - self.session.commit() - html = widget.serialize(field, {user.uuid}, readonly=True) - self.assertIn('