move handlers to separate files

This commit is contained in:
Dmitry Afanasyev
2023-09-22 22:59:52 +03:00
committed by GitHub
parent 1ecf95631d
commit 315284fc38
8 changed files with 161 additions and 128 deletions

View File

@@ -16,6 +16,7 @@ from telegram import Bot, User
from telegram.ext import Application, ApplicationBuilder, Defaults, ExtBot
from app.core.bot import BotApplication
from app.core.handlers import command_handlers
from app.main import Application as AppApplication
from settings.config import AppSettings, get_settings
from tests.integration.bot.networking import NonchalantHttpxRequest
@@ -119,27 +120,41 @@ def bot_info() -> dict[str, Any]:
@pytest_asyncio.fixture(scope="session")
async def bot(bot_info: dict[str, Any]) -> AsyncGenerator[PytestExtBot, None]:
async def bot_application(bot_info: dict[str, Any]) -> AsyncGenerator[Any, None]:
# We build a new bot each time so that we use `app` in a context manager without problems
application = ApplicationBuilder().bot(make_bot(bot_info)).application_class(PytestApplication).build()
yield application
if application.running:
await application.stop()
await application.shutdown()
@pytest_asyncio.fixture(scope="session")
async def bot(bot_info: dict[str, Any], bot_application: Any) -> AsyncGenerator[PytestExtBot, None]:
"""Makes an ExtBot instance with the given bot_info"""
async with make_bot(bot_info) as _bot:
_bot.application = bot_application
yield _bot
@pytest.fixture()
def one_time_bot(bot_info: dict[str, Any]) -> PytestExtBot:
def one_time_bot(bot_info: dict[str, Any], bot_application: Any) -> PytestExtBot:
"""A function scoped bot since the session bot would shutdown when `async with app` finishes"""
return make_bot(bot_info)
bot = make_bot(bot_info)
bot.application = bot_application
return bot
@pytest_asyncio.fixture(scope="session")
async def cdc_bot(bot_info: dict[str, Any]) -> AsyncGenerator[PytestExtBot, None]:
async def cdc_bot(bot_info: dict[str, Any], bot_application: Any) -> AsyncGenerator[PytestExtBot, None]:
"""Makes an ExtBot instance with the given bot_info that uses arbitrary callback_data"""
async with make_bot(bot_info, arbitrary_callback_data=True) as _bot:
_bot.application = bot_application
yield _bot
@pytest_asyncio.fixture(scope="session")
async def raw_bot(bot_info: dict[str, Any]) -> AsyncGenerator[PytestBot, None]:
async def raw_bot(bot_info: dict[str, Any], bot_application: Any) -> AsyncGenerator[PytestBot, None]:
"""Makes an regular Bot instance with the given bot_info"""
async with PytestBot(
bot_info["token"],
@@ -147,6 +162,7 @@ async def raw_bot(bot_info: dict[str, Any]) -> AsyncGenerator[PytestBot, None]:
request=NonchalantHttpxRequest(8),
get_updates_request=NonchalantHttpxRequest(1),
) as _bot:
_bot.application = bot_application
yield _bot
@@ -207,22 +223,15 @@ def provider_token(bot_info: dict[str, Any]) -> str:
return bot_info["payment_provider_token"]
@pytest_asyncio.fixture(scope="session")
async def bot_application(bot_info: dict[str, Any]) -> AsyncGenerator[Any, None]:
# We build a new bot each time so that we use `app` in a context manager without problems
application = ApplicationBuilder().bot(make_bot(bot_info)).application_class(PytestApplication).build()
yield application
if application.running:
await application.stop()
await application.shutdown()
@pytest_asyncio.fixture(scope="session")
async def main_application(
bot_application: PytestApplication, test_settings: AppSettings
) -> AsyncGenerator[FastAPI, None]:
bot_app = BotApplication(settings=test_settings)
bot_app.application = bot_application
bot_app = BotApplication(
application=bot_application,
settings=test_settings,
handlers=command_handlers.handlers,
)
fast_api_app = AppApplication(settings=test_settings, bot_app=bot_app).fastapi_app
yield fast_api_app

View File

@@ -4,91 +4,69 @@ from asyncio import AbstractEventLoop
from typing import Any
import pytest
from assertpy import assert_that
from faker import Faker
from httpx import AsyncClient
from app.core.bot import BotApplication, BotQueue
from app.main import Application
from tests.integration.bot.networking import MockedRequest
from tests.integration.factories.bot import (
BotChatFactory,
BotEntitleFactory,
BotUserFactory,
)
pytestmark = [
pytest.mark.asyncio,
]
faker = Faker()
async def test_bot_updates(rest_client: AsyncClient) -> None:
response = await rest_client.get("/api/healthcheck")
assert response.status_code == 200
async def test_bot_webhook_endpoint(
rest_client: AsyncClient,
main_application: Application,
) -> None:
response = await rest_client.post(
url="/api/123456789:AABBCCDDEEFFaabbccddeeff-1234567890",
json={
"update_id": 957250703,
"message": {
"message_id": 417070387,
"from": {
"id": 1000,
"is_bot": "false",
"first_name": "William",
"last_name": "Dalton",
"username": "bolshakovfortunat",
"language_code": "ru",
},
"chat": {
"id": 1,
"first_name": "Gabrielle",
"last_name": "Smith",
"username": "arefi_2019",
"type": "private",
},
"date": time.time(),
"text": "/chatid",
"entities": [{"type": "bot_command", "offset": 0, "length": 7}],
},
},
)
bot_update = create_bot_update()
response = await rest_client.post(url="/api/123456789:AABBCCDDEEFFaabbccddeeff-1234567890", json=bot_update)
assert response.status_code == 202
update = await main_application.state._state["queue"].queue.get() # type: ignore[attr-defined]
update = update.to_dict()
assert update["update_id"] == bot_update["update_id"]
assert_that(update["message"]).is_equal_to(
bot_update["message"], include=["from", "entities", "message_id", "text"]
)
async def test_bot_queue(
bot: BotApplication,
bot_application: Any,
main_application: Application,
event_loop: AbstractEventLoop,
) -> None:
bot.application = bot_application
bot_queue = BotQueue(bot_app=bot)
event_loop.create_task(bot_queue.get_updates_from_queue())
mocked_request = MockedRequest(
{
"update_id": 957250703,
"message": {
"message_id": 417070387,
"from": {
"id": 1000,
"is_bot": "false",
"first_name": "William",
"last_name": "Dalton",
"username": "bolshakovfortunat",
"language_code": "ru",
},
"chat": {
"id": 1,
"first_name": "Gabrielle",
"last_name": "Smith",
"username": "arefi_2019",
"type": "private",
},
"date": time.time(),
"text": "/chatid",
"entities": [{"type": "bot_command", "offset": 0, "length": 7}],
},
}
)
bot_update = create_bot_update()
mocked_request = MockedRequest(bot_update)
await bot_queue.put_updates_on_queue(mocked_request) # type: ignore
await asyncio.sleep(1)
assert bot_queue.queue.empty()
def create_bot_update() -> dict[str, Any]:
bot_update: dict[str, Any] = {}
bot_update["update_id"] = faker.random_int(min=10**8, max=10**9 - 1)
bot_update["message"] = {
"message_id": faker.random_int(min=10**8, max=10**9 - 1),
"from": BotUserFactory()._asdict(),
"chat": BotChatFactory()._asdict(),
"date": time.time(),
"text": "/chatid",
"entities": [BotEntitleFactory()],
}
return bot_update