From a2245071e780f7378e53d92b77044bdaf8a80f2f Mon Sep 17 00:00:00 2001 From: Andrew Morgan Date: Sun, 10 Jan 2021 22:00:33 -0500 Subject: [PATCH] Add a unit test for the invite callback --- tests/test_callbacks.py | 50 +++++++++++++++++++++++++++++++++++++++++ tests/utils.py | 22 ++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 tests/test_callbacks.py create mode 100644 tests/utils.py diff --git a/tests/test_callbacks.py b/tests/test_callbacks.py new file mode 100644 index 0000000..ff6a20a --- /dev/null +++ b/tests/test_callbacks.py @@ -0,0 +1,50 @@ +import unittest +from unittest.mock import Mock + +import nio + +from my_project_name.callbacks import Callbacks +from my_project_name.storage import Storage + +from tests.utils import make_awaitable, run_coroutine + + +class CallbacksTestCase(unittest.TestCase): + def setUp(self) -> None: + # Create a Callbacks object and give it some Mock'd objects to use + self.fake_client = Mock(spec=nio.AsyncClient) + self.fake_client.user = "@fake_user:example.com" + + self.fake_storage = Mock(spec=Storage) + + # We don't spec config, as it doesn't currently have well defined attributes + self.fake_config = Mock() + + self.callbacks = Callbacks( + self.fake_client, self.fake_storage, self.fake_config + ) + + def test_invite(self): + """Tests the callback for InviteMemberEvents""" + # Tests that the bot attempts to join a room after being invited to it + + # Create a fake room and invite event to call the 'invite' callback with + fake_room = Mock(spec=nio.MatrixRoom) + fake_room_id = "!abcdefg:example.com" + fake_room.room_id = fake_room_id + + fake_invite_event = Mock(spec=nio.InviteMemberEvent) + fake_invite_event.sender = "@some_other_fake_user:example.com" + + # Pretend that attempting to join a room is always successful + self.fake_client.join.return_value = make_awaitable(None) + + # Pretend that we received an invite event + run_coroutine(self.callbacks.invite(fake_room, fake_invite_event)) + + # Check that we attempted to join the room + self.fake_client.join.assert_called_once_with(fake_room_id) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/utils.py b/tests/utils.py new file mode 100644 index 0000000..3fcf429 --- /dev/null +++ b/tests/utils.py @@ -0,0 +1,22 @@ +# Utility functions to make testing easier +import asyncio +from typing import Any, Awaitable + + +def run_coroutine(result: Awaitable[Any]) -> Any: + """Wrapper for asyncio functions to allow them to be run from synchronous functions""" + loop = asyncio.get_event_loop() + result = loop.run_until_complete(result) + loop.close() + return result + + +def make_awaitable(result: Any) -> Awaitable[Any]: + """ + Makes an awaitable, suitable for mocking an `async` function. + This uses Futures as they can be awaited multiple times so can be returned + to multiple callers. + """ + future = asyncio.Future() # type: ignore + future.set_result(result) + return future