From 1137ecc6c0b06c639f4a07dc96ded30f45ccba01 Mon Sep 17 00:00:00 2001 From: "Karl O. Pinc" Date: Tue, 1 Dec 2020 21:22:57 -0600 Subject: [PATCH] Move acting on pgwui.routes setting from PGWUI_Server --- README.rst | 16 +++++++- src/pgwui_common/exceptions.py | 13 ++++++ src/pgwui_common/routes.py | 45 ++++++++++++++++++++ tests/test_routes.py | 75 ++++++++++++++++++++++++++++++++++ 4 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 src/pgwui_common/routes.py create mode 100644 tests/test_routes.py diff --git a/README.rst b/README.rst index 03b2406..eff18f6 100644 --- a/README.rst +++ b/README.rst @@ -29,8 +29,8 @@ Short Documentation PGWUI_Common stands for `PostgreSQL`_ Web User Interface, Common files. -Shared files used by the web interfaces which are a part of the PGWUI -package suite. +Shared files and functionality used by the web interfaces which are a +part of the PGWUI package suite. The PGWUI package suite is a Python framework for creating `PostgreSQL`_ web user interfaces, and a collection of user interfaces @@ -46,6 +46,9 @@ PGWUI_Common provides: database and credentials. These forms are rendered using `Pyramid`_ views. + * Code used to establish `routes`_, called by PGWUI_Server + or whatever else is used to configure `Pyramid`_. + The official PGWUI components based on PGWUI_Common are highly configurable. The web page templates used to generate HTML files, the CSS files, the static HTML files, and the location of the web pages @@ -137,6 +140,14 @@ Override API. See: `_ +Establishing Routes +^^^^^^^^^^^^^^^^^^^ + +To establish `Pyramid`_ `routes`_ to the installed PGWUI components, +after all components are configured, `pgwui_common.routes.add_routes()` +must be called. + + Development Status ------------------ @@ -177,3 +188,4 @@ provided by `The Dian Fossey Gorilla Fund .. _PostgreSQL: https://www.postgresql.org/ .. _Pyramid: https://trypyramid.com/ .. _Pyramid's: `Pyramid`_ +.. _routes: https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/urldispatch.html diff --git a/src/pgwui_common/exceptions.py b/src/pgwui_common/exceptions.py index 02122f0..b91e9c9 100644 --- a/src/pgwui_common/exceptions.py +++ b/src/pgwui_common/exceptions.py @@ -32,6 +32,19 @@ class Error(core_ex.PGWUIError): pass +class Info(core_ex.PGWUIError): + '''Informational exceptions + ''' + pass + + +class MenuPageInRoutes(Info): + def __init__(self): + super().__init__( + 'The pgwui_menu in the pgwui.routes setting is ignored ' + 'and the pgwui.menu_page setting used instead') + + class UnknownSettingKeyError(Error): def __init__(self, key): super().__init__('Unknown PGWUI setting: {}'.format(key)) diff --git a/src/pgwui_common/routes.py b/src/pgwui_common/routes.py new file mode 100644 index 0000000..f9db695 --- /dev/null +++ b/src/pgwui_common/routes.py @@ -0,0 +1,45 @@ +# Copyright (C) 2018, 2020 The Meme Factory, Inc. http://www.karlpinc.com/ + +# This file is part of PGWUI_Common. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# This program 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 +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with this program. If not, see +# . +# + +# Karl O. Pinc + +'''Configure routing +''' + +import logging +import pgwui_common.exceptions as ex + +log = logging.getLogger(__name__) + + +def add_routes(config, settings): + '''Add routes found in pgwui.routes setting + + Because settings established with Pyramid's Configurator.include() + can be overridden by the caller, whatever configures PGWUI should + call add_routes() after configuring all PGWUI components. + ''' + pgwui_settings = settings['pgwui'] + if 'routes' in pgwui_settings: + have_menu_page = 'menu_page' in pgwui_settings + for name, route in pgwui_settings['routes'].items(): + if have_menu_page and name == 'pgwui_menu': + log.info(ex.MenuPageInRoutes()) + else: + config.add_route(name, route) diff --git a/tests/test_routes.py b/tests/test_routes.py new file mode 100644 index 0000000..d652688 --- /dev/null +++ b/tests/test_routes.py @@ -0,0 +1,75 @@ +# Copyright (C) 2018, 2019, 2020 The Meme Factory, Inc. +# http://www.karlpinc.com/ + +# This file is part of PGWUI_Common. +# +# This program is free software: you can redistribute it and/or +# modify it under the terms of the GNU Affero General Public License +# as published by the Free Software Foundation, either version 3 of +# the License, or (at your option) any later version. +# +# This program 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 +# Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public +# License along with this program. If not, see +# . +# + +# Karl O. Pinc + +import pytest +from pgwui_testing import testing + +import logging +import pyramid.testing +import pgwui_common.routes as routes + +mock_add_route = testing.instance_method_mock_fixture('add_route') + + +# add_routes() + +@pytest.mark.unittest +def test_add_routes_empty(mock_add_route): + '''When there is no pgwui.routes setting nothing gets added''' + with pyramid.testing.testConfig() as config: + mocked_add_route = mock_add_route(config) + routes.add_routes(config, {'pgwui': {}}) + + assert not mocked_add_route.called + + +@pytest.mark.unittest +def test_add_routes_notempty(mock_add_route): + '''When there is a pgwui.routes setting config.add_route() is called + for each route''' + test_routes = {'name1': 'route1', + 'name2': 'route2'} + with pyramid.testing.testConfig() as config: + mocked_add_route = mock_add_route(config) + routes.add_routes(config, {'pgwui': {'routes': test_routes}}) + + assert mocked_add_route.call_count == len(test_routes) + + +@pytest.mark.unittest +def test_add_routes_menu(mock_add_route, caplog): + '''When there is a a route for pgwui_menu, but there is a menu_page + setting, no route is added and an INFO message is logged + ''' + caplog.set_level(logging.DEBUG) + + test_routes = {'pgwui_menu': None, 'notused': None} + with pyramid.testing.testConfig() as config: + mocked_add_route = mock_add_route(config) + routes.add_routes(config, {'pgwui': {'routes': test_routes, + 'menu_page': 'anything'}}) + + mocked_add_route.assert_called_once() + + logs = caplog.record_tuples + assert len(logs) == 1 + assert logs[0][1] == logging.INFO -- 2.34.1