From dd176a5e9e43752ef87e16440e74f45ce303f1f3 Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Thu, 15 Aug 2024 16:05:53 -0500 Subject: [PATCH] feat: add first wutta-based master, for PersonView still opt-in-only at this point, the traditional tailbone-native master is used by default. new wutta master is not feature complete yet. but at least things seem to render and form posts work okay.. when enabled, this uses a "completely" wutta-based stack for the view, grid and forms. but the underlying DB is of course rattail, and the templates are still traditional/tailbone. --- tailbone/views/people.py | 6 +- tailbone/views/wutta/__init__.py | 0 tailbone/views/wutta/people.py | 102 +++++++++++++++++++++++++++++++ tests/util.py | 2 + tests/views/test_people.py | 17 ++++++ tests/views/wutta/__init__.py | 0 tests/views/wutta/test_people.py | 47 ++++++++++++++ 7 files changed, 173 insertions(+), 1 deletion(-) create mode 100644 tailbone/views/wutta/__init__.py create mode 100644 tailbone/views/wutta/people.py create mode 100644 tests/views/test_people.py create mode 100644 tests/views/wutta/__init__.py create mode 100644 tests/views/wutta/test_people.py diff --git a/tailbone/views/people.py b/tailbone/views/people.py index 9b28b94d..94c85821 100644 --- a/tailbone/views/people.py +++ b/tailbone/views/people.py @@ -2187,4 +2187,8 @@ def defaults(config, **kwargs): def includeme(config): - defaults(config) + wutta_config = config.registry.settings['wutta_config'] + if wutta_config.get_bool('tailbone.use_wutta_views', default=False, usedb=False): + config.include('tailbone.views.wutta.people') + else: + defaults(config) diff --git a/tailbone/views/wutta/__init__.py b/tailbone/views/wutta/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tailbone/views/wutta/people.py b/tailbone/views/wutta/people.py new file mode 100644 index 00000000..44cc26d9 --- /dev/null +++ b/tailbone/views/wutta/people.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8; -*- +################################################################################ +# +# Rattail -- Retail Software Framework +# Copyright © 2010-2024 Lance Edgar +# +# This file is part of Rattail. +# +# Rattail is free software: you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation, either version 3 of the License, or (at your option) any later +# version. +# +# Rattail is distributed in the hope that it will be useful, but WITHOUT ANY +# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more +# details. +# +# You should have received a copy of the GNU General Public License along with +# Rattail. If not, see . +# +################################################################################ +""" +Person Views +""" + +from rattail.db.model import Person + +from wuttaweb.views import people as wutta +from tailbone.views import people as tailbone +from tailbone.db import Session + + +class PersonView(wutta.PersonView): + """ + This is the first attempt at blending newer Wutta views with + legacy Tailbone config. + + So, this is a Wutta-based view but it should be included by a + Tailbone app configurator. + """ + model_class = Person + Session = Session + + # labels = { + # 'display_name': "Full Name", + # } + + grid_columns = [ + 'display_name', + 'first_name', + 'last_name', + 'phone', + 'email', + 'merge_requested', + ] + + form_fields = [ + 'first_name', + 'middle_name', + 'last_name', + 'display_name', + 'default_phone', + 'default_email', + # 'address', + # 'employee', + 'customers', + # 'members', + 'users', + ] + + def get_query(self, session=None): + """ """ + model = self.app.model + session = session or self.Session() + return session.query(model.Person)\ + .order_by(model.Person.display_name) + + def configure_form(self, f): + """ """ + super().configure_form(f) + + # default_phone + f.set_required('default_phone', False) + + # default_email + f.set_required('default_email', False) + + # customers + if self.creating or self.editing: + f.remove('customers') + + +def defaults(config, **kwargs): + base = globals() + + kwargs.setdefault('PersonView', base['PersonView']) + tailbone.defaults(config, **kwargs) + + +def includeme(config): + defaults(config) diff --git a/tests/util.py b/tests/util.py index 98d89ce0..3aa04f5e 100644 --- a/tests/util.py +++ b/tests/util.py @@ -43,6 +43,8 @@ class WebTestCase(DataTestCase): 'tailbone.app.add_index_page') self.pyramid_config.add_directive('add_tailbone_model_view', 'tailbone.app.add_model_view') + self.pyramid_config.add_directive('add_tailbone_config_page', + 'tailbone.app.add_config_page') self.pyramid_config.add_subscriber('tailbone.subscribers.before_render', 'pyramid.events.BeforeRender') self.pyramid_config.include('tailbone.static') diff --git a/tests/views/test_people.py b/tests/views/test_people.py new file mode 100644 index 00000000..f85577e7 --- /dev/null +++ b/tests/views/test_people.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8; -*- + +from tailbone.views import users as mod +from tests.util import WebTestCase + + +class TestPersonView(WebTestCase): + + def make_view(self): + return mod.PersonView(self.request) + + def test_includeme(self): + self.pyramid_config.include('tailbone.views.people') + + def test_includeme_wutta(self): + self.config.setdefault('tailbone.use_wutta_views', 'true') + self.pyramid_config.include('tailbone.views.people') diff --git a/tests/views/wutta/__init__.py b/tests/views/wutta/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/tests/views/wutta/test_people.py b/tests/views/wutta/test_people.py new file mode 100644 index 00000000..7795d641 --- /dev/null +++ b/tests/views/wutta/test_people.py @@ -0,0 +1,47 @@ +# -*- coding: utf-8; -*- + +from unittest.mock import patch + +from sqlalchemy import orm + +from tailbone.views.wutta import people as mod +from tests.util import WebTestCase + + +class TestPersonView(WebTestCase): + + def make_view(self): + return mod.PersonView(self.request) + + def test_includeme(self): + self.pyramid_config.include('tailbone.views.wutta.people') + + def test_get_query(self): + view = self.make_view() + + # sanity / coverage check + query = view.get_query(session=self.session) + self.assertIsInstance(query, orm.Query) + + def test_configure_form(self): + model = self.app.model + barney = model.User(username='barney') + self.session.add(barney) + self.session.commit() + view = self.make_view() + + # customers field remains when viewing + with patch.object(view, 'viewing', new=True): + form = view.make_form(model_instance=barney, + fields=view.get_form_fields()) + self.assertIn('customers', form.fields) + view.configure_form(form) + self.assertIn('customers', form) + + # customers field removed when editing + with patch.object(view, 'editing', new=True): + form = view.make_form(model_instance=barney, + fields=view.get_form_fields()) + self.assertIn('customers', form.fields) + view.configure_form(form) + self.assertNotIn('customers', form)