Files
dzentra_bot/app/tests/unit/bootstrap/test_app_factory.py

167 lines
3.8 KiB
Python

from __future__ import annotations
from types import SimpleNamespace
import pytest
import src.bootstrap.app_factory as app_factory
from src.bootstrap.application import ApplicationComposition
class RecordingJournal:
def __init__(self) -> None:
self.info_calls: list[
tuple[str, str, dict[str, object]]
] = []
def log_info(
self,
event: str,
message: str,
context: dict[str, object],
) -> None:
self.info_calls.append(
(
event,
message,
context,
)
)
def log_critical(
self,
event: str,
message: str,
context: dict[str, object],
) -> None:
del event, message, context
def make_settings() -> SimpleNamespace:
return SimpleNamespace(
bot_token="test-token",
bot_parse_mode="HTML",
log_level="INFO",
app_env="test",
exchange_name="dzengi",
default_symbol="BTC/USD_LEVERAGE",
trade_stream=SimpleNamespace(enabled=True),
)
def test_create_app_builds_one_application_composition(
monkeypatch: pytest.MonkeyPatch,
) -> None:
settings = make_settings()
bot = object()
dispatcher = object()
runtime = object()
journal = RecordingJournal()
observed_runtime_settings: list[object] = []
registered_bots: list[object] = []
routed_dispatchers: list[object] = []
monkeypatch.setattr(
app_factory,
"load_settings",
lambda: settings,
)
monkeypatch.setattr(
app_factory,
"setup_logging",
lambda level: None,
)
monkeypatch.setattr(
app_factory,
"init_schema",
lambda: None,
)
monkeypatch.setattr(
app_factory,
"JournalService",
lambda: journal,
)
def build_runtime(received_settings: object) -> object:
observed_runtime_settings.append(received_settings)
return runtime
monkeypatch.setattr(
app_factory,
"build_trade_stream_production_runtime",
build_runtime,
)
monkeypatch.setattr(
app_factory,
"Bot",
lambda **kwargs: bot,
)
monkeypatch.setattr(
app_factory,
"Dispatcher",
lambda: dispatcher,
)
monkeypatch.setattr(
app_factory.NotificationTargetRegistry,
"set_bot",
registered_bots.append,
)
monkeypatch.setattr(
app_factory,
"setup_routers",
routed_dispatchers.append,
)
application = app_factory.create_app()
assert isinstance(application, ApplicationComposition)
assert application.bot is bot
assert application.dispatcher is dispatcher
assert application.trade_stream_runtime is runtime
assert observed_runtime_settings == [settings]
assert registered_bots == [bot]
assert routed_dispatchers == [dispatcher]
assert journal.info_calls[0][2]["trade_stream_enabled"] is True
def test_runtime_build_error_is_fatal(
monkeypatch: pytest.MonkeyPatch,
) -> None:
expected = RuntimeError("invalid Trade Stream settings")
monkeypatch.setattr(
app_factory,
"load_settings",
make_settings,
)
monkeypatch.setattr(
app_factory,
"setup_logging",
lambda level: None,
)
monkeypatch.setattr(
app_factory,
"init_schema",
lambda: None,
)
monkeypatch.setattr(
app_factory,
"JournalService",
RecordingJournal,
)
def fail_runtime_build(settings: object) -> None:
del settings
raise expected
monkeypatch.setattr(
app_factory,
"build_trade_stream_production_runtime",
fail_runtime_build,
)
with pytest.raises(RuntimeError) as exc_info:
app_factory.create_app()
assert exc_info.value is expected