# Path: honeybadger/plugins.py
# class PluginManager(object):
#     """
#     Manages lifecycle of plugins.
#     """
#     def __init__(self):
#         self._registered = OrderedDict()
# 
#     def register(self, plugin):
#         """
#         Register the given plugin. Registration order is kept.
#         :param plugin: the plugin to register.
#         """
#         if plugin.name not in self._registered:
#             logger.info('Registering plugin %s' % plugin.name)
#             self._registered[plugin.name] = plugin
#         else:
#             logger.warning('Plugin %s already registered' % plugin.name)
# 
#     def generate_payload(self, default_payload, config=None, context=None):
#         """
#         Generate payload by iterating over registered plugins. Merges .
#         :param context: current context.
#         :param config: honeybadger configuration.
#         :return: a dict with the generated payload.
#         """
#         for name, plugin in iteritems(self._registered):
#             if plugin.supports(config, context):
#                 logger.debug('Returning payload from plugin %s' % name)
#                 
#                 default_payload = plugin.generate_payload(default_payload, config, context)
#         else:
#             logger.debug('No active plugin to generate payload')
#         
#         return default_payload


import unittest
from mock import Mock
from honeybadger.plugins import PluginManager
        # Given only 2nd registered plugin supports providing payload
        self.plugin1.supports.return_value = False
        self.plugin2.supports.return_value = True
        self.plugin2.generate_payload.return_value = {'name': 'plugin2'}

        payload = self.manager.generate_payload(default_payload=self.default_payload, context=context)
        # Expect order to be preferred and use value from second plugin
        self.assertDictEqual({'name': 'plugin2'}, payload)
        self.plugin1.supports.assert_called_once_with(None, context)
        self.assertEqual(0, self.plugin1.generate_payload.call_count)
        self.plugin2.supports.assert_called_once_with(None, context)
        self.plugin2.generate_payload.assert_called_once_with(self.default_payload, None, context)

    def test_generate_payload_none(self):
        self.manager.register(self.plugin1)
        self.manager.register(self.plugin2)
        context = {'test': 'context'}
        default_payload = {'request':{'context':context}}

        # Given no registered plugin supports providing payload
        self.plugin1.supports.return_value = False
        self.plugin2.supports.return_value = False

        payload = self.manager.generate_payload(default_payload=default_payload, context=context)
        print(payload)
        # Expect order to be preferred and use input context value
        self.assertDictEqual({'request':{'context': context}}, payload)
        self.plugin1.supports.assert_called_once_with(None, context)
        self.assertEqual(0, self.plugin1.generate_payload.call_count)
        self.plugin2.supports.assert_called_once_with(None, context)

# Path: honeybadger/plugins.py
# class PluginManager(object):
#     """
#     Manages lifecycle of plugins.
#     """
#     def __init__(self):
#         self._registered = OrderedDict()
# 
#     def register(self, plugin):
#         """
#         Register the given plugin. Registration order is kept.
#         :param plugin: the plugin to register.
#         """
#         if plugin.name not in self._registered:
#             logger.info('Registering plugin %s' % plugin.name)
#             self._registered[plugin.name] = plugin
#         else:
#             logger.warning('Plugin %s already registered' % plugin.name)
# 
#     def generate_payload(self, default_payload, config=None, context=None):
#         """
#         Generate payload by iterating over registered plugins. Merges .
#         :param context: current context.
#         :param config: honeybadger configuration.
#         :return: a dict with the generated payload.
#         """
#         for name, plugin in iteritems(self._registered):
#             if plugin.supports(config, context):
#                 logger.debug('Returning payload from plugin %s' % name)
#                 
#                 default_payload = plugin.generate_payload(default_payload, config, context)
#         else:
#             logger.debug('No active plugin to generate payload')
#         
#         return default_payload


# Path: honeybadger/tests/test_plugins.py
import unittest
from mock import Mock
from honeybadger.plugins import PluginManager

        # Given only 2nd registered plugin supports providing payload
        self.plugin1.supports.return_value = False
        self.plugin2.supports.return_value = True
        self.plugin2.generate_payload.return_value = {'name': 'plugin2'}

        payload = self.manager.generate_payload(default_payload=self.default_payload, context=context)
        # Expect order to be preferred and use value from second plugin
        self.assertDictEqual({'name': 'plugin2'}, payload)
        self.plugin1.supports.assert_called_once_with(None, context)
        self.assertEqual(0, self.plugin1.generate_payload.call_count)
        self.plugin2.supports.assert_called_once_with(None, context)
        self.plugin2.generate_payload.assert_called_once_with(self.default_payload, None, context)

    def test_generate_payload_none(self):
        self.manager.register(self.plugin1)
        self.manager.register(self.plugin2)
        context = {'test': 'context'}
        default_payload = {'request':{'context':context}}

        # Given no registered plugin supports providing payload
        self.plugin1.supports.return_value = False
        self.plugin2.supports.return_value = False

        payload = self.manager.generate_payload(default_payload=default_payload, context=context)
        print(payload)
        # Expect order to be preferred and use input context value
        self.assertDictEqual({'request':{'context': context}}, payload)
        self.plugin1.supports.assert_called_once_with(None, context)
        self.assertEqual(0, self.plugin1.generate_payload.call_count)
        self.plugin2.supports.assert_called_once_with(None, context)

        self.assertEqual(0, self.plugin2.generate_payload.call_count)