feat: add basic support for SQLAlchemy model in master view
must more to be done for this yet, but basics are in place for the Setting view
This commit is contained in:
parent
73014964cb
commit
fc01fa283a
10 changed files with 506 additions and 260 deletions
|
@ -49,6 +49,7 @@ class TestForm(TestCase):
|
|||
self.config = WuttaConfig(defaults={
|
||||
'wutta.web.menus.handler_spec': 'tests.utils: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={
|
||||
|
@ -115,6 +116,7 @@ class TestForm(TestCase):
|
|||
self.assertEqual(form.fields, ['baz'])
|
||||
|
||||
def test_get_schema(self):
|
||||
model = self.app.model
|
||||
form = self.make_form()
|
||||
self.assertIsNone(form.schema)
|
||||
|
||||
|
@ -135,6 +137,24 @@ class TestForm(TestCase):
|
|||
self.assertIsNone(form.schema)
|
||||
self.assertRaises(NotImplementedError, form.get_schema)
|
||||
|
||||
# schema is auto-generated if model_class provided
|
||||
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)
|
||||
|
||||
# schema is auto-generated if model_instance provided
|
||||
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)
|
||||
|
||||
# schema nodes are required by default
|
||||
form = self.make_form(fields=['foo', 'bar'])
|
||||
schema = form.get_schema()
|
||||
|
@ -149,6 +169,7 @@ class TestForm(TestCase):
|
|||
self.assertIsNone(schema['bar'].missing)
|
||||
|
||||
def test_get_deform(self):
|
||||
model = self.app.model
|
||||
schema = self.make_schema()
|
||||
|
||||
# basic
|
||||
|
@ -158,12 +179,24 @@ class TestForm(TestCase):
|
|||
self.assertIsInstance(dform, deform.Form)
|
||||
self.assertIs(form.deform_form, dform)
|
||||
|
||||
# with model instance / cstruct
|
||||
# with model instance as dict
|
||||
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')
|
||||
form = self.make_form(model_instance=myobj)
|
||||
dform = form.get_deform()
|
||||
self.assertEqual(dform.cstruct, {'name': 'foo', 'value': 'bar'})
|
||||
|
||||
# sqlalchemy instance with null value
|
||||
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})
|
||||
|
||||
def test_get_cancel_url(self):
|
||||
|
||||
# is referrer by default
|
||||
|
|
|
@ -16,6 +16,7 @@ class TestGrid(TestCase):
|
|||
self.config = WuttaConfig(defaults={
|
||||
'wutta.web.menus.handler_spec': 'tests.utils:NullMenuHandler',
|
||||
})
|
||||
self.app = self.config.get_app()
|
||||
|
||||
self.request = testing.DummyRequest(wutta_config=self.config, use_oruga=False)
|
||||
|
||||
|
@ -50,6 +51,24 @@ class TestGrid(TestCase):
|
|||
grid = self.make_grid()
|
||||
self.assertEqual(grid.vue_component, 'WuttaGrid')
|
||||
|
||||
def test_get_columns(self):
|
||||
model = self.app.model
|
||||
|
||||
# empty
|
||||
grid = self.make_grid()
|
||||
self.assertIsNone(grid.columns)
|
||||
self.assertIsNone(grid.get_columns())
|
||||
|
||||
# explicit
|
||||
grid = self.make_grid(columns=['foo', 'bar'])
|
||||
self.assertEqual(grid.columns, ['foo', 'bar'])
|
||||
self.assertEqual(grid.get_columns(), ['foo', 'bar'])
|
||||
|
||||
# derived from model
|
||||
grid = self.make_grid(model_class=model.Setting)
|
||||
self.assertEqual(grid.columns, ['name', 'value'])
|
||||
self.assertEqual(grid.get_columns(), ['name', 'value'])
|
||||
|
||||
def test_linked_columns(self):
|
||||
grid = self.make_grid(columns=['foo', 'bar'])
|
||||
self.assertEqual(grid.linked_columns, [])
|
||||
|
|
|
@ -403,6 +403,18 @@ class TestGetFormData(TestCase):
|
|||
self.assertEqual(data, {'foo2': 'baz'})
|
||||
|
||||
|
||||
class TestGetModelFields(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.config = WuttaConfig()
|
||||
self.app = self.config.get_app()
|
||||
|
||||
def test_basic(self):
|
||||
model = self.app.model
|
||||
fields = util.get_model_fields(self.config, model.Setting)
|
||||
self.assertEqual(fields, ['name', 'value'])
|
||||
|
||||
|
||||
class TestGetCsrfToken(TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
|
|
@ -6,7 +6,7 @@ from unittest.mock import MagicMock, patch
|
|||
|
||||
from pyramid import testing
|
||||
from pyramid.response import Response
|
||||
from pyramid.httpexceptions import HTTPFound
|
||||
from pyramid.httpexceptions import HTTPFound, HTTPNotFound
|
||||
|
||||
from wuttjamaican.conf import WuttaConfig
|
||||
from wuttaweb.views import master
|
||||
|
@ -348,10 +348,120 @@ class TestMasterView(WebTestCase):
|
|||
self.assertEqual(view.get_index_title(), "Wutta Widgets")
|
||||
del master.MasterView.model_title_plural
|
||||
|
||||
def test_make_model_grid(self):
|
||||
model = self.app.model
|
||||
|
||||
# no model class
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_name='Widget',
|
||||
model_key='uuid'):
|
||||
view = master.MasterView(self.request)
|
||||
grid = view.make_model_grid()
|
||||
self.assertIsNone(grid.model_class)
|
||||
|
||||
# explicit model class
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
grid = view.make_model_grid(session=self.session)
|
||||
self.assertIs(grid.model_class, model.Setting)
|
||||
|
||||
def test_get_instance(self):
|
||||
model = self.app.model
|
||||
self.app.save_setting(self.session, 'foo', 'bar')
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 1)
|
||||
|
||||
# default not implemented
|
||||
view = master.MasterView(self.request)
|
||||
self.assertRaises(NotImplementedError, view.get_instance)
|
||||
|
||||
# fetch from DB if model class is known
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
view = master.MasterView(self.request)
|
||||
|
||||
# existing setting is returned
|
||||
self.request.matchdict = {'name': 'foo'}
|
||||
setting = view.get_instance(session=self.session)
|
||||
self.assertIsInstance(setting, model.Setting)
|
||||
self.assertEqual(setting.name, 'foo')
|
||||
self.assertEqual(setting.value, 'bar')
|
||||
|
||||
# missing setting not found
|
||||
self.request.matchdict = {'name': 'blarg'}
|
||||
self.assertRaises(HTTPNotFound, view.get_instance, session=self.session)
|
||||
|
||||
def test_make_model_form(self):
|
||||
model = self.app.model
|
||||
|
||||
# no model class
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_name='Widget',
|
||||
model_key='uuid'):
|
||||
view = master.MasterView(self.request)
|
||||
form = view.make_model_form()
|
||||
self.assertIsNone(form.model_class)
|
||||
|
||||
# explicit model class
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
form = view.make_model_form()
|
||||
self.assertIs(form.model_class, model.Setting)
|
||||
|
||||
def test_objectify(self):
|
||||
model = self.app.model
|
||||
self.app.save_setting(self.session, 'foo', 'bar')
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 1)
|
||||
|
||||
# no model class
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_name='Widget',
|
||||
model_key='uuid'):
|
||||
view = master.MasterView(self.request)
|
||||
form = view.make_model_form()
|
||||
form.validated = {'name': 'first'}
|
||||
obj = view.objectify(form)
|
||||
self.assertIs(obj, form.validated)
|
||||
|
||||
# explicit model class (editing)
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting,
|
||||
editing=True):
|
||||
form = view.make_model_form()
|
||||
form.validated = {'name': 'foo', 'value': 'blarg'}
|
||||
form.model_instance = self.session.query(model.Setting).one()
|
||||
obj = view.objectify(form)
|
||||
self.assertIsInstance(obj, model.Setting)
|
||||
self.assertEqual(obj.name, 'foo')
|
||||
self.assertEqual(obj.value, 'blarg')
|
||||
|
||||
# explicit model class (creating)
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting,
|
||||
creating=True):
|
||||
form = view.make_model_form()
|
||||
form.validated = {'name': 'another', 'value': 'whatever'}
|
||||
obj = view.objectify(form)
|
||||
self.assertIsInstance(obj, model.Setting)
|
||||
self.assertEqual(obj.name, 'another')
|
||||
self.assertEqual(obj.value, 'whatever')
|
||||
|
||||
def test_persist(self):
|
||||
model = self.app.model
|
||||
with patch.multiple(master.MasterView, create=True,
|
||||
model_class=model.Setting):
|
||||
view = master.MasterView(self.request)
|
||||
|
||||
# new instance is persisted
|
||||
setting = model.Setting(name='foo', value='bar')
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 0)
|
||||
view.persist(setting, session=self.session)
|
||||
self.session.commit()
|
||||
setting = self.session.query(model.Setting).one()
|
||||
self.assertEqual(setting.name, 'foo')
|
||||
self.assertEqual(setting.value, 'bar')
|
||||
|
||||
##############################
|
||||
# view methods
|
||||
##############################
|
||||
|
@ -366,7 +476,7 @@ class TestMasterView(WebTestCase):
|
|||
response = view.index()
|
||||
# then again with data, to include view action url
|
||||
data = [{'name': 'foo', 'value': 'bar'}]
|
||||
with patch.object(view, 'index_get_grid_data', return_value=data):
|
||||
with patch.object(view, 'get_grid_data', return_value=data):
|
||||
response = view.index()
|
||||
del master.MasterView.model_name
|
||||
del master.MasterView.model_key
|
||||
|
@ -544,7 +654,9 @@ class TestMasterView(WebTestCase):
|
|||
model_class=model.Setting,
|
||||
form_fields=['name', 'value']):
|
||||
view = master.MasterView(self.request)
|
||||
self.assertRaises(NotImplementedError, view.delete_instance, setting)
|
||||
view.delete_instance(setting)
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 0)
|
||||
|
||||
def test_configure(self):
|
||||
model = self.app.model
|
||||
|
|
|
@ -35,39 +35,19 @@ class TestSettingView(WebTestCase):
|
|||
def make_view(self):
|
||||
return settings.SettingView(self.request)
|
||||
|
||||
def test_index_get_grid_data(self):
|
||||
def test_get_grid_data(self):
|
||||
|
||||
# empty data by default
|
||||
view = self.make_view()
|
||||
data = view.index_get_grid_data(session=self.session)
|
||||
data = view.get_grid_data(session=self.session)
|
||||
self.assertEqual(len(data), 0)
|
||||
|
||||
# unless we save some settings
|
||||
self.app.save_setting(self.session, 'foo', 'bar')
|
||||
self.session.commit()
|
||||
data = view.index_get_grid_data(session=self.session)
|
||||
data = view.get_grid_data(session=self.session)
|
||||
self.assertEqual(len(data), 1)
|
||||
|
||||
def test_get_instance(self):
|
||||
view = self.make_view()
|
||||
self.request.matchdict = {'name': 'foo'}
|
||||
|
||||
# setting not found
|
||||
setting = view.get_instance(session=self.session)
|
||||
self.assertIsInstance(setting, HTTPNotFound)
|
||||
|
||||
# setting is returned
|
||||
self.app.save_setting(self.session, 'foo', 'bar')
|
||||
self.session.commit()
|
||||
setting = view.get_instance(session=self.session)
|
||||
self.assertEqual(setting, {'name': 'foo', 'value': 'bar'})
|
||||
|
||||
def test_get_instance_title(self):
|
||||
setting = {'name': 'foo', 'value': 'bar'}
|
||||
view = self.make_view()
|
||||
title = view.get_instance_title(setting)
|
||||
self.assertEqual(title, 'foo')
|
||||
|
||||
def test_configure_form(self):
|
||||
view = self.make_view()
|
||||
form = view.make_form(fields=view.get_form_fields())
|
||||
|
@ -75,42 +55,3 @@ class TestSettingView(WebTestCase):
|
|||
view.configure_form(form)
|
||||
self.assertIn('value', form.required_fields)
|
||||
self.assertFalse(form.required_fields['value'])
|
||||
|
||||
def test_persist(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
# setup
|
||||
self.app.save_setting(self.session, 'foo', 'bar')
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 1)
|
||||
|
||||
# setting is updated
|
||||
self.request.matchdict = {'name': 'foo'}
|
||||
view.persist({'name': 'foo', 'value': 'frazzle'}, session=self.session)
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 1)
|
||||
self.assertEqual(self.app.get_setting(self.session, 'foo'), 'frazzle')
|
||||
|
||||
# new setting is created
|
||||
self.request.matchdict = {}
|
||||
with patch.object(view, 'creating', new=True):
|
||||
view.persist({'name': 'foo', 'value': 'frazzle'}, session=self.session)
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 1)
|
||||
self.assertEqual(self.app.get_setting(self.session, 'foo'), 'frazzle')
|
||||
|
||||
def test_delete_instance(self):
|
||||
model = self.app.model
|
||||
view = self.make_view()
|
||||
|
||||
# setup
|
||||
self.app.save_setting(self.session, 'foo', 'bar')
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 1)
|
||||
|
||||
# setting is deleted
|
||||
self.request.matchdict = {'name': 'foo'}
|
||||
view.delete_instance({'name': 'foo', 'value': 'frazzle'}, session=self.session)
|
||||
self.session.commit()
|
||||
self.assertEqual(self.session.query(model.Setting).count(), 0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue