126 lines
3.7 KiB
Python
126 lines
3.7 KiB
Python
from pathlib import Path
|
|
|
|
import pytest
|
|
from typer.testing import CliRunner
|
|
|
|
from takopi import cli
|
|
from takopi.config import ConfigError
|
|
from takopi.settings import TakopiSettings
|
|
from takopi.settings import TelegramTopicsSettings
|
|
from takopi.telegram.api_models import Chat, User
|
|
|
|
|
|
def _settings() -> TakopiSettings:
|
|
return TakopiSettings.model_validate(
|
|
{
|
|
"transport": "telegram",
|
|
"transports": {"telegram": {"bot_token": "token", "chat_id": 123}},
|
|
}
|
|
)
|
|
|
|
|
|
def test_doctor_ok(monkeypatch) -> None:
|
|
settings = _settings()
|
|
monkeypatch.setattr(cli, "load_settings", lambda: (settings, Path("x")))
|
|
monkeypatch.setattr(cli, "resolve_plugins_allowlist", lambda _settings: None)
|
|
monkeypatch.setattr(cli, "list_backend_ids", lambda allowlist=None: ["codex"])
|
|
|
|
async def _fake_checks(*_args, **_kwargs):
|
|
return [cli.DoctorCheck("telegram token", "ok", "@bot")]
|
|
|
|
monkeypatch.setattr(cli, "_doctor_telegram_checks", _fake_checks)
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli.create_app(), ["doctor"])
|
|
|
|
assert result.exit_code == 0
|
|
assert "takopi doctor" in result.output
|
|
assert "telegram token: ok" in result.output
|
|
|
|
|
|
def test_doctor_errors_exit_nonzero(monkeypatch) -> None:
|
|
settings = _settings()
|
|
monkeypatch.setattr(cli, "load_settings", lambda: (settings, Path("x")))
|
|
monkeypatch.setattr(cli, "resolve_plugins_allowlist", lambda _settings: None)
|
|
monkeypatch.setattr(cli, "list_backend_ids", lambda allowlist=None: ["codex"])
|
|
|
|
async def _fake_checks(*_args, **_kwargs):
|
|
return [cli.DoctorCheck("telegram token", "error", "bad token")]
|
|
|
|
monkeypatch.setattr(cli, "_doctor_telegram_checks", _fake_checks)
|
|
|
|
runner = CliRunner()
|
|
result = runner.invoke(cli.create_app(), ["doctor"])
|
|
|
|
assert result.exit_code == 1
|
|
assert "telegram token: error" in result.output
|
|
|
|
|
|
class _FakeBot:
|
|
def __init__(self, me: User | None, chat: Chat | None) -> None:
|
|
self._me = me
|
|
self._chat = chat
|
|
self.closed = False
|
|
|
|
async def get_me(self) -> User | None:
|
|
return self._me
|
|
|
|
async def get_chat(self, chat_id: int) -> Chat | None:
|
|
_ = chat_id
|
|
return self._chat
|
|
|
|
async def close(self) -> None:
|
|
self.closed = True
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_doctor_telegram_checks_invalid_token(monkeypatch) -> None:
|
|
bot = _FakeBot(me=None, chat=None)
|
|
monkeypatch.setattr(cli, "TelegramClient", lambda _token: bot)
|
|
topics = TelegramTopicsSettings(enabled=True)
|
|
|
|
checks = await cli._doctor_telegram_checks(
|
|
"token",
|
|
123,
|
|
topics,
|
|
(),
|
|
)
|
|
|
|
assert [check.label for check in checks] == [
|
|
"telegram token",
|
|
"chat_id",
|
|
"topics",
|
|
]
|
|
assert checks[0].status == "error"
|
|
assert checks[1].detail == "skipped (token invalid)"
|
|
assert checks[2].detail == "skipped (token invalid)"
|
|
assert bot.closed is True
|
|
|
|
|
|
@pytest.mark.anyio
|
|
async def test_doctor_telegram_checks_chat_and_topics_error(monkeypatch) -> None:
|
|
bot = _FakeBot(
|
|
me=User(id=1, username="bot", first_name=None, last_name=None),
|
|
chat=None,
|
|
)
|
|
monkeypatch.setattr(cli, "TelegramClient", lambda _token: bot)
|
|
|
|
async def _raise_topics(*_args, **_kwargs) -> None:
|
|
raise ConfigError("bad topics")
|
|
|
|
monkeypatch.setattr(cli, "_validate_topics_setup_for", _raise_topics)
|
|
topics = TelegramTopicsSettings(enabled=True)
|
|
|
|
checks = await cli._doctor_telegram_checks(
|
|
"token",
|
|
321,
|
|
topics,
|
|
(),
|
|
)
|
|
|
|
assert checks[0].detail == "@bot"
|
|
assert checks[1].status == "error"
|
|
assert "unreachable" in (checks[1].detail or "")
|
|
assert checks[2].detail == "bad topics"
|
|
assert bot.closed is True
|