# Path: hotness/domain/package.py
# class Package:
#     """
#     Internal representation of package object.
# 
#     Attributes:
#         name (str): Name of the package
#         version (str): Latest version of the package
#         distro (str): Distribution assigned
#     """
# 
#     def __init__(self, name: str, version: str, distro: str) -> None:
#         """
#         Class constructor
#         """
#         self.name = name
#         self.version = version
#         self.distro = distro
# 
#     def to_dict(self) -> dict:
#         """
#         Convert object to dictionary.
# 
#         Return:
#             Dictionary created from package object.
#         """
#         return {"name": self.name, "version": self.version, "distro": self.distro}
# 
#     @classmethod
#     def from_dict(cls, package_dict: dict) -> object:
#         """
#         Convert dictionary to object.
# 
#         Params:
#             package_dict: Dictionary to create package from.
# 
#         Return:
#             Package object.
#         """
#         package = Package(
#             name=package_dict["name"],
#             version=package_dict["version"],
#             distro=package_dict["distro"],
#         )
#         return package
# 
#     def __eq__(self, other: object) -> bool:
#         """
#         Compare method for package object.
# 
#         Params:
#             other: object to compare with
# 
#         Return:
#             Compare result.
#         """
#         return self.to_dict() == other.to_dict()  # type: ignore
# 
# Path: hotness/exceptions/notifier_exception.py
# class NotifierException(BaseHotnessException):
#     """
#     Class representing notifier exception.
#     This exception is raised by notifier
#     when it encounters error with external notifier system.
# 
#     Attributes:
#         message: Error message.
#     """
# 
#     def __init__(self, message: str) -> None:
#         """
#         Class constructor.
#         """
#         self.message = message
#         super(NotifierException, self).__init__(self.message)
# 
# Path: hotness/notifiers/fedora_messaging.py
# class FedoraMessaging(Notifier):
#     """
#     This class is a wrapper for https://github.com/fedora-infra/fedora-messaging publisher.
#     It publishes a message to fedora messaging broker using hotness_schema messages.
# 
#     Attributes:
#         prefix (str): String used as prefix for the topic
#     """
# 
#     def __init__(self, prefix: str) -> None:
#         """
#         Class constructor.
# 
#         It initializes class attributes.
# 
#         Params:
#             prefix: Prefix to use for topic
#         """
#         super(FedoraMessaging, self).__init__()
#         self.prefix = prefix
# 
#     def notify(self, package: Package, message: str, opts: dict) -> dict:
#         """
#         This method is inherited from `hotness.notifiers.Notifier`.
# 
#         It publishes messages to Fedora messaging broker.
# 
#         Params:
#             package: Package to create notification for
#             message: Topic for the message
#             opts: Additional options for fedora message. Example:
#                 {
#                     "body": {} # Body of the message we want to sent. Look at the
#                                # hotness_schema for more info
#                 }
# 
#         Returns:
#             Dictionary containing message id
#             Example:
#             {
#                 "msg_id": "ae68f"
#             }
# 
#         Raises:
#             NotifierException: When the required `opts` parameters are missing or
#                                error happens during publishing.
#         """
#         topic = self.prefix + "." + message
#         body = opts.get("body", {})
#         output = {}
# 
#         if not body:
#             raise NotifierException(
#                 "Additional parameters are missing! Please provide `body` for the message."
#             )
# 
#         message_class = fm_message.get_class(topic)
#         if not message_class:
#             raise NotifierException("Unknown topic provided '{}'".format(topic))
# 
#         _logger.info("publishing topic %r" % topic)
#         try:
#             msg = message_class(topic=topic, body=body)
#             api.publish(msg)
#         except PublishException as e:
#             raise NotifierException(
#                 "Fedora messaging broker rejected message {}:{}".format(msg.id, e)
#             )
#         except ConnectionException as e:
#             raise NotifierException("Error sending the message {}:{}".format(msg.id, e))
#         finally:
#             output["msg_id"] = msg.id
# 
#         return output


import pytest
from unittest import mock
from fedora_messaging.testing import mock_sends
from fedora_messaging.exceptions import PublishException, ConnectionException
from hotness_schema.messages import UpdateDrop
from hotness.domain import Package
from hotness.exceptions import NotifierException
from hotness.notifiers import FedoraMessaging
        opts = {"body": body}

        with mock_sends(UpdateDrop):
            output = self.notifier.notify(package, topic, opts)

            assert list(output.keys()) == ["msg_id"]

    def test_notify_missing_opts(self):
        """
        Assert that NotifierException is raised when opts are missing.
        """
        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        topic = "update.drop"

        with pytest.raises(NotifierException) as exc:
            self.notifier.notify(package, topic, {})

        assert exc.value.message == (
            "Additional parameters are missing! "
            "Please provide `body` for the message."
        )

    @mock.patch("hotness.notifiers.fedora_messaging.fm_message.get_class")
    def test_notify_unknown_topic(self, mock_fm_get_class):
        """
        Assert that NotifierException is raised when topic is not found.
        """
        # Prepare package

# Path: hotness/domain/package.py
# class Package:
#     """
#     Internal representation of package object.
# 
#     Attributes:
#         name (str): Name of the package
#         version (str): Latest version of the package
#         distro (str): Distribution assigned
#     """
# 
#     def __init__(self, name: str, version: str, distro: str) -> None:
#         """
#         Class constructor
#         """
#         self.name = name
#         self.version = version
#         self.distro = distro
# 
#     def to_dict(self) -> dict:
#         """
#         Convert object to dictionary.
# 
#         Return:
#             Dictionary created from package object.
#         """
#         return {"name": self.name, "version": self.version, "distro": self.distro}
# 
#     @classmethod
#     def from_dict(cls, package_dict: dict) -> object:
#         """
#         Convert dictionary to object.
# 
#         Params:
#             package_dict: Dictionary to create package from.
# 
#         Return:
#             Package object.
#         """
#         package = Package(
#             name=package_dict["name"],
#             version=package_dict["version"],
#             distro=package_dict["distro"],
#         )
#         return package
# 
#     def __eq__(self, other: object) -> bool:
#         """
#         Compare method for package object.
# 
#         Params:
#             other: object to compare with
# 
#         Return:
#             Compare result.
#         """
#         return self.to_dict() == other.to_dict()  # type: ignore
# 
# Path: hotness/exceptions/notifier_exception.py
# class NotifierException(BaseHotnessException):
#     """
#     Class representing notifier exception.
#     This exception is raised by notifier
#     when it encounters error with external notifier system.
# 
#     Attributes:
#         message: Error message.
#     """
# 
#     def __init__(self, message: str) -> None:
#         """
#         Class constructor.
#         """
#         self.message = message
#         super(NotifierException, self).__init__(self.message)
# 
# Path: hotness/notifiers/fedora_messaging.py
# class FedoraMessaging(Notifier):
#     """
#     This class is a wrapper for https://github.com/fedora-infra/fedora-messaging publisher.
#     It publishes a message to fedora messaging broker using hotness_schema messages.
# 
#     Attributes:
#         prefix (str): String used as prefix for the topic
#     """
# 
#     def __init__(self, prefix: str) -> None:
#         """
#         Class constructor.
# 
#         It initializes class attributes.
# 
#         Params:
#             prefix: Prefix to use for topic
#         """
#         super(FedoraMessaging, self).__init__()
#         self.prefix = prefix
# 
#     def notify(self, package: Package, message: str, opts: dict) -> dict:
#         """
#         This method is inherited from `hotness.notifiers.Notifier`.
# 
#         It publishes messages to Fedora messaging broker.
# 
#         Params:
#             package: Package to create notification for
#             message: Topic for the message
#             opts: Additional options for fedora message. Example:
#                 {
#                     "body": {} # Body of the message we want to sent. Look at the
#                                # hotness_schema for more info
#                 }
# 
#         Returns:
#             Dictionary containing message id
#             Example:
#             {
#                 "msg_id": "ae68f"
#             }
# 
#         Raises:
#             NotifierException: When the required `opts` parameters are missing or
#                                error happens during publishing.
#         """
#         topic = self.prefix + "." + message
#         body = opts.get("body", {})
#         output = {}
# 
#         if not body:
#             raise NotifierException(
#                 "Additional parameters are missing! Please provide `body` for the message."
#             )
# 
#         message_class = fm_message.get_class(topic)
#         if not message_class:
#             raise NotifierException("Unknown topic provided '{}'".format(topic))
# 
#         _logger.info("publishing topic %r" % topic)
#         try:
#             msg = message_class(topic=topic, body=body)
#             api.publish(msg)
#         except PublishException as e:
#             raise NotifierException(
#                 "Fedora messaging broker rejected message {}:{}".format(msg.id, e)
#             )
#         except ConnectionException as e:
#             raise NotifierException("Error sending the message {}:{}".format(msg.id, e))
#         finally:
#             output["msg_id"] = msg.id
# 
#         return output


# Path: tests/notifiers/test_fedora_messaging.py
import pytest
from unittest import mock
from fedora_messaging.testing import mock_sends
from fedora_messaging.exceptions import PublishException, ConnectionException
from hotness_schema.messages import UpdateDrop
from hotness.domain import Package
from hotness.exceptions import NotifierException
from hotness.notifiers import FedoraMessaging

        opts = {"body": body}

        with mock_sends(UpdateDrop):
            output = self.notifier.notify(package, topic, opts)

            assert list(output.keys()) == ["msg_id"]

    def test_notify_missing_opts(self):
        """
        Assert that NotifierException is raised when opts are missing.
        """
        # Prepare package
        package = Package(name="test", version="1.0", distro="Fedora")

        topic = "update.drop"

        with pytest.raises(NotifierException) as exc:
            self.notifier.notify(package, topic, {})

        assert exc.value.message == (
            "Additional parameters are missing! "
            "Please provide `body` for the message."
        )

    @mock.patch("hotness.notifiers.fedora_messaging.fm_message.get_class")
    def test_notify_unknown_topic(self, mock_fm_get_class):
        """
        Assert that NotifierException is raised when topic is not found.
        """
        # Prepare package

        package = Package(name="test", version="1.0", distro="Fedora")