3
0
Fork 0

fix: format all code with black

and from now on should not deviate from that...
This commit is contained in:
Lance Edgar 2025-08-31 12:26:43 -05:00
parent 8a09fb1a3c
commit 4d0693862d
68 changed files with 6693 additions and 5659 deletions

View file

@ -18,17 +18,22 @@ from wuttaweb.grids import Grid
class TestForm(TestCase):
def setUp(self):
self.config = WuttaConfig(defaults={
'wutta.web.menus.handler_spec': 'tests.util:NullMenuHandler',
})
self.config = WuttaConfig(
defaults={
"wutta.web.menus.handler_spec": "tests.util:NullMenuHandler",
}
)
self.app = self.config.get_app()
self.request = testing.DummyRequest(wutta_config=self.config, use_oruga=False)
self.pyramid_config = testing.setUp(request=self.request, settings={
'wutta_config': self.config,
'mako.directories': ['wuttaweb:templates'],
'pyramid_deform.template_search_path': 'wuttaweb:templates/deform',
})
self.pyramid_config = testing.setUp(
request=self.request,
settings={
"wutta_config": self.config,
"mako.directories": ["wuttaweb:templates"],
"pyramid_deform.template_search_path": "wuttaweb:templates/deform",
},
)
event = MagicMock(request=self.request)
subscribers.new_request(event)
@ -40,12 +45,12 @@ class TestForm(TestCase):
return base.Form(self.request, **kwargs)
def make_schema(self):
schema = colander.Schema(children=[
colander.SchemaNode(colander.String(),
name='foo'),
colander.SchemaNode(colander.String(),
name='bar'),
])
schema = colander.Schema(
children=[
colander.SchemaNode(colander.String(), name="foo"),
colander.SchemaNode(colander.String(), name="bar"),
]
)
return schema
def test_init_with_none(self):
@ -53,126 +58,126 @@ class TestForm(TestCase):
self.assertEqual(form.fields, [])
def test_init_with_fields(self):
form = self.make_form(fields=['foo', 'bar'])
self.assertEqual(form.fields, ['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.fields, ["foo", "bar"])
def test_init_with_schema(self):
schema = self.make_schema()
form = self.make_form(schema=schema)
self.assertEqual(form.fields, ['foo', 'bar'])
self.assertEqual(form.fields, ["foo", "bar"])
def test_vue_tagname(self):
form = self.make_form()
self.assertEqual(form.vue_tagname, 'wutta-form')
self.assertEqual(form.vue_tagname, "wutta-form")
def test_vue_component(self):
form = self.make_form()
self.assertEqual(form.vue_component, 'WuttaForm')
self.assertEqual(form.vue_component, "WuttaForm")
def test_contains(self):
form = self.make_form(fields=['foo', 'bar'])
self.assertIn('foo', form)
self.assertNotIn('baz', form)
form = self.make_form(fields=["foo", "bar"])
self.assertIn("foo", form)
self.assertNotIn("baz", form)
def test_iter(self):
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
fields = list(iter(form))
self.assertEqual(fields, ['foo', 'bar'])
self.assertEqual(fields, ["foo", "bar"])
fields = []
for field in form:
fields.append(field)
self.assertEqual(fields, ['foo', 'bar'])
self.assertEqual(fields, ["foo", "bar"])
def test_set_fields(self):
form = self.make_form(fields=['foo', 'bar'])
self.assertEqual(form.fields, ['foo', 'bar'])
form.set_fields(['baz'])
self.assertEqual(form.fields, ['baz'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.fields, ["foo", "bar"])
form.set_fields(["baz"])
self.assertEqual(form.fields, ["baz"])
def test_append(self):
form = self.make_form(fields=['one', 'two'])
self.assertEqual(form.fields, ['one', 'two'])
form.append('one', 'two', 'three')
self.assertEqual(form.fields, ['one', 'two', 'three'])
form = self.make_form(fields=["one", "two"])
self.assertEqual(form.fields, ["one", "two"])
form.append("one", "two", "three")
self.assertEqual(form.fields, ["one", "two", "three"])
def test_remove(self):
form = self.make_form(fields=['one', 'two', 'three', 'four'])
self.assertEqual(form.fields, ['one', 'two', 'three', 'four'])
form.remove('two', 'three')
self.assertEqual(form.fields, ['one', 'four'])
form = self.make_form(fields=["one", "two", "three", "four"])
self.assertEqual(form.fields, ["one", "two", "three", "four"])
form.remove("two", "three")
self.assertEqual(form.fields, ["one", "four"])
def test_set_node(self):
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.nodes, {})
# complete node
node = colander.SchemaNode(colander.Bool(), name='foo')
form.set_node('foo', node)
self.assertIs(form.nodes['foo'], node)
node = colander.SchemaNode(colander.Bool(), name="foo")
form.set_node("foo", node)
self.assertIs(form.nodes["foo"], node)
# type only
typ = colander.Bool()
form.set_node('foo', typ)
node = form.nodes['foo']
form.set_node("foo", typ)
node = form.nodes["foo"]
self.assertIsInstance(node, colander.SchemaNode)
self.assertIsInstance(node.typ, colander.Bool)
self.assertEqual(node.name, 'foo')
self.assertEqual(node.name, "foo")
# schema is updated if already present
schema = form.get_schema()
self.assertIsNotNone(schema)
typ = colander.Date()
form.set_node('foo', typ)
node = form.nodes['foo']
form.set_node("foo", typ)
node = form.nodes["foo"]
self.assertIsInstance(node, colander.SchemaNode)
self.assertIsInstance(node.typ, colander.Date)
self.assertEqual(node.name, 'foo')
self.assertEqual(node.name, "foo")
def test_set_widget(self):
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.widgets, {})
# basic
widget = widgets.SelectWidget()
form.set_widget('foo', widget)
self.assertIs(form.widgets['foo'], widget)
form.set_widget("foo", widget)
self.assertIs(form.widgets["foo"], widget)
# schema is updated if already present
schema = form.get_schema()
self.assertIsNotNone(schema)
self.assertIs(schema['foo'].widget, widget)
self.assertIs(schema["foo"].widget, widget)
new_widget = widgets.TextInputWidget()
form.set_widget('foo', new_widget)
self.assertIs(form.widgets['foo'], new_widget)
self.assertIs(schema['foo'].widget, new_widget)
form.set_widget("foo", new_widget)
self.assertIs(form.widgets["foo"], new_widget)
self.assertIs(schema["foo"].widget, new_widget)
# can also just specify widget pseudo-type (invalid)
self.assertNotIn('bar', form.widgets)
self.assertRaises(ValueError, form.set_widget, 'bar', 'ldjfadjfadj')
self.assertNotIn("bar", form.widgets)
self.assertRaises(ValueError, form.set_widget, "bar", "ldjfadjfadj")
# can also just specify widget pseudo-type (valid)
self.assertNotIn('bar', form.widgets)
form.set_widget('bar', 'notes')
self.assertIsInstance(form.widgets['bar'], widgets.NotesWidget)
self.assertNotIn("bar", form.widgets)
form.set_widget("bar", "notes")
self.assertIsInstance(form.widgets["bar"], widgets.NotesWidget)
def test_make_widget(self):
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
# notes
widget = form.make_widget('notes')
widget = form.make_widget("notes")
self.assertIsInstance(widget, widgets.NotesWidget)
# invalid
widget = form.make_widget('fdajvdafjjf')
widget = form.make_widget("fdajvdafjjf")
self.assertIsNone(widget)
def test_set_default_widgets(self):
model = self.app.model
# no defaults for "plain" schema
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.widgets, {})
# no defaults for "plain" mapped class
@ -184,52 +189,56 @@ class TestForm(TestCase):
# widget set for datetime mapped field
form = self.make_form(model_class=model.Upgrade)
self.assertIn('created', form.widgets)
self.assertIsNot(form.widgets['created'], MyWidget)
self.assertNotIsInstance(form.widgets['created'], MyWidget)
self.assertIn("created", form.widgets)
self.assertIsNot(form.widgets["created"], MyWidget)
self.assertNotIsInstance(form.widgets["created"], MyWidget)
# widget *not* set for datetime, if override present
form = self.make_form(model_class=model.Upgrade,
widgets={'created': MyWidget()})
self.assertIn('created', form.widgets)
self.assertIsInstance(form.widgets['created'], MyWidget)
form = self.make_form(
model_class=model.Upgrade, widgets={"created": MyWidget()}
)
self.assertIn("created", form.widgets)
self.assertIsInstance(form.widgets["created"], MyWidget)
# mock up a table with all relevant column types
class Whatever(model.Base):
__tablename__ = 'whatever'
__tablename__ = "whatever"
id = sa.Column(sa.Integer(), primary_key=True)
date = sa.Column(sa.Date())
date_time = sa.Column(sa.DateTime())
# widget set for all known types
form = self.make_form(model_class=Whatever)
self.assertIsInstance(form.widgets['date'], widgets.WuttaDateWidget)
self.assertIsInstance(form.widgets['date_time'], widgets.WuttaDateTimeWidget)
self.assertIsInstance(form.widgets["date"], widgets.WuttaDateWidget)
self.assertIsInstance(form.widgets["date_time"], widgets.WuttaDateTimeWidget)
def test_set_grid(self):
form = self.make_form(fields=['foo', 'bar'])
self.assertNotIn('foo', form.widgets)
self.assertNotIn('foogrid', form.grid_vue_context)
form = self.make_form(fields=["foo", "bar"])
self.assertNotIn("foo", form.widgets)
self.assertNotIn("foogrid", form.grid_vue_context)
grid = Grid(self.request, key='foogrid',
columns=['a', 'b'],
data=[{'a': 1, 'b': 2}, {'a': 3, 'b': 4}])
grid = Grid(
self.request,
key="foogrid",
columns=["a", "b"],
data=[{"a": 1, "b": 2}, {"a": 3, "b": 4}],
)
form.set_grid('foo', grid)
self.assertIn('foo', form.widgets)
self.assertIsInstance(form.widgets['foo'], widgets.GridWidget)
self.assertIn('foogrid', form.grid_vue_context)
form.set_grid("foo", grid)
self.assertIn("foo", form.widgets)
self.assertIsInstance(form.widgets["foo"], widgets.GridWidget)
self.assertIn("foogrid", form.grid_vue_context)
def test_set_validator(self):
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.validators, {})
def validate1(node, value):
pass
# basic
form.set_validator('foo', validate1)
self.assertIs(form.validators['foo'], validate1)
form.set_validator("foo", validate1)
self.assertIs(form.validators["foo"], validate1)
def validate2(node, value):
pass
@ -237,18 +246,18 @@ class TestForm(TestCase):
# schema is updated if already present
schema = form.get_schema()
self.assertIsNotNone(schema)
self.assertIs(schema['foo'].validator, validate1)
form.set_validator('foo', validate2)
self.assertIs(form.validators['foo'], validate2)
self.assertIs(schema['foo'].validator, validate2)
self.assertIs(schema["foo"].validator, validate1)
form.set_validator("foo", validate2)
self.assertIs(form.validators["foo"], validate2)
self.assertIs(schema["foo"].validator, validate2)
def test_set_default(self):
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.defaults, {})
# basic
form.set_default('foo', 42)
self.assertEqual(form.defaults['foo'], 42)
form.set_default("foo", 42)
self.assertEqual(form.defaults["foo"], 42)
def test_get_schema(self):
model = self.app.model
@ -262,10 +271,10 @@ class TestForm(TestCase):
self.assertIs(form.get_schema(), schema)
# schema is auto-generated if fields provided
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
schema = form.get_schema()
self.assertEqual(len(schema.children), 2)
self.assertEqual(schema['foo'].name, 'foo')
self.assertEqual(schema["foo"].name, "foo")
# but auto-generating without fields is not supported
form = self.make_form()
@ -276,58 +285,62 @@ class TestForm(TestCase):
form = self.make_form(model_class=model.Setting)
schema = form.get_schema()
self.assertEqual(len(schema.children), 2)
self.assertIn('name', schema)
self.assertIn('value', schema)
self.assertIn("name", schema)
self.assertIn("value", schema)
# but node overrides are honored when auto-generating
form = self.make_form(model_class=model.Setting)
value_node = colander.SchemaNode(colander.Bool(), name='value')
form.set_node('value', value_node)
value_node = colander.SchemaNode(colander.Bool(), name="value")
form.set_node("value", value_node)
schema = form.get_schema()
self.assertIs(schema['value'], value_node)
self.assertIs(schema["value"], value_node)
# schema is auto-generated if model_instance provided
form = self.make_form(model_instance=model.Setting(name='uhoh'))
self.assertEqual(form.fields, ['name', 'value'])
form = self.make_form(model_instance=model.Setting(name="uhoh"))
self.assertEqual(form.fields, ["name", "value"])
self.assertIsNone(form.schema)
# nb. force method to get new fields
del form.fields
schema = form.get_schema()
self.assertEqual(len(schema.children), 2)
self.assertIn('name', schema)
self.assertIn('value', schema)
self.assertIn("name", schema)
self.assertIn("value", schema)
# ColanderAlchemy schema still has *all* requested fields
form = self.make_form(model_instance=model.Setting(name='uhoh'),
fields=['name', 'value', 'foo', 'bar'])
self.assertEqual(form.fields, ['name', 'value', 'foo', 'bar'])
form = self.make_form(
model_instance=model.Setting(name="uhoh"),
fields=["name", "value", "foo", "bar"],
)
self.assertEqual(form.fields, ["name", "value", "foo", "bar"])
self.assertIsNone(form.schema)
schema = form.get_schema()
self.assertEqual(len(schema.children), 4)
self.assertIn('name', schema)
self.assertIn('value', schema)
self.assertIn('foo', schema)
self.assertIn('bar', schema)
self.assertIn("name", schema)
self.assertIn("value", schema)
self.assertIn("foo", schema)
self.assertIn("bar", schema)
# schema nodes are required by default
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
schema = form.get_schema()
self.assertIs(schema['foo'].missing, colander.required)
self.assertIs(schema['bar'].missing, colander.required)
self.assertIs(schema["foo"].missing, colander.required)
self.assertIs(schema["bar"].missing, colander.required)
# but fields can be marked *not* required
form = self.make_form(fields=['foo', 'bar'])
form.set_required('bar', False)
form = self.make_form(fields=["foo", "bar"])
form.set_required("bar", False)
schema = form.get_schema()
self.assertIs(schema['foo'].missing, colander.required)
self.assertIs(schema['bar'].missing, colander.null)
self.assertIs(schema["foo"].missing, colander.required)
self.assertIs(schema["bar"].missing, colander.null)
# validator overrides are honored
def validate(node, value): pass
def validate(node, value):
pass
form = self.make_form(model_class=model.Setting)
form.set_validator('name', validate)
form.set_validator("name", validate)
schema = form.get_schema()
self.assertIs(schema['name'].validator, validate)
self.assertIs(schema["name"].validator, validate)
# validator can be set for whole form
form = self.make_form(model_class=model.Setting)
@ -340,9 +353,9 @@ class TestForm(TestCase):
# default value overrides are honored
form = self.make_form(model_class=model.Setting)
form.set_default('name', 'foo')
form.set_default("name", "foo")
schema = form.get_schema()
self.assertEqual(schema['name'].default, 'foo')
self.assertEqual(schema["name"].default, "foo")
def test_get_deform(self):
model = self.app.model
@ -350,139 +363,142 @@ class TestForm(TestCase):
# basic
form = self.make_form(schema=schema)
self.assertFalse(hasattr(form, 'deform_form'))
self.assertFalse(hasattr(form, "deform_form"))
dform = form.get_deform()
self.assertIsInstance(dform, deform.Form)
self.assertIs(form.deform_form, dform)
# with model instance as dict
myobj = {'foo': 'one', 'bar': 'two'}
myobj = {"foo": "one", "bar": "two"}
form = self.make_form(schema=schema, model_instance=myobj)
dform = form.get_deform()
self.assertEqual(dform.cstruct, myobj)
# with sqlalchemy model instance
myobj = model.Setting(name='foo', value='bar')
myobj = model.Setting(name="foo", value="bar")
form = self.make_form(model_instance=myobj)
dform = form.get_deform()
self.assertEqual(dform.cstruct, {'name': 'foo', 'value': 'bar'})
self.assertEqual(dform.cstruct, {"name": "foo", "value": "bar"})
# sqlalchemy instance with null value
myobj = model.Setting(name='foo', value=None)
myobj = model.Setting(name="foo", value=None)
form = self.make_form(model_instance=myobj)
dform = form.get_deform()
self.assertEqual(dform.cstruct, {'name': 'foo', 'value': colander.null})
self.assertEqual(dform.cstruct, {"name": "foo", "value": colander.null})
def test_get_cancel_url(self):
# is referrer by default
form = self.make_form()
self.request.get_referrer = MagicMock(return_value='/cancel-default')
self.assertEqual(form.get_cancel_url(), '/cancel-default')
self.request.get_referrer = MagicMock(return_value="/cancel-default")
self.assertEqual(form.get_cancel_url(), "/cancel-default")
del self.request.get_referrer
# or can be static URL
form = self.make_form(cancel_url='/cancel-static')
self.assertEqual(form.get_cancel_url(), '/cancel-static')
form = self.make_form(cancel_url="/cancel-static")
self.assertEqual(form.get_cancel_url(), "/cancel-static")
# or can be fallback URL (nb. 'NOPE' indicates no referrer)
form = self.make_form(cancel_url_fallback='/cancel-fallback')
self.request.get_referrer = MagicMock(return_value='NOPE')
self.assertEqual(form.get_cancel_url(), '/cancel-fallback')
form = self.make_form(cancel_url_fallback="/cancel-fallback")
self.request.get_referrer = MagicMock(return_value="NOPE")
self.assertEqual(form.get_cancel_url(), "/cancel-fallback")
del self.request.get_referrer
# or can be referrer fallback, i.e. home page
form = self.make_form()
def get_referrer(default=None):
if default == 'NOPE':
return 'NOPE'
return '/home-page'
if default == "NOPE":
return "NOPE"
return "/home-page"
self.request.get_referrer = get_referrer
self.assertEqual(form.get_cancel_url(), '/home-page')
self.assertEqual(form.get_cancel_url(), "/home-page")
del self.request.get_referrer
def test_get_label(self):
form = self.make_form(fields=['foo', 'bar'])
self.assertEqual(form.get_label('foo'), "Foo")
form.set_label('foo', "Baz")
self.assertEqual(form.get_label('foo'), "Baz")
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.get_label("foo"), "Foo")
form.set_label("foo", "Baz")
self.assertEqual(form.get_label("foo"), "Baz")
def test_set_label(self):
form = self.make_form(fields=['foo', 'bar'])
self.assertEqual(form.get_label('foo'), "Foo")
form.set_label('foo', "Baz")
self.assertEqual(form.get_label('foo'), "Baz")
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.get_label("foo"), "Foo")
form.set_label("foo", "Baz")
self.assertEqual(form.get_label("foo"), "Baz")
# schema should be updated when setting label
schema = self.make_schema()
form = self.make_form(schema=schema)
form.set_label('foo', "Woohoo")
self.assertEqual(form.get_label('foo'), "Woohoo")
self.assertEqual(schema['foo'].title, "Woohoo")
form.set_label("foo", "Woohoo")
self.assertEqual(form.get_label("foo"), "Woohoo")
self.assertEqual(schema["foo"].title, "Woohoo")
def test_readonly_fields(self):
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.readonly_fields, set())
self.assertFalse(form.is_readonly('foo'))
self.assertFalse(form.is_readonly("foo"))
form.set_readonly('foo')
self.assertEqual(form.readonly_fields, {'foo'})
self.assertTrue(form.is_readonly('foo'))
self.assertFalse(form.is_readonly('bar'))
form.set_readonly("foo")
self.assertEqual(form.readonly_fields, {"foo"})
self.assertTrue(form.is_readonly("foo"))
self.assertFalse(form.is_readonly("bar"))
form.set_readonly('bar')
self.assertEqual(form.readonly_fields, {'foo', 'bar'})
self.assertTrue(form.is_readonly('foo'))
self.assertTrue(form.is_readonly('bar'))
form.set_readonly("bar")
self.assertEqual(form.readonly_fields, {"foo", "bar"})
self.assertTrue(form.is_readonly("foo"))
self.assertTrue(form.is_readonly("bar"))
form.set_readonly('foo', False)
self.assertEqual(form.readonly_fields, {'bar'})
self.assertFalse(form.is_readonly('foo'))
self.assertTrue(form.is_readonly('bar'))
form.set_readonly("foo", False)
self.assertEqual(form.readonly_fields, {"bar"})
self.assertFalse(form.is_readonly("foo"))
self.assertTrue(form.is_readonly("bar"))
def test_required_fields(self):
form = self.make_form(fields=['foo', 'bar'])
form = self.make_form(fields=["foo", "bar"])
self.assertEqual(form.required_fields, {})
self.assertIsNone(form.is_required('foo'))
self.assertIsNone(form.is_required("foo"))
form.set_required('foo')
self.assertEqual(form.required_fields, {'foo': True})
self.assertTrue(form.is_required('foo'))
self.assertIsNone(form.is_required('bar'))
form.set_required("foo")
self.assertEqual(form.required_fields, {"foo": True})
self.assertTrue(form.is_required("foo"))
self.assertIsNone(form.is_required("bar"))
form.set_required('bar')
self.assertEqual(form.required_fields, {'foo': True, 'bar': True})
self.assertTrue(form.is_required('foo'))
self.assertTrue(form.is_required('bar'))
form.set_required("bar")
self.assertEqual(form.required_fields, {"foo": True, "bar": True})
self.assertTrue(form.is_required("foo"))
self.assertTrue(form.is_required("bar"))
form.set_required('foo', False)
self.assertEqual(form.required_fields, {'foo': False, 'bar': True})
self.assertFalse(form.is_required('foo'))
self.assertTrue(form.is_required('bar'))
form.set_required("foo", False)
self.assertEqual(form.required_fields, {"foo": False, "bar": True})
self.assertFalse(form.is_required("foo"))
self.assertTrue(form.is_required("bar"))
def test_render_vue_tag(self):
schema = self.make_schema()
form = self.make_form(schema=schema)
html = form.render_vue_tag()
self.assertEqual(html, '<wutta-form></wutta-form>')
self.assertEqual(html, "<wutta-form></wutta-form>")
def test_render_vue_template(self):
self.pyramid_config.include('pyramid_mako')
self.pyramid_config.add_subscriber('wuttaweb.subscribers.before_render',
'pyramid.events.BeforeRender')
self.pyramid_config.include("pyramid_mako")
self.pyramid_config.add_subscriber(
"wuttaweb.subscribers.before_render", "pyramid.events.BeforeRender"
)
# form button is disabled on @submit by default
schema = self.make_schema()
form = self.make_form(schema=schema, cancel_url='/')
form = self.make_form(schema=schema, cancel_url="/")
html = form.render_vue_template()
self.assertIn('<script type="text/x-template" id="wutta-form-template">', html)
self.assertIn('@submit', html)
self.assertIn("@submit", html)
# but not if form is configured otherwise
form = self.make_form(schema=schema, auto_disable_submit=False, cancel_url='/')
form = self.make_form(schema=schema, auto_disable_submit=False, cancel_url="/")
html = form.render_vue_template()
self.assertIn('<script type="text/x-template" id="wutta-form-template">', html)
self.assertNotIn('@submit', html)
self.assertNotIn("@submit", html)
def test_add_grid_vue_context(self):
form = self.make_form()
@ -492,76 +508,84 @@ class TestForm(TestCase):
self.assertRaises(ValueError, form.add_grid_vue_context, grid)
# otherwise it works
grid = Grid(self.request, key='foo')
grid = Grid(self.request, key="foo")
self.assertEqual(len(form.grid_vue_context), 0)
form.add_grid_vue_context(grid)
self.assertEqual(len(form.grid_vue_context), 1)
self.assertIn('foo', form.grid_vue_context)
self.assertEqual(form.grid_vue_context['foo'], {
'data': [],
'row_classes': {},
})
self.assertIn("foo", form.grid_vue_context)
self.assertEqual(
form.grid_vue_context["foo"],
{
"data": [],
"row_classes": {},
},
)
# calling again with same key will replace data
records = [{'foo': 1}, {'foo': 2}]
grid = Grid(self.request, key='foo', columns=['foo'], data=records)
records = [{"foo": 1}, {"foo": 2}]
grid = Grid(self.request, key="foo", columns=["foo"], data=records)
form.add_grid_vue_context(grid)
self.assertEqual(len(form.grid_vue_context), 1)
self.assertIn('foo', form.grid_vue_context)
self.assertEqual(form.grid_vue_context['foo'], {
'data': records,
'row_classes': {},
})
self.assertIn("foo", form.grid_vue_context)
self.assertEqual(
form.grid_vue_context["foo"],
{
"data": records,
"row_classes": {},
},
)
def test_render_vue_finalize(self):
form = self.make_form()
html = form.render_vue_finalize()
self.assertIn('<script>', html)
self.assertIn("<script>", html)
self.assertIn("Vue.component('wutta-form', WuttaForm)", html)
def test_render_vue_field(self):
self.pyramid_config.include('pyramid_deform')
self.pyramid_config.include("pyramid_deform")
schema = self.make_schema()
form = self.make_form(schema=schema)
dform = form.get_deform()
# typical
html = form.render_vue_field('foo')
html = form.render_vue_field("foo")
self.assertIn('<b-field :horizontal="true" label="Foo">', html)
self.assertIn('<b-input name="foo"', html)
# nb. no error message
self.assertNotIn('message', html)
self.assertNotIn("message", html)
# readonly
html = form.render_vue_field('foo', readonly=True)
html = form.render_vue_field("foo", readonly=True)
self.assertIn('<b-field :horizontal="true" label="Foo">', html)
self.assertNotIn('<b-input name="foo"', html)
# nb. no error message
self.assertNotIn('message', html)
self.assertNotIn("message", html)
# with error message
with patch.object(form, 'get_field_errors', return_value=['something is wrong']):
html = form.render_vue_field('foo')
self.assertIn('something is wrong', html)
with patch.object(
form, "get_field_errors", return_value=["something is wrong"]
):
html = form.render_vue_field("foo")
self.assertIn("something is wrong", html)
# add another field, but not to deform, so it should still
# display but with no widget
form.fields.append('zanzibar')
html = form.render_vue_field('zanzibar')
form.fields.append("zanzibar")
html = form.render_vue_field("zanzibar")
self.assertIn('<b-field :horizontal="true" label="Zanzibar">', html)
self.assertNotIn('<b-input', html)
self.assertNotIn("<b-input", html)
# nb. no error message
self.assertNotIn('message', html)
self.assertNotIn("message", html)
# try that once more but with a model record instance
with patch.object(form, 'model_instance', new={'zanzibar': 'omgwtfbbq'}):
html = form.render_vue_field('zanzibar')
self.assertIn('<b-field', html)
with patch.object(form, "model_instance", new={"zanzibar": "omgwtfbbq"}):
html = form.render_vue_field("zanzibar")
self.assertIn("<b-field", html)
self.assertIn('label="Zanzibar"', html)
self.assertNotIn('<b-input', html)
self.assertIn('>omgwtfbbq<', html)
self.assertNotIn("<b-input", html)
self.assertIn(">omgwtfbbq<", html)
# nb. no error message
self.assertNotIn('message', html)
self.assertNotIn("message", html)
def test_get_vue_field_value(self):
schema = self.make_schema()
@ -569,20 +593,20 @@ class TestForm(TestCase):
# TODO: yikes what a hack (?)
dform = form.get_deform()
dform.set_appstruct({'foo': 'one', 'bar': 'two'})
dform.set_appstruct({"foo": "one", "bar": "two"})
# null for missing field
value = form.get_vue_field_value('doesnotexist')
value = form.get_vue_field_value("doesnotexist")
self.assertIsNone(value)
# normal value is returned
value = form.get_vue_field_value('foo')
self.assertEqual(value, 'one')
value = form.get_vue_field_value("foo")
self.assertEqual(value, "one")
# but not if we remove field from deform
# TODO: what is the use case here again?
dform.children.remove(dform['foo'])
value = form.get_vue_field_value('foo')
dform.children.remove(dform["foo"])
value = form.get_vue_field_value("foo")
self.assertIsNone(value)
def test_get_vue_model_data(self):
@ -594,19 +618,22 @@ class TestForm(TestCase):
self.assertEqual(len(data), 2)
# still just 2 fields even if we request more
form.set_fields(['foo', 'bar', 'baz'])
form.set_fields(["foo", "bar", "baz"])
data = form.get_vue_model_data()
self.assertEqual(len(data), 2)
# confirm bool values make it thru as-is
schema.add(colander.SchemaNode(colander.Bool(), name='baz'))
form = self.make_form(schema=schema, model_instance={
'foo': 'one',
'bar': 'two',
'baz': True,
})
schema.add(colander.SchemaNode(colander.Bool(), name="baz"))
form = self.make_form(
schema=schema,
model_instance={
"foo": "one",
"bar": "two",
"baz": True,
},
)
data = form.get_vue_model_data()
self.assertEqual(list(data.values()), ['one', 'two', True])
self.assertEqual(list(data.values()), ["one", "two", True])
def test_has_global_errors(self):
@ -617,8 +644,8 @@ class TestForm(TestCase):
schema.validator = fail
form = self.make_form(schema=schema)
self.assertFalse(form.has_global_errors())
self.request.method = 'POST'
self.request.POST = {'foo': 'one', 'bar': 'two'}
self.request.method = "POST"
self.request.POST = {"foo": "one", "bar": "two"}
self.assertFalse(form.validate())
self.assertTrue(form.has_global_errors())
@ -631,8 +658,8 @@ class TestForm(TestCase):
schema.validator = fail
form = self.make_form(schema=schema)
self.assertEqual(form.get_global_errors(), [])
self.request.method = 'POST'
self.request.POST = {'foo': 'one', 'bar': 'two'}
self.request.method = "POST"
self.request.POST = {"foo": "one", "bar": "two"}
self.assertFalse(form.validate())
self.assertTrue(form.get_global_errors(), ["things are bad!"])
@ -641,55 +668,55 @@ class TestForm(TestCase):
# simple 'Required' validation failure
form = self.make_form(schema=schema)
self.request.method = 'POST'
self.request.POST = {'foo': 'one'}
self.request.method = "POST"
self.request.POST = {"foo": "one"}
self.assertFalse(form.validate())
errors = form.get_field_errors('bar')
self.assertEqual(errors, ['Required'])
errors = form.get_field_errors("bar")
self.assertEqual(errors, ["Required"])
# no errors
form = self.make_form(schema=schema)
self.request.POST = {'foo': 'one', 'bar': 'two'}
self.request.POST = {"foo": "one", "bar": "two"}
self.assertTrue(form.validate())
errors = form.get_field_errors('bar')
errors = form.get_field_errors("bar")
self.assertEqual(errors, [])
def test_validate(self):
schema = self.make_schema()
form = self.make_form(schema=schema)
self.assertFalse(hasattr(form, 'validated'))
self.assertFalse(hasattr(form, "validated"))
# will not validate unless request is POST
self.request.POST = {'foo': 'blarg', 'bar': 'baz'}
self.request.method = 'GET'
self.request.POST = {"foo": "blarg", "bar": "baz"}
self.request.method = "GET"
self.assertFalse(form.validate())
self.request.method = 'POST'
self.request.method = "POST"
data = form.validate()
self.assertEqual(data, {'foo': 'blarg', 'bar': 'baz'})
self.assertEqual(data, {"foo": "blarg", "bar": "baz"})
# validating a second time updates form.validated
self.request.POST = {'foo': 'BLARG', 'bar': 'BAZ'}
self.request.POST = {"foo": "BLARG", "bar": "BAZ"}
data = form.validate()
self.assertEqual(data, {'foo': 'BLARG', 'bar': 'BAZ'})
self.assertEqual(data, {"foo": "BLARG", "bar": "BAZ"})
self.assertIs(form.validated, data)
# bad data does not validate
self.request.POST = {'foo': 42, 'bar': None}
self.request.POST = {"foo": 42, "bar": None}
self.assertFalse(form.validate())
dform = form.get_deform()
self.assertEqual(len(dform.error.children), 2)
self.assertEqual(dform['foo'].errormsg, "Pstruct is not a string")
self.assertEqual(dform["foo"].errormsg, "Pstruct is not a string")
# when a form has readonly fields, validating it will *remove*
# those fields from deform/schema as well as final data dict
schema = self.make_schema()
form = self.make_form(schema=schema)
form.set_readonly('foo')
self.request.POST = {'foo': 'one', 'bar': 'two'}
form.set_readonly("foo")
self.request.POST = {"foo": "one", "bar": "two"}
data = form.validate()
self.assertEqual(data, {'bar': 'two'})
self.assertEqual(data, {"bar": "two"})
dform = form.get_deform()
self.assertNotIn('foo', schema)
self.assertNotIn('foo', dform)
self.assertIn('bar', schema)
self.assertIn('bar', dform)
self.assertNotIn("foo", schema)
self.assertNotIn("foo", dform)
self.assertIn("bar", schema)
self.assertIn("bar", dform)

View file

@ -25,17 +25,17 @@ class TestWuttaDateTime(TestCase):
result = typ.deserialize(node, colander.null)
self.assertIs(result, colander.null)
result = typ.deserialize(node, '2024-12-11T10:33 PM')
result = typ.deserialize(node, "2024-12-11T10:33 PM")
self.assertIsInstance(result, datetime.datetime)
self.assertEqual(result, datetime.datetime(2024, 12, 11, 22, 33))
self.assertIsNone(result.tzinfo)
result = typ.deserialize(node, '2024-12-11T22:33:00')
result = typ.deserialize(node, "2024-12-11T22:33:00")
self.assertIsInstance(result, datetime.datetime)
self.assertEqual(result, datetime.datetime(2024, 12, 11, 22, 33))
self.assertIsNone(result.tzinfo)
self.assertRaises(colander.Invalid, typ.deserialize, node, 'bogus')
self.assertRaises(colander.Invalid, typ.deserialize, node, "bogus")
class TestObjectNode(DataTestCase):
@ -84,20 +84,24 @@ class TestWuttaEnum(WebTestCase):
MOCK_STATUS_ONE = 1
MOCK_STATUS_TWO = 2
MOCK_STATUS = {
MOCK_STATUS_ONE: 'one',
MOCK_STATUS_TWO: 'two',
MOCK_STATUS_ONE: "one",
MOCK_STATUS_TWO: "two",
}
class TestWuttaDictEnum(WebTestCase):
def test_widget_maker(self):
typ = mod.WuttaDictEnum(self.request, MOCK_STATUS)
widget = typ.widget_maker()
self.assertIsInstance(widget, widgets.SelectWidget)
self.assertEqual(widget.values, [
(1, 'one'),
(2, 'two'),
])
self.assertEqual(
widget.values,
[
(1, "one"),
(2, "two"),
],
)
class TestWuttaMoney(WebTestCase):
@ -132,13 +136,13 @@ class TestWuttaQuantity(WebTestCase):
# quantity
result = typ.serialize(node, 42)
self.assertEqual(result, '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')
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')
self.assertEqual(result, "42.13")
class TestObjectRef(DataTestCase):
@ -155,19 +159,19 @@ class TestObjectRef(DataTestCase):
# passing true yields default empty option
typ = mod.ObjectRef(self.request, empty_option=True)
self.assertEqual(typ.empty_option, ('', "(none)"))
self.assertEqual(typ.empty_option, ("", "(none)"))
# can set explicitly
typ = mod.ObjectRef(self.request, empty_option=('foo', 'bar'))
self.assertEqual(typ.empty_option, ('foo', 'bar'))
typ = mod.ObjectRef(self.request, empty_option=("foo", "bar"))
self.assertEqual(typ.empty_option, ("foo", "bar"))
# can set just a label
typ = mod.ObjectRef(self.request, empty_option="(empty)")
self.assertEqual(typ.empty_option, ('', "(empty)"))
self.assertEqual(typ.empty_option, ("", "(empty)"))
def test_model_class(self):
typ = mod.ObjectRef(self.request)
self.assertRaises(NotImplementedError, getattr, typ, 'model_class')
self.assertRaises(NotImplementedError, getattr, typ, "model_class")
def test_serialize(self):
model = self.app.model
@ -188,9 +192,9 @@ class TestObjectRef(DataTestCase):
self.assertEqual(value, person.uuid.hex)
# null w/ empty option
typ = mod.ObjectRef(self.request, empty_option=('bad', 'BAD'))
typ = mod.ObjectRef(self.request, empty_option=("bad", "BAD"))
value = typ.serialize(node, colander.null)
self.assertEqual(value, 'bad')
self.assertEqual(value, "bad")
def test_deserialize(self):
model = self.app.model
@ -206,8 +210,8 @@ class TestObjectRef(DataTestCase):
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):
with patch.object(mod.ObjectRef, "model_class", new=model.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)
@ -234,14 +238,14 @@ class TestObjectRef(DataTestCase):
value = typ.objectify(None)
self.assertIsNone(value)
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod, "Session", return_value=self.session):
# 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.ObjectRef, "model_class", new=model.Person):
# can specify as uuid
typ = mod.ObjectRef(self.request)
@ -254,22 +258,22 @@ class TestObjectRef(DataTestCase):
self.assertIs(value, person)
# 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)
self.assertRaises(ValueError, typ.objectify, 'WRONG-UUID')
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):
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod.ObjectRef, "model_class", new=model.Person):
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):
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod.ObjectRef, "model_class", new=model.Person):
with patch.object(mod, "Session", return_value=self.session):
typ = mod.ObjectRef(self.request)
query = typ.get_query()
sorted_query = typ.sort_query(query)
@ -282,16 +286,16 @@ class TestObjectRef(DataTestCase):
self.session.commit()
# basic
with patch.object(mod.ObjectRef, 'model_class', new=model.Person):
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod.ObjectRef, "model_class", new=model.Person):
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):
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod.ObjectRef, "model_class", new=model.Person):
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)
@ -302,7 +306,7 @@ class TestObjectRef(DataTestCase):
class TestPersonRef(WebTestCase):
def test_sort_query(self):
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod, "Session", return_value=self.session):
typ = mod.PersonRef(self.request)
query = typ.get_query()
self.assertIsInstance(query, orm.Query)
@ -311,9 +315,9 @@ class TestPersonRef(WebTestCase):
self.assertIsNot(sorted_query, query)
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
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod, "Session", return_value=self.session):
typ = mod.PersonRef(self.request)
person = model.Person(full_name="Barney Rubble")
@ -322,13 +326,13 @@ class TestPersonRef(WebTestCase):
url = typ.get_object_url(person)
self.assertIsNotNone(url)
self.assertIn(f'/people/{person.uuid}', url)
self.assertIn(f"/people/{person.uuid}", url)
class TestRoleRef(WebTestCase):
def test_sort_query(self):
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod, "Session", return_value=self.session):
typ = mod.RoleRef(self.request)
query = typ.get_query()
self.assertIsInstance(query, orm.Query)
@ -337,24 +341,24 @@ class TestRoleRef(WebTestCase):
self.assertIsNot(sorted_query, query)
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
with patch.object(mod, 'Session', return_value=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.commit()
url = typ.get_object_url(role)
self.assertIsNotNone(url)
self.assertIn(f'/roles/{role.uuid}', url)
self.assertIn(f"/roles/{role.uuid}", url)
class TestUserRef(WebTestCase):
def test_sort_query(self):
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod, "Session", return_value=self.session):
typ = mod.UserRef(self.request)
query = typ.get_query()
self.assertIsInstance(query, orm.Query)
@ -363,18 +367,18 @@ class TestUserRef(WebTestCase):
self.assertIsNot(sorted_query, query)
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
with patch.object(mod, 'Session', return_value=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.commit()
url = typ.get_object_url(user)
self.assertIsNotNone(url)
self.assertIn(f'/users/{user.uuid}', url)
self.assertIn(f"/users/{user.uuid}", url)
class TestRoleRefs(DataTestCase):
@ -393,7 +397,7 @@ class TestRoleRefs(DataTestCase):
self.session.add(blokes)
self.session.commit()
with patch.object(mod, 'Session', return_value=self.session):
with patch.object(mod, "Session", return_value=self.session):
# with root access, default values include: admin, blokes
self.request.is_root = True
@ -427,11 +431,11 @@ class TestPermissions(DataTestCase):
# supported permissions are morphed to values
permissions = {
'widgets': {
'label': "Widgets",
'perms': {
'widgets.polish': {
'label': "Polish the widgets",
"widgets": {
"label": "Widgets",
"perms": {
"widgets.polish": {
"label": "Polish the widgets",
},
},
},
@ -439,7 +443,7 @@ class TestPermissions(DataTestCase):
typ = mod.Permissions(self.request, permissions)
widget = typ.widget_maker()
self.assertEqual(len(widget.values), 1)
self.assertEqual(widget.values[0], ('widgets.polish', "Polish the widgets"))
self.assertEqual(widget.values[0], ("widgets.polish", "Polish the widgets"))
class TestFileDownload(DataTestCase):
@ -451,10 +455,10 @@ class TestFileDownload(DataTestCase):
def test_widget_maker(self):
# sanity / coverage check
typ = mod.FileDownload(self.request, url='/foo')
typ = mod.FileDownload(self.request, url="/foo")
widget = typ.widget_maker()
self.assertIsInstance(widget, widgets.FileDownloadWidget)
self.assertEqual(widget.url, '/foo')
self.assertEqual(widget.url, "/foo")
class TestEmailRecipients(TestCase):
@ -464,14 +468,14 @@ class TestEmailRecipients(TestCase):
node = colander.SchemaNode(typ)
recips = [
'alice@example.com',
'bob@example.com',
"alice@example.com",
"bob@example.com",
]
recips_str = ', '.join(recips)
recips_str = ", ".join(recips)
# values
result = typ.serialize(node, recips_str)
self.assertEqual(result, '\n'.join(recips))
self.assertEqual(result, "\n".join(recips))
# null
result = typ.serialize(node, colander.null)
@ -482,10 +486,10 @@ class TestEmailRecipients(TestCase):
node = colander.SchemaNode(typ)
recips = [
'alice@example.com',
'bob@example.com',
"alice@example.com",
"bob@example.com",
]
recips_str = ', '.join(recips)
recips_str = ", ".join(recips)
# values
result = typ.deserialize(node, recips_str)

View file

@ -11,8 +11,14 @@ 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, Permissions,
WuttaDateTime, EmailRecipients)
from wuttaweb.forms.schema import (
FileDownload,
PersonRef,
RoleRefs,
Permissions,
WuttaDateTime,
EmailRecipients,
)
from wuttaweb.testing import WebTestCase
@ -21,7 +27,7 @@ class TestObjectRefWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def make_widget(self, **kwargs):
@ -33,14 +39,14 @@ class TestObjectRefWidget(WebTestCase):
self.session.add(person)
self.session.commit()
with patch.object(schema, 'Session', return_value=self.session):
with patch.object(schema, "Session", return_value=self.session):
# standard (editable)
node = colander.SchemaNode(PersonRef(self.request))
widget = self.make_widget()
field = self.make_field(node)
html = widget.serialize(field, person.uuid)
self.assertIn('<b-select ', html)
self.assertIn("<b-select ", html)
# readonly
node = colander.SchemaNode(PersonRef(self.request))
@ -48,17 +54,17 @@ class TestObjectRefWidget(WebTestCase):
widget = self.make_widget()
field = self.make_field(node)
html = widget.serialize(field, person.uuid, readonly=True)
self.assertIn('Betty Boop', html)
self.assertNotIn('<a', html)
self.assertIn("Betty Boop", html)
self.assertNotIn("<a", html)
# with hyperlink
node = colander.SchemaNode(PersonRef(self.request))
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)
html = widget.serialize(field, person.uuid, readonly=True)
self.assertIn('Betty Boop', html)
self.assertIn('<a', html)
self.assertIn("Betty Boop", html)
self.assertIn("<a", html)
self.assertIn('href="/foo"', html)
def test_get_template_values(self):
@ -67,24 +73,25 @@ class TestObjectRefWidget(WebTestCase):
self.session.add(person)
self.session.commit()
with patch.object(schema, 'Session', return_value=self.session):
with patch.object(schema, "Session", return_value=self.session):
# standard
node = colander.SchemaNode(PersonRef(self.request))
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)
self.assertIn("cstruct", 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')
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)
values = widget.get_template_values(field, "_empty_", {})
self.assertIn("cstruct", values)
self.assertNotIn("url", values)
class TestWuttaDateWidget(WebTestCase):
@ -92,7 +99,7 @@ class TestWuttaDateWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def make_widget(self, **kwargs):
@ -108,11 +115,11 @@ class TestWuttaDateWidget(WebTestCase):
# editable widget has normal picker html
result = widget.serialize(field, str(dt))
self.assertIn('<wutta-datepicker', result)
self.assertIn("<wutta-datepicker", result)
# readonly is rendered per app convention
result = widget.serialize(field, str(dt), readonly=True)
self.assertEqual(result, '2025-01-15')
self.assertEqual(result, "2025-01-15")
# now try again with datetime
widget = self.make_widget()
@ -120,11 +127,11 @@ class TestWuttaDateWidget(WebTestCase):
# editable widget has normal picker html
result = widget.serialize(field, str(dt))
self.assertIn('<wutta-datepicker', result)
self.assertIn("<wutta-datepicker", result)
# readonly is rendered per app convention
result = widget.serialize(field, str(dt), readonly=True)
self.assertEqual(result, '2025-01-15')
self.assertEqual(result, "2025-01-15")
class TestWuttaDateTimeWidget(WebTestCase):
@ -132,7 +139,7 @@ class TestWuttaDateTimeWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def make_widget(self, **kwargs):
@ -146,11 +153,11 @@ class TestWuttaDateTimeWidget(WebTestCase):
# editable widget has normal picker html
result = widget.serialize(field, str(dt))
self.assertIn('<wutta-datepicker', result)
self.assertIn("<wutta-datepicker", result)
# readonly is rendered per app convention
result = widget.serialize(field, str(dt), readonly=True)
self.assertEqual(result, '2024-12-12 13:49+0000')
self.assertEqual(result, "2024-12-12 13:49+0000")
class TestWuttaMoneyInputWidget(WebTestCase):
@ -158,7 +165,7 @@ class TestWuttaMoneyInputWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def make_widget(self, **kwargs):
@ -168,19 +175,19 @@ class TestWuttaMoneyInputWidget(WebTestCase):
node = colander.SchemaNode(schema.WuttaMoney(self.request))
field = self.make_field(node)
widget = self.make_widget()
amount = decimal.Decimal('12.34')
amount = decimal.Decimal("12.34")
# editable widget has normal text input
result = widget.serialize(field, str(amount))
self.assertIn('<b-input', result)
self.assertIn("<b-input", result)
# readonly is rendered per app convention
result = widget.serialize(field, str(amount), readonly=True)
self.assertEqual(result, '<span>$12.34</span>')
self.assertEqual(result, "<span>$12.34</span>")
# readonly w/ null value
result = widget.serialize(field, None, readonly=True)
self.assertEqual(result, '<span></span>')
self.assertEqual(result, "<span></span>")
class TestFileDownloadWidget(WebTestCase):
@ -188,7 +195,7 @@ class TestFileDownloadWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def test_serialize(self):
@ -201,31 +208,31 @@ class TestFileDownloadWidget(WebTestCase):
# null value
html = widget.serialize(field, None, readonly=True)
self.assertNotIn('<a ', html)
self.assertIn('<span>', html)
self.assertNotIn("<a ", html)
self.assertIn("<span>", html)
# path to nonexistent file
html = widget.serialize(field, '/this/path/does/not/exist', readonly=True)
self.assertNotIn('<a ', html)
self.assertIn('<span>', html)
html = widget.serialize(field, "/this/path/does/not/exist", readonly=True)
self.assertNotIn("<a ", html)
self.assertIn("<span>", html)
# path to actual file
datfile = self.write_file('data.txt', "hello\n" * 1000)
datfile = self.write_file("data.txt", "hello\n" * 1000)
html = widget.serialize(field, datfile, readonly=True)
self.assertNotIn('<a ', html)
self.assertIn('<span>', html)
self.assertIn('data.txt', html)
self.assertIn('kB)', html)
self.assertNotIn("<a ", html)
self.assertIn("<span>", html)
self.assertIn("data.txt", html)
self.assertIn("kB)", html)
# path to file, w/ url
node = colander.SchemaNode(FileDownload(self.request, url='/download/blarg'))
node = colander.SchemaNode(FileDownload(self.request, url="/download/blarg"))
field = self.make_field(node)
widget = field.widget
html = widget.serialize(field, datfile, readonly=True)
self.assertNotIn('<span>', html)
self.assertNotIn("<span>", html)
self.assertIn('<a href="/download/blarg">', html)
self.assertIn('data.txt', html)
self.assertIn('kB)', html)
self.assertIn("data.txt", html)
self.assertIn("kB)", html)
# nb. same readonly output even if we ask for editable
html2 = widget.serialize(field, datfile, readonly=False)
@ -237,13 +244,15 @@ class TestGridWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def test_serialize(self):
grid = grids.Grid(self.request,
columns=['foo', 'bar'],
data=[{'foo': 1, 'bar': 2}, {'foo': 3, 'bar': 4}])
grid = grids.Grid(
self.request,
columns=["foo", "bar"],
data=[{"foo": 1, "bar": 2}, {"foo": 3, "bar": 4}],
)
node = colander.SchemaNode(colander.String())
widget = mod.GridWidget(self.request, grid)
@ -251,7 +260,7 @@ class TestGridWidget(WebTestCase):
# readonly works okay
html = widget.serialize(field, None, readonly=True)
self.assertIn('<b-table ', html)
self.assertIn("<b-table ", html)
# but otherwise, error
self.assertRaises(NotImplementedError, widget.serialize, field, None)
@ -262,11 +271,11 @@ class TestRoleRefsWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def test_serialize(self):
self.pyramid_config.add_route('roles.view', '/roles/{uuid}')
self.pyramid_config.add_route("roles.view", "/roles/{uuid}")
model = self.app.model
auth = self.app.get_auth_handler()
admin = auth.get_role_administrator(self.session)
@ -275,7 +284,7 @@ class TestRoleRefsWidget(WebTestCase):
self.session.commit()
# nb. we let the field construct the widget via our type
with patch.object(schema, 'Session', return_value=self.session):
with patch.object(schema, "Session", return_value=self.session):
node = colander.SchemaNode(RoleRefs(self.request))
field = self.make_field(node)
widget = field.widget
@ -305,16 +314,16 @@ class TestPermissionsWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def test_serialize(self):
permissions = {
'widgets': {
'label': "Widgets",
'perms': {
'widgets.polish': {
'label': "Polish the widgets",
"widgets": {
"label": "Widgets",
"perms": {
"widgets.polish": {
"label": "Polish the widgets",
},
},
},
@ -330,7 +339,7 @@ class TestPermissionsWidget(WebTestCase):
self.assertNotIn("Polish the widgets", html)
# readonly output includes the perm if set
html = widget.serialize(field, {'widgets.polish'}, readonly=True)
html = widget.serialize(field, {"widgets.polish"}, readonly=True)
self.assertIn("Polish the widgets", html)
# editable output always includes the perm
@ -343,7 +352,7 @@ class TestEmailRecipientsWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def test_serialize(self):
@ -352,19 +361,19 @@ class TestEmailRecipientsWidget(WebTestCase):
widget = mod.EmailRecipientsWidget()
recips = [
'alice@example.com',
'bob@example.com',
"alice@example.com",
"bob@example.com",
]
recips_str = ', '.join(recips)
recips_str = ", ".join(recips)
# readonly
result = widget.serialize(field, recips_str, readonly=True)
self.assertIn('<ul>', result)
self.assertIn('<li>alice@example.com</li>', result)
self.assertIn("<ul>", result)
self.assertIn("<li>alice@example.com</li>", result)
# editable
result = widget.serialize(field, recips_str)
self.assertIn('<b-input', result)
self.assertIn("<b-input", result)
self.assertIn('type="textarea"', result)
def test_deserialize(self):
@ -373,10 +382,10 @@ class TestEmailRecipientsWidget(WebTestCase):
widget = mod.EmailRecipientsWidget()
recips = [
'alice@example.com',
'bob@example.com',
"alice@example.com",
"bob@example.com",
]
recips_str = ', '.join(recips)
recips_str = ", ".join(recips)
# values
result = widget.deserialize(field, recips_str)
@ -392,7 +401,7 @@ class TestBatchIdWidget(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)
kwargs.setdefault("renderer", deform.Form.default_renderer)
return deform.Field(node, **kwargs)
def test_serialize(self):
@ -404,4 +413,4 @@ class TestBatchIdWidget(WebTestCase):
self.assertIs(result, colander.null)
result = widget.serialize(field, 42)
self.assertEqual(result, '00000042')
self.assertEqual(result, "00000042")