186 lines
5.6 KiB
Python
186 lines
5.6 KiB
Python
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Any
|
|
|
|
import pytest
|
|
|
|
from takopi.config import ProjectsConfig
|
|
from takopi.router import AutoRouter, RunnerEntry
|
|
from takopi.runners.mock import Return, ScriptRunner
|
|
from takopi.settings import (
|
|
TelegramFilesSettings,
|
|
TelegramTopicsSettings,
|
|
TelegramTransportSettings,
|
|
)
|
|
from takopi.telegram import backend as telegram_backend
|
|
from takopi.transport_runtime import TransportRuntime
|
|
|
|
|
|
def test_build_startup_message_includes_missing_engines(tmp_path: Path) -> None:
|
|
codex = "codex"
|
|
pi = "pi"
|
|
runner = ScriptRunner([Return(answer="ok")], engine=codex)
|
|
missing = ScriptRunner([Return(answer="ok")], engine=pi)
|
|
router = AutoRouter(
|
|
entries=[
|
|
RunnerEntry(engine=codex, runner=runner),
|
|
RunnerEntry(
|
|
engine=pi,
|
|
runner=missing,
|
|
status="missing_cli",
|
|
issue="missing",
|
|
),
|
|
],
|
|
default_engine=codex,
|
|
)
|
|
runtime = TransportRuntime(
|
|
router=router,
|
|
projects=ProjectsConfig(projects={}, default_project=None),
|
|
watch_config=True,
|
|
)
|
|
|
|
message = telegram_backend._build_startup_message(
|
|
runtime,
|
|
startup_pwd=str(tmp_path),
|
|
chat_id=123,
|
|
session_mode="stateless",
|
|
show_resume_line=True,
|
|
topics=TelegramTopicsSettings(),
|
|
)
|
|
|
|
assert "takopi is ready" in message
|
|
assert "engines: `codex (not installed: pi)`" in message
|
|
assert "projects: `none`" in message
|
|
|
|
|
|
def test_build_startup_message_surfaces_unavailable_engine_reasons(
|
|
tmp_path: Path,
|
|
) -> None:
|
|
codex = "codex"
|
|
pi = "pi"
|
|
claude = "claude"
|
|
runner = ScriptRunner([Return(answer="ok")], engine=codex)
|
|
bad_cfg = ScriptRunner([Return(answer="ok")], engine=pi)
|
|
load_err = ScriptRunner([Return(answer="ok")], engine=claude)
|
|
|
|
router = AutoRouter(
|
|
entries=[
|
|
RunnerEntry(engine=codex, runner=runner),
|
|
RunnerEntry(engine=pi, runner=bad_cfg, status="bad_config", issue="bad"),
|
|
RunnerEntry(
|
|
engine=claude,
|
|
runner=load_err,
|
|
status="load_error",
|
|
issue="failed",
|
|
),
|
|
],
|
|
default_engine=codex,
|
|
)
|
|
runtime = TransportRuntime(
|
|
router=router,
|
|
projects=ProjectsConfig(projects={}, default_project=None),
|
|
watch_config=True,
|
|
)
|
|
|
|
message = telegram_backend._build_startup_message(
|
|
runtime,
|
|
startup_pwd=str(tmp_path),
|
|
chat_id=123,
|
|
session_mode="stateless",
|
|
show_resume_line=True,
|
|
topics=TelegramTopicsSettings(),
|
|
)
|
|
|
|
assert "engines: `codex" in message
|
|
assert "misconfigured: pi" in message
|
|
assert "failed to load: claude" in message
|
|
|
|
|
|
def test_telegram_backend_build_and_run_wires_config(
|
|
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
config_path = tmp_path / "takopi.toml"
|
|
config_path.write_text(
|
|
'watch_config = true\ntransport = "telegram"\n\n'
|
|
"[transports.telegram]\n"
|
|
'bot_token = "token"\n'
|
|
"chat_id = 321\n",
|
|
encoding="utf-8",
|
|
)
|
|
|
|
codex = "codex"
|
|
runner = ScriptRunner([Return(answer="ok")], engine=codex)
|
|
router = AutoRouter(
|
|
entries=[RunnerEntry(engine=codex, runner=runner)],
|
|
default_engine=codex,
|
|
)
|
|
runtime = TransportRuntime(
|
|
router=router,
|
|
projects=ProjectsConfig(projects={}, default_project=None),
|
|
watch_config=True,
|
|
)
|
|
|
|
captured: dict[str, Any] = {}
|
|
|
|
async def fake_run_main_loop(cfg, **kwargs) -> None:
|
|
captured["cfg"] = cfg
|
|
captured["kwargs"] = kwargs
|
|
|
|
class _FakeClient:
|
|
def __init__(self, token: str) -> None:
|
|
self.token = token
|
|
|
|
async def close(self) -> None:
|
|
return None
|
|
|
|
monkeypatch.setattr(telegram_backend, "run_main_loop", fake_run_main_loop)
|
|
monkeypatch.setattr(telegram_backend, "TelegramClient", _FakeClient)
|
|
|
|
transport_config = TelegramTransportSettings(
|
|
bot_token="token",
|
|
chat_id=321,
|
|
allowed_user_ids=[7, 8],
|
|
voice_transcription=True,
|
|
voice_max_bytes=1234,
|
|
voice_transcription_model="whisper-1",
|
|
voice_transcription_base_url="http://localhost:8000/v1",
|
|
voice_transcription_api_key="local",
|
|
files=TelegramFilesSettings(enabled=True, allowed_user_ids=[1, 2]),
|
|
topics=TelegramTopicsSettings(enabled=True, scope="main"),
|
|
)
|
|
|
|
telegram_backend.TelegramBackend().build_and_run(
|
|
transport_config=transport_config,
|
|
config_path=config_path,
|
|
runtime=runtime,
|
|
final_notify=False,
|
|
default_engine_override=None,
|
|
)
|
|
|
|
cfg = captured["cfg"]
|
|
kwargs = captured["kwargs"]
|
|
assert cfg.chat_id == 321
|
|
assert cfg.voice_transcription is True
|
|
assert cfg.voice_max_bytes == 1234
|
|
assert cfg.voice_transcription_model == "whisper-1"
|
|
assert cfg.voice_transcription_base_url == "http://localhost:8000/v1"
|
|
assert cfg.voice_transcription_api_key == "local"
|
|
assert cfg.allowed_user_ids == (7, 8)
|
|
assert cfg.files.enabled is True
|
|
assert cfg.files.allowed_user_ids == [1, 2]
|
|
assert cfg.topics.enabled is True
|
|
assert cfg.bot.token == "token"
|
|
assert kwargs["watch_config"] is True
|
|
assert kwargs["transport_id"] == "telegram"
|
|
|
|
|
|
def test_telegram_files_settings_defaults() -> None:
|
|
cfg = TelegramFilesSettings()
|
|
|
|
assert cfg.enabled is False
|
|
assert cfg.auto_put is True
|
|
assert cfg.auto_put_mode == "upload"
|
|
assert cfg.uploads_dir == "incoming"
|
|
assert cfg.allowed_user_ids == []
|