Skip to content

Commit

Permalink
more work on tests (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
brokenpip3 authored Feb 1, 2025
1 parent 1b45e44 commit d20b88c
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 37 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ Check [CONTRIBUTING.md](./CONTRIBUTING.md)

## Credits 🙏

* Thanks to the [`python-telegra-bot`](https://github.com/python-telegram-bot/python-telegram-bot) dev team for the great library
* Thanks to the [`python-telegram-bot`](https://github.com/python-telegram-bot/python-telegram-bot) dev team for the great library
* Thanks DALL-E for the great logo
* This repo has been initialized with:

Expand Down
4 changes: 2 additions & 2 deletions lotb/lotb.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ async def photo_handler(update: Update, context: ContextTypes.DEFAULT_TYPE):

async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
commands = [f"/{command} - {plugin.description}" for command, plugin in plugins.items()]
response = "Available commands:\n\n" + "\n".join(commands) + "\nFind more at https://github.com/brokenpip3/lotb"
response = "Available commands:\n\n" + "\n".join(commands) + "\n\nFind more at https://github.com/brokenpip3/lotb"
if update.message:
await update.message.reply_text(response)
await update.message.reply_text(response, disable_web_page_preview=True)
logger.info("Displayed help commands.")


Expand Down
2 changes: 0 additions & 2 deletions lotb/plugins/readwise.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ def __init__(self):

def initialize(self):
plugin_config = self.config.get(f"plugins.{self.name}", {})
if plugin_config.get("debug"):
self.log_info(f"Configuration for {self.name}: {plugin_config}")
self.readwise_token = plugin_config.get("token")
if not self.readwise_token:
raise ValueError("Readwise token not found in configuration.")
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "lotb"
version = "0.0.3"
version = "0.0.4"
description = "Lord of the Telegram bots"
authors = ["brokenpip3 <brokenpip3@gmail.com>"]
license = "MIT"
Expand Down
27 changes: 2 additions & 25 deletions test/lotb_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
from unittest.mock import patch

import pytest
from telegram import Chat
from telegram import User
from telegram.ext import ContextTypes

from lotb.common.plugin_class import PluginBase
Expand All @@ -18,13 +16,7 @@
@pytest.fixture
def mock_update(mock_update):
update = mock_update
user = MagicMock(spec=User)
chat = MagicMock(spec=Chat)
user.id = 12345
chat.id = 67890
update.message.text = "/test"
update.effective_user = user
update.effective_chat = chat
return update


Expand All @@ -45,9 +37,7 @@ async def test_handle_command_authorized(mock_load_plugins, mock_plugins, mock_u
mock_plugin.group_is_authorized.return_value = True
mock_plugin.execute = AsyncMock()
mock_plugins["test"] = mock_plugin

await handle_command(mock_update, mock_context)

mock_plugin.execute.assert_called_once_with(mock_update, mock_context)
mock_update.message.reply_text.assert_not_called()

Expand All @@ -59,9 +49,7 @@ async def test_handle_command_unauthorized_group(mock_load_plugins, mock_plugins
mock_plugin = MagicMock()
mock_plugin.group_is_authorized.return_value = False
mock_plugins["test"] = mock_plugin

await handle_command(mock_update, mock_context)

mock_plugin.execute.assert_not_called()


Expand All @@ -74,9 +62,7 @@ async def test_handle_command_unauthorized_user(mock_load_plugins, mock_plugins,
mock_plugin.group_is_authorized.return_value = True
mock_plugin.execute = AsyncMock()
mock_plugins["test"] = mock_plugin

await handle_command(mock_update, mock_context)

mock_update.message.reply_text.assert_called_once_with("you are not authorized to use this command.")


Expand All @@ -87,11 +73,9 @@ async def test_help_command(mock_load_plugins, mock_plugins, mock_update, mock_c
mock_plugin = MagicMock()
mock_plugin.description = "Test command"
mock_plugins["test"] = mock_plugin

await help_command(mock_update, mock_context)

expected_text = "Available commands:\n\n/test - Test command\nFind more at https://github.com/brokenpip3/lotb"
mock_update.message.reply_text.assert_called_once_with(expected_text)
expected_text = "Available commands:\n\n/test - Test command\n\nFind more at https://github.com/brokenpip3/lotb"
mock_update.message.reply_text.assert_called_once_with(expected_text, disable_web_page_preview=True)


@pytest.mark.asyncio
Expand All @@ -107,11 +91,8 @@ async def test_enable_plugin(
mock_import_module.return_value = mock_module
mock_plugin_instance = MagicMock()
mock_module.Plugin.return_value = mock_plugin_instance

config = MagicMock()

await enable_plugin(mock_update, mock_context, config)

mock_update.message.reply_text.assert_called_once_with("Plugin test enabled.")
assert "test" in mock_plugins

Expand All @@ -124,9 +105,7 @@ async def test_disable_plugin(mock_application, mock_handlers, mock_plugins, moc
mock_context.args = ["test"]
mock_plugins["test"] = MagicMock()
mock_handlers["test"] = MagicMock()

await disable_plugin(mock_update, mock_context)

mock_update.message.reply_text.assert_called_once_with("Plugin test disabled.")
assert "test" not in mock_plugins
assert "test" not in mock_handlers
Expand All @@ -137,9 +116,7 @@ async def test_disable_plugin(mock_application, mock_handlers, mock_plugins, moc
@patch("lotb.lotb.load_plugins")
async def test_list_plugins(mock_load_plugins, mock_plugins, mock_update, mock_context):
mock_plugins["test"] = MagicMock()

await list_plugins(mock_update, mock_context)

mock_update.message.reply_text.assert_called_once_with("🤖 Enabled plugins:\ntest")


Expand Down
40 changes: 40 additions & 0 deletions test/plugin_readwise_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ def mock_update(mock_update):
return update


@pytest.mark.asyncio
async def test_readwise_token_not_found():
config = MagicMock()
config.get.side_effect = lambda key, default=None: {"plugins.readwise": {"enabled": "true"}}.get(key, default)
plugin = Plugin()
plugin.set_config(config)
with pytest.raises(ValueError, match="Readwise token not found in configuration."):
plugin.initialize()


def test_extract_url_from_message():
plugin = Plugin()
assert plugin.extract_url_from_message("this is a local url http://local.lan") == "http://local.lan"
assert plugin.extract_url_from_message("I love wikipedia: https://wikipedia.com") == "https://wikipedia.com"
assert plugin.extract_url_from_message("No url here") == ""


@pytest.mark.asyncio
@patch("lotb.plugins.readwise.httpx.AsyncClient")
@patch("lotb.plugins.readwise.httpx.Client")
Expand Down Expand Up @@ -102,3 +119,26 @@ async def test_readwise_no_url(mock_httpx_client, mock_httpx_async, mock_update,
mock_update.message.text = "/readwise"
await plugin.execute(mock_update, mock_context)
mock_update.message.reply_text.assert_called_once_with("Missing URL argument for Readwise command.", quote=True)


@pytest.mark.asyncio
@patch("lotb.plugins.readwise.httpx.AsyncClient")
@patch("lotb.plugins.readwise.httpx.Client")
async def test_readwise_failed_to_save(mock_httpx_client, mock_httpx_async, mock_update, mock_context):
mock_response_valid = MagicMock()
mock_response_valid.status_code = 204
mock_httpx_client.return_value.__enter__.return_value.get.return_value = mock_response_valid
mock_response_fail = MagicMock()
mock_response_fail.status_code = 500
mock_httpx_async.return_value.__aenter__.return_value.post.return_value = mock_response_fail

config = MagicMock()
config.get.side_effect = lambda key, default=None: {
"plugins.readwise": {"enabled": "true", "token": "fake_token"}
}.get(key, default)

plugin = Plugin()
plugin.set_config(config)
plugin.initialize()
await plugin.execute(mock_update, mock_context)
mock_update.message.reply_text.assert_called_once_with("Failed to save URL to Readwise.", quote=True)
33 changes: 27 additions & 6 deletions test/plugin_welcome_test.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,46 @@
from unittest.mock import AsyncMock
from unittest.mock import MagicMock

import pytest

from lotb.common.config import Config
from lotb.plugins.welcome import Plugin


@pytest.fixture
def mock_config():
config = MagicMock(spec=Config)
config.get.side_effect = lambda key, default=None: {
"core.database": "/tmp/test.db",
"plugins.welcome": {"enabled": "true"},
}.get(key, default)
return config


@pytest.fixture
def mock_update(mock_update):
update = mock_update
update.message.text = "/welcome What is dead may never die"
return update


@pytest.mark.asyncio
async def test_welcome_plugin(mock_update, mock_context):
@pytest.fixture
def welcome_plugin(mock_config):
plugin = Plugin()
await plugin.execute(mock_update, mock_context)
plugin.set_config(mock_config)
plugin.initialize()
plugin.reply_message = AsyncMock()
return plugin


@pytest.mark.asyncio
async def test_welcome_plugin(mock_update, mock_context, welcome_plugin):
await welcome_plugin.execute(mock_update, mock_context)
mock_update.message.reply_text.assert_called_once_with("Welcome: What is dead may never die", quote=True)


@pytest.mark.asyncio
async def test_welcome_plugin_no_message(mock_update, mock_context):
plugin = Plugin()
async def test_welcome_plugin_no_message(mock_update, mock_context, welcome_plugin):
mock_update.message.text = "/welcome"
await plugin.execute(mock_update, mock_context)
await welcome_plugin.execute(mock_update, mock_context)
mock_update.message.reply_text.assert_called_once_with("Welcome!", quote=True)

0 comments on commit d20b88c

Please sign in to comment.