diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index b7e47898..00000000 --- a/setup.cfg +++ /dev/null @@ -1,2 +0,0 @@ -[aliases] -test=pytest diff --git a/setup.py b/setup.py index 9dc183f1..7e22130d 100644 --- a/setup.py +++ b/setup.py @@ -51,9 +51,6 @@ setuptools.setup( extras_require=extras_require, python_requires="~=3.7", - setup_requires=["pytest-runner"], - tests_require=["pytest", "pytest-asyncio", "pytest-mock"], - classifiers=[ "Development Status :: 4 - Beta", "License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)", diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/commands/__init__.py b/tests/commands/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/commands/test_handler.py b/tests/commands/test_handler.py deleted file mode 100644 index 4e175102..00000000 --- a/tests/commands/test_handler.py +++ /dev/null @@ -1,381 +0,0 @@ -from typing import Tuple -from unittest.mock import Mock - -import pytest -from _pytest.fixtures import FixtureRequest -from pytest_mock import MockFixture - -from mautrix.types import EventID, RoomID, UserID -import mautrix.bridge.commands.handler - -import mautrix_telegram.commands.handler -from mautrix_telegram.commands.handler import (CommandEvent, CommandHandler, CommandProcessor, - HelpSection, HelpCacheKey) -from mautrix_telegram.config import Config -from mautrix_telegram.context import Context -import mautrix_telegram.user as u - -from tests.utils.helpers import AsyncMock, list_true_once_each - - -@pytest.fixture -def context(request: FixtureRequest) -> Context: - """Returns a Context with mocked Attributes. - - Uses the attribute cls.config as Config. - """ - # Config(path, registration_path, base_path) - config = getattr(request.cls, 'config', Config("", "", "")) - return Context(az=Mock(), config=config, loop=Mock(), session_container=Mock(), bridge=Mock(), bot=Mock()) - - -@pytest.fixture -def command_processor(context: Context) -> CommandProcessor: - """Returns a mocked CommandProcessor.""" - return CommandProcessor(context) - - -class TestCommandEvent: - config = Config("", "", "") - config["bridge.command_prefix"] = "tg" - config["bridge.permissions"] = {"*": "noperm"} - - def test_reply( - self, command_processor: CommandProcessor, mocker: MockFixture - ) -> None: - mocker.patch("mautrix_telegram.user.config", self.config) - - evt = CommandEvent( - processor=command_processor, - room_id=RoomID("#mock_room:example.org"), - event_id=EventID("$H45H:example.org"), - sender=u.User(UserID("@sender:example.org")), - command="help", - args=[], - content=Mock(), - is_management=True, - is_portal=False, - ) - - mock_az = command_processor.az - - message = "**This** was
allfun*!" - - # html, no markdown - evt.reply(message, allow_html=True, render_markdown=False) - mock_az.intent.send_notice.assert_called_with( - RoomID("#mock_room:example.org"), - "**This** was
allfun*!", - html="**This** was
allfun*!\n", - ) - - # html, markdown (default) - evt.reply(message, allow_html=True, render_markdown=True) - mock_az.intent.send_notice.assert_called_with( - RoomID("#mock_room:example.org"), - "**This** was
allfun*!", - html=( - "

This was
" - "allfun*!

\n" - ), - ) - - # no html, no markdown - evt.reply(message, allow_html=False, render_markdown=False) - mock_az.intent.send_notice.assert_called_with( - RoomID("#mock_room:example.org"), - "**This** was
allfun*!", - html=None, - ) - - # no html, markdown - evt.reply(message, allow_html=False, render_markdown=True) - mock_az.intent.send_notice.assert_called_with( - RoomID("#mock_room:example.org"), - "**This** was
allfun*!", - html="

This <i>was</i><br/>" - "<strong>all</strong>fun*!

\n" - ) - - def test_reply_with_cmdprefix(self, command_processor: CommandProcessor, mocker: MockFixture - ) -> None: - mocker.patch("mautrix_telegram.user.config", self.config) - - evt = CommandEvent( - processor=command_processor, - room_id=RoomID("#mock_room:example.org"), - event_id=EventID("$H45H:example.org"), - sender=u.User(UserID("@sender:example.org")), - command="help", - args=[], - content=Mock(), - is_management=False, - is_portal=False, - ) - - mock_az = command_processor.az - - evt.reply("$cmdprefix+sp ....$cmdprefix+sp...$cmdprefix $cmdprefix", allow_html=False, - render_markdown=False) - - mock_az.intent.send_notice.assert_called_with( - RoomID("#mock_room:example.org"), - "tg ....tg+sp...tg tg", - html=None, - ) - - def test_reply_with_cmdprefix_in_management_room(self, command_processor: CommandProcessor, - mocker: MockFixture) -> None: - mocker.patch("mautrix_telegram.user.config", self.config) - - evt = CommandEvent( - processor=command_processor, - room_id=RoomID("#mock_room:example.org"), - event_id=EventID("$H45H:example.org"), - sender=u.User(UserID("@sender:example.org")), - command="help", - args=[], - content=Mock(), - is_management=True, - is_portal=False, - ) - - mock_az = command_processor.az - - evt.reply( - "$cmdprefix+sp ....$cmdprefix+sp...$cmdprefix $cmdprefix", - allow_html=True, - render_markdown=True, - ) - - mock_az.intent.send_notice.assert_called_with( - RoomID("#mock_room:example.org"), - "....tg+sp...tg tg", - html="

....tg+sp...tg tg

\n", - ) - - -class TestCommandHandler: - config = Config("", "", "") - config["bridge.permissions"] = {"*": "noperm"} - - @pytest.mark.parametrize( - ( - "needs_auth," - "needs_puppeting," - "needs_matrix_puppeting," - "needs_admin," - "management_only," - ), - [l for l in list_true_once_each(length=5)] - ) - @pytest.mark.asyncio - async def test_permissions_denied( - self, - needs_auth: bool, - needs_puppeting: bool, - needs_matrix_puppeting: bool, - needs_admin: bool, - management_only: bool, - command_processor: CommandProcessor, - boolean: bool, - mocker: MockFixture, - ) -> None: - mocker.patch("mautrix_telegram.user.config", self.config) - - command = "testcmd" - - mock_handler = Mock() - - command_handler = CommandHandler( - handler=mock_handler, - needs_auth=needs_auth, - needs_puppeting=needs_puppeting, - needs_matrix_puppeting=needs_matrix_puppeting, - needs_admin=needs_admin, - management_only=management_only, - name=command, - help_text="No real command", - help_args="mock mockmock", - help_section=HelpSection("Mock Section", 42, ""), - ) - - sender = u.User(UserID("@sender:example.org")) - sender.puppet_whitelisted = False - sender.matrix_puppet_whitelisted = False - sender.is_admin = False - - event = CommandEvent( - processor=command_processor, - room_id=RoomID("#mock_room:example.org"), - event_id=EventID("$H45H:example.org"), - sender=sender, - command=command, - args=[], - content=Mock(), - is_management=False, - is_portal=boolean, - ) - - assert await command_handler.get_permission_error(event) - assert not command_handler.has_permission( - HelpCacheKey(False, False, False, False, False, False)) - - @pytest.mark.parametrize( - ( - "is_management," - "puppet_whitelisted," - "matrix_puppet_whitelisted," - "is_admin," - "is_logged_in," - ), - [l for l in list_true_once_each(length=5)] - ) - @pytest.mark.asyncio - async def test_permission_granted( - self, - is_management: bool, - puppet_whitelisted: bool, - matrix_puppet_whitelisted: bool, - is_admin: bool, - is_logged_in: bool, - command_processor: CommandProcessor, - boolean: bool, - mocker: MockFixture, - ) -> None: - mocker.patch("mautrix_telegram.user.config", self.config) - - command = "testcmd" - - mock_handler = Mock() - - command_handler = CommandHandler( - handler=mock_handler, - needs_auth=False, - needs_puppeting=False, - needs_matrix_puppeting=False, - needs_admin=False, - management_only=False, - name=command, - help_text="No real command", - help_args="mock mockmock", - help_section=HelpSection("Mock Section", 42, ""), - ) - - sender = u.User(UserID("@sender:example.org")) - sender.puppet_whitelisted = puppet_whitelisted - sender.matrix_puppet_whitelisted = matrix_puppet_whitelisted - sender.is_admin = is_admin - mocker.patch.object(u.User, 'is_logged_in', return_value=is_logged_in) - - event = CommandEvent( - processor=command_processor, - room_id=RoomID("#mock_room:example.org"), - event_id=EventID("$H45H:example.org"), - sender=sender, - command=command, - args=[], - content=Mock(), - is_management=is_management, - is_portal=boolean, - ) - - assert not await command_handler.get_permission_error(event) - assert command_handler.has_permission( - HelpCacheKey(is_management=is_management, - puppet_whitelisted=puppet_whitelisted, - matrix_puppet_whitelisted=matrix_puppet_whitelisted, - is_admin=is_admin, - is_logged_in=is_logged_in, - is_portal=boolean)) - - -class TestCommandProcessor: - config = Config("", "", "") - config["bridge.command_prefix"] = "tg" - config["bridge.permissions"] = {"*": "relaybot"} - - @pytest.mark.asyncio - async def test_handle(self, command_processor: CommandProcessor, boolean2: Tuple[bool, bool], - mocker: MockFixture) -> None: - mocker.patch('mautrix_telegram.user.config', self.config) - mocker.patch( - 'mautrix.bridge.commands.handler.command_handlers', - {"help": AsyncMock(), "unknown-command": AsyncMock()} - ) - - sender = u.User(UserID("@sender:example.org")) - - result = await command_processor.handle( - room_id=RoomID("#mock_room:example.org"), - event_id=EventID("$H45H:example.org"), - sender=sender, - command="hElp", - args=[], - content=Mock(), - is_management=boolean2[0], - is_portal=boolean2[1]) - - assert result is None - command_handlers = mautrix.bridge.commands.handler.command_handlers - command_handlers["help"].mock.assert_called_once() # type: ignore - - @pytest.mark.asyncio - async def test_handle_unknown_command(self, command_processor: CommandProcessor, - boolean2: Tuple[bool, bool], - mocker: MockFixture) -> None: - mocker.patch('mautrix_telegram.user.config', self.config) - mocker.patch( - 'mautrix.bridge.commands.handler.command_handlers', - {"help": AsyncMock(), "unknown-command": AsyncMock()} - ) - - sender = u.User(UserID("@sender:example.org")) - sender.command_status = {} - - result = await command_processor.handle( - room_id=RoomID("#mock_room:example.org"), - event_id=EventID("$H45H:example.org"), - sender=sender, - command="foo", - args=[], - content=Mock(), - is_management=boolean2[0], - is_portal=boolean2[1], - ) - - assert result is None - command_handlers = mautrix.bridge.commands.handler.command_handlers - command_handlers["help"].mock.assert_not_called() # type: ignore - command_handlers["unknown-command"].mock.assert_called_once() # type: ignore - - @pytest.mark.asyncio - async def test_handle_delegated_handler(self, command_processor: CommandProcessor, - boolean2: Tuple[bool, bool], - mocker: MockFixture) -> None: - mocker.patch('mautrix_telegram.user.config', self.config) - mocker.patch( - 'mautrix.bridge.commands.handler.command_handlers', - {"help": AsyncMock(), "unknown-command": AsyncMock()} - ) - - sender = u.User(UserID("@sender:example.org")) - sender.command_status = {"foo": AsyncMock(), "next": AsyncMock()} - - result = await command_processor.handle( - room_id=RoomID("#mock_room:example.org"), - event_id=EventID("$H45H:example.org"), - sender=sender, # u.User - command="foo", - args=[], - content=Mock(), - is_management=boolean2[0], - is_portal=boolean2[1] - ) - - assert result is None - command_handlers = mautrix.bridge.commands.handler.command_handlers - command_handlers["help"].mock.assert_not_called() # type: ignore - command_handlers["unknown-command"].mock.assert_not_called() # type: ignore - sender.command_status["foo"].mock.assert_not_called() # type: ignore - sender.command_status["next"].mock.assert_called_once() # type: ignore diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index 86f72a5c..00000000 --- a/tests/conftest.py +++ /dev/null @@ -1,3 +0,0 @@ -pytest_plugins = [ - "tests.utils.fixtures", -] diff --git a/tests/utils/__init__.py b/tests/utils/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/utils/fixtures.py b/tests/utils/fixtures.py deleted file mode 100644 index e0953da7..00000000 --- a/tests/utils/fixtures.py +++ /dev/null @@ -1,27 +0,0 @@ -"""This module provides utility fixtures for testing.""" -from typing import Tuple - -from _pytest.fixtures import FixtureRequest -import pytest - - -@pytest.fixture(params=[True, False]) -def boolean(request: FixtureRequest) -> bool: - return request.param - - -@pytest.fixture -def boolean1(boolean: bool) -> Tuple[bool]: - return boolean, - - -@pytest.fixture(params=[True, False]) -def boolean2(request: FixtureRequest, boolean: bool) -> Tuple[bool, bool]: - return boolean, request.param - - -@pytest.fixture(params=[True, False]) -def boolean3(request: FixtureRequest, boolean2: Tuple[bool, bool]) -> Tuple[bool, bool, bool]: - return boolean2[0], boolean2[1], request.param - -# … diff --git a/tests/utils/helpers.py b/tests/utils/helpers.py deleted file mode 100644 index e2283b9b..00000000 --- a/tests/utils/helpers.py +++ /dev/null @@ -1,24 +0,0 @@ -"""This module provides utility functions for testing.""" -from typing import Generator, Tuple -from unittest.mock import Mock - - -def AsyncMock(*args, **kwargs): - """Mocks a asyncronous coroutine which can be called with 'await'.""" - m = Mock(*args, **kwargs) - - async def mock_coro(*args, **kwargs): - return m(*args, **kwargs) - - mock_coro.mock = m - return mock_coro - - -def list_true_once_each(length: int) -> Generator[Tuple[bool, ...], None, None]: - """Yields tuples of bools with exactly one entry being True, starting left. - - Args: - length: Length of the resulting tuples - """ - for i in range(length): - yield tuple(i == j for j in range(length))