Skip to content

Commit

Permalink
- More tests for PluginManager edge cases.
Browse files Browse the repository at this point in the history
- Documentation improvements.
  • Loading branch information
alexdlaird committed Sep 20, 2020
1 parent 2eeeeb1 commit d703d56
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 22 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
- Console output colors are now configurable.
- Improved formatting for enabled/available plugin listing from CLI.
- Support for `description` for a Plugin.
- More tests for `PluginManager` edge cases.
- Documentation improvements.

### Changed
- Removed "Beta" label in PyPI classifiers.
Expand Down
8 changes: 6 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,17 @@ From now on, these args are no longer necessary when starting ``hookee``:
Customizing the Response
========================

If we don't want to bother with building our own plugins and just want to quickly customize the response from
``/webhook``, the ``--response`` arg is here for us.
If we don't want to bother with building our own plugins, the response from ``/webhook`` and be customized right from
the command line with the ``--response`` arg.

.. code-block:: sh
hookee --response "<Response>Ok</Response>" --content-type application/xml
This approach can be particularly useful in tutorials where we want to quickly allow a developer to see and interact
with webhooks from our service before they've done any actual integration with our service themselves—all they would
have to do is copy and paste a simple ``hookee`` command like the one shown above.

As with any config, if we find ourselves continually passing this response to ``hookee`` every time we run it, we can
make it the default:

Expand Down
2 changes: 1 addition & 1 deletion tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

__author__ = "Alex Laird"
__copyright__ = "Copyright 2020, Alex Laird"
__version__ = "1.2.0"
__version__ = "1.2.2"


class TestCli(HookeeTestCase):
Expand Down
79 changes: 60 additions & 19 deletions tests/test_plugin_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from types import ModuleType

from flask import Response
from hookee.exception import HookeePluginValidationError

from hookee.pluginmanager import PluginManager, Plugin, VALID_PLUGIN_TYPES, BLUEPRINT_PLUGIN

Expand All @@ -11,7 +12,7 @@

__author__ = "Alex Laird"
__copyright__ = "Copyright 2020, Alex Laird"
__version__ = "1.2.0"
__version__ = "1.2.2"


class TestPluginManager(HookeeTestCase):
Expand All @@ -35,50 +36,84 @@ def test_build_from_module(self):
self.assertEqual(plugin.name, "request_body")
self.assertTrue(plugin.has_setup)

def test_build_from_module_not_conform_to_spec(self):
# TODO implement
pass
# GIVEN

# WHEN

# THEN

def test_build_from_module_no_plugin_type(self):
# TODO implement
pass
# GIVEN
invalid_plugin_path = os.path.join(self.plugins_dir, "invalid_plugin.py")
with open(invalid_plugin_path, "w") as f:
f.write("""
def setup(hookee_manager):
pass
def run(request, response):
return response""")
plugin = self.plugin_manager.source.load_plugin("invalid_plugin")

# WHEN
with self.assertRaises(HookeePluginValidationError) as cm:
Plugin.build_from_module(plugin)

# THEN
self.assertIn("does not conform to the plugin spec", str(cm.exception))

def test_build_from_module_no_run(self):
# TODO implement
pass
# GIVEN
invalid_plugin_path = os.path.join(self.plugins_dir, "invalid_plugin.py")
with open(invalid_plugin_path, "w") as f:
f.write("""from hookee.pluginmanager import REQUEST_PLUGIN
plugin_type = REQUEST_PLUGIN
def setup(hookee_manager):
pass""")
plugin = self.plugin_manager.source.load_plugin("invalid_plugin")

# WHEN
with self.assertRaises(HookeePluginValidationError) as cm:
Plugin.build_from_module(plugin)

# THEN
self.assertIn("must implement `run", str(cm.exception))

def test_build_from_module_wrong_args(self):
# TODO implement
pass
# GIVEN
invalid_plugin_path = os.path.join(self.plugins_dir, "invalid_plugin.py")
with open(invalid_plugin_path, "w") as f:
f.write("""from hookee.pluginmanager import REQUEST_PLUGIN
plugin_type = REQUEST_PLUGIN
def setup(hookee_manager):
pass
def run():
return response""")
plugin = self.plugin_manager.source.load_plugin("invalid_plugin")

# WHEN
with self.assertRaises(HookeePluginValidationError) as cm:
Plugin.build_from_module(plugin)

# THEN
self.assertIn("`run(request)` must be defined", str(cm.exception))

def test_build_from_module_no_blueprint(self):
# TODO implement
pass
# GIVEN
invalid_plugin_path = os.path.join(self.plugins_dir, "invalid_plugin.py")
with open(invalid_plugin_path, "w") as f:
f.write("""from hookee.pluginmanager import BLUEPRINT_PLUGIN
plugin_type = BLUEPRINT_PLUGIN
def setup(hookee_manager):
pass""")
plugin = self.plugin_manager.source.load_plugin("invalid_plugin")

# WHEN
with self.assertRaises(HookeePluginValidationError) as cm:
Plugin.build_from_module(plugin)

# THEN
self.assertIn("must define `blueprint", str(cm.exception))

def test_response_callback(self):
# GIVEN
Expand All @@ -102,6 +137,10 @@ def response_callback(request, response):
def test_load_plugins(self):
# GIVEN
self.assertEqual(0, len(self.plugin_manager.loaded_plugins))
builtin_plugin_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "hookee", "plugins",
"request_url_info.py")
custom_plugin_path = os.path.join(self.plugins_dir, "custom_plugin.py")
shutil.copy(builtin_plugin_path, custom_plugin_path)
request_script_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "hookee", "plugins",
"request_body.py")
custom_request_plugin_path = os.path.join(self.plugins_dir, "custom_request_plugin.py")
Expand All @@ -110,6 +149,8 @@ def test_load_plugins(self):
"response_echo.py")
custom_response_plugin_path = os.path.join(self.plugins_dir, "custom_response_plugin.py")
shutil.copy(response_script_path, custom_response_plugin_path)

self.hookee_manager.config.append("plugins", "custom_plugin")
self.hookee_manager.config.set("request_script", custom_request_plugin_path)
self.hookee_manager.config.set("response_script", custom_response_plugin_path)
self.hookee_manager.config.set("response", "<Response>Ok</Response>")
Expand All @@ -119,7 +160,7 @@ def test_load_plugins(self):
self.plugin_manager.load_plugins()

# THEN
self.assertEqual(10, len(self.plugin_manager.loaded_plugins))
self.assertEqual(11, len(self.plugin_manager.loaded_plugins))
request_script_found = False
response_script_found = False
for plugin in self.plugin_manager.loaded_plugins:
Expand Down

0 comments on commit d703d56

Please sign in to comment.