From b73127e350d7b89125ed14b675fc11150def969f Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Tue, 7 Jan 2025 13:34:42 -0600 Subject: [PATCH] fix: make WuttaQuantity serialize w/ app handler, remove custom widget turns out we need to always serialize the value via render_quantity() and the widget becomes redundant --- src/wuttaweb/forms/schema.py | 14 ++++++++++---- src/wuttaweb/forms/widgets.py | 36 ----------------------------------- tests/forms/__init__.py | 0 tests/forms/test_schema.py | 27 ++++++++++++++++++++------ tests/forms/test_widgets.py | 30 ----------------------------- 5 files changed, 31 insertions(+), 76 deletions(-) delete mode 100644 tests/forms/__init__.py diff --git a/src/wuttaweb/forms/schema.py b/src/wuttaweb/forms/schema.py index 3d0e08b..07502e6 100644 --- a/src/wuttaweb/forms/schema.py +++ b/src/wuttaweb/forms/schema.py @@ -181,8 +181,9 @@ class WuttaQuantity(colander.Decimal): """ Custom schema type for "quantity" fields. - This is a subclass of :class:`colander:colander.Decimal` but uses - :class:`~wuttaweb.forms.widgets.WuttaQuantityWidget` by default. + This is a subclass of :class:`colander:colander.Decimal` but will + serialize values via + :meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_quantity()`. :param request: Current :term:`request` object. """ @@ -193,9 +194,14 @@ class WuttaQuantity(colander.Decimal): self.config = self.request.wutta_config self.app = self.config.get_app() - def widget_maker(self, **kwargs): + def serialize(self, node, appstruct): """ """ - return widgets.WuttaQuantityWidget(self.request, **kwargs) + if appstruct in (colander.null, None): + return colander.null + + # nb. we render as quantity here to avoid values like 12.0000, + # so we just show value like 12 instead + return self.app.render_quantity(appstruct) class WuttaSet(colander.Set): diff --git a/src/wuttaweb/forms/widgets.py b/src/wuttaweb/forms/widgets.py index a6f33d2..7b3e4be 100644 --- a/src/wuttaweb/forms/widgets.py +++ b/src/wuttaweb/forms/widgets.py @@ -226,42 +226,6 @@ class WuttaMoneyInputWidget(MoneyInputWidget): return super().serialize(field, cstruct, **kw) -class WuttaQuantityWidget(TextInputWidget): - """ - Custom widget for "quantity" fields. This is used by default for - :class:`~wuttaweb.forms.schema.WuttaQuantity` type nodes. - - The main purpose of this widget is to leverage - :meth:`~wuttjamaican:wuttjamaican.app.AppHandler.render_quantity()` - for the readonly display. - - This is a subclass of - :class:`deform:deform.widget.TextInputWidget` and uses these - Deform templates: - - * ``textinput`` - - :param request: Current :term:`request` object. - """ - - 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() - - def serialize(self, field, cstruct, **kw): - """ """ - readonly = kw.get('readonly', self.readonly) - if readonly: - if cstruct in (colander.null, None): - return HTML.tag('span') - cstruct = decimal.Decimal(cstruct) - return HTML.tag('span', c=[self.app.render_quantity(cstruct)]) - - return super().serialize(field, cstruct, **kw) - - class FileDownloadWidget(Widget): """ Widget for use with :class:`~wuttaweb.forms.schema.FileDownload` diff --git a/tests/forms/__init__.py b/tests/forms/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/forms/test_schema.py b/tests/forms/test_schema.py index 80a40e2..b7b68c4 100644 --- a/tests/forms/test_schema.py +++ b/tests/forms/test_schema.py @@ -1,6 +1,7 @@ # -*- coding: utf-8; -*- import datetime +import decimal from unittest import TestCase from unittest.mock import patch @@ -15,7 +16,7 @@ from wuttaweb.forms import widgets from wuttaweb.testing import DataTestCase, WebTestCase -class TestWutaDateTime(TestCase): +class TestWuttaDateTime(TestCase): def test_deserialize(self): typ = mod.WuttaDateTime() @@ -91,11 +92,25 @@ class TestWuttaMoney(WebTestCase): class TestWuttaQuantity(WebTestCase): - def test_widget_maker(self): - enum = self.app.enum - typ = mod.WuttaQuantity(self.request) - widget = typ.widget_maker() - self.assertIsInstance(widget, widgets.WuttaQuantityWidget) + def test_serialize(self): + node = colander.SchemaNode(mod.WuttaQuantity(self.request)) + typ = node.typ + + # null + result = typ.serialize(node, colander.null) + self.assertIs(result, colander.null) + result = typ.serialize(node, None) + self.assertIs(result, colander.null) + + # quantity + result = typ.serialize(node, 42) + self.assertEqual(result, '42') + result = typ.serialize(node, 42.00) + self.assertEqual(result, '42') + result = typ.serialize(node, decimal.Decimal('42.00')) + self.assertEqual(result, '42') + result = typ.serialize(node, 42.13) + self.assertEqual(result, '42.13') class TestObjectRef(DataTestCase): diff --git a/tests/forms/test_widgets.py b/tests/forms/test_widgets.py index 47aed58..4874c25 100644 --- a/tests/forms/test_widgets.py +++ b/tests/forms/test_widgets.py @@ -143,36 +143,6 @@ class TestWuttaMoneyInputWidget(WebTestCase): self.assertEqual(result, '') -class TestWuttaQuantityWidget(WebTestCase): - - def make_field(self, node, **kwargs): - # TODO: not sure why default renderer is in use even though - # pyramid_deform was included in setup? but this works.. - kwargs.setdefault('renderer', deform.Form.default_renderer) - return deform.Field(node, **kwargs) - - def make_widget(self, **kwargs): - return mod.WuttaQuantityWidget(self.request, **kwargs) - - def test_serialize(self): - node = colander.SchemaNode(schema.WuttaQuantity(self.request)) - field = self.make_field(node) - widget = self.make_widget() - amount = decimal.Decimal('42.00') - - # editable widget has normal text input - result = widget.serialize(field, str(amount)) - self.assertIn('42') - - # readonly w/ null value - result = widget.serialize(field, None, readonly=True) - self.assertEqual(result, '') - - class TestFileDownloadWidget(WebTestCase): def make_field(self, node, **kwargs):