huesoporro/tests/conftest.py

269 lines
6.7 KiB
Python

from pathlib import Path
from uuid import UUID
import pytest
from caribou.migrate import Database as CaribouDatabase
from caribou.migrate import load_migrations
from polyfactory.factories.pydantic_factory import ModelFactory
from polyfactory.pytest_plugin import register_fixture
from pydantic import BaseModel
from huesoporro.infra.repos import ChatbotRepo, IRepo, QuoteRepo, UserRepo
from huesoporro.models import Chatbot, Quote, TwitchAuth, User
from huesoporro.settings import Settings
from huesoporro.svc.backoff_service import BackoffService
from huesoporro.svc.chatbot_svcs import (
CreateChatbotSvc,
GetChatbotByUserIdSvc,
UpdateChatbotSvc,
)
from huesoporro.svc.hello import HelloGeneratorSvc
from huesoporro.svc.is_mod import IsModSvc
from huesoporro.svc.quotes_svcs import CreateQuoteSvc, GetRandomQuoteSvc
from huesoporro.svc.users_svcs import (
CreateUserSvc,
DeleteUserSvc,
GetTwitchAuthByAuthCodeSvc,
GetUserByIdSvc,
GetUserByUsernameSvc,
UpdateUserSvc,
)
@register_fixture()
class TwitchAuthFactory(ModelFactory[TwitchAuth]): ...
@register_fixture()
class ChatbotFactory(ModelFactory[Chatbot]): ...
@register_fixture()
class UserFactory(ModelFactory[User]): ...
@register_fixture()
class QuoteFactory(ModelFactory[Quote]): ...
@pytest.fixture
def s(tmp_path: Path, user: User) -> Settings:
return Settings(
static_files_path=tmp_path / "static_files",
db_filepath=tmp_path / "huesoporro.db",
twitch_client_id="test_client_id",
twitch_client_secret="test_client_secret", # type: ignore[arg-type] # noqa: S106
jwt_secret="test_jwt_secret", # type: ignore[arg-type] # noqa: S106
allowed_users=[user.username],
)
@pytest.fixture
def db(s, cdb):
class BogusRepo(IRepo[BaseModel]):
async def get_by_id(self, obj_id: UUID, auto_commit=True) -> BaseModel | None:
pass
async def list( # type: ignore[empty-body]
self, offset: int = 0, limit: int = 10, auto_commit=True
) -> list[BaseModel]:
pass
async def create(self, obj: BaseModel, auto_commit: bool = True) -> BaseModel: # type: ignore[empty-body]
pass
async def update(self, obj: BaseModel, auto_commit=True) -> BaseModel: # type: ignore[empty-body]
pass
async def delete(self, obj: BaseModel, auto_commit=True) -> None: # type: ignore[empty-body]
pass
async def get_by_user(self, user: str) -> BaseModel: # type: ignore[empty-body]
pass
return BogusRepo(s=s).get_client
@pytest.fixture
def cdb(s) -> CaribouDatabase:
cdb = CaribouDatabase(
db_url=s.db_filepath,
)
cdb.initialize_version_control()
migrations = load_migrations(Path(__file__).parents[1] / "migrations")
cdb.upgrade(migrations)
return cdb
@pytest.fixture
async def user_repo(s, db):
return UserRepo(s=s)
@pytest.fixture
def twitch_auth(twitch_auth_factory):
return twitch_auth_factory.build(
userinfo={
"aud": twitch_auth_factory.__faker__.pystr(),
"exp": twitch_auth_factory.__faker__.pyint(),
"iat": twitch_auth_factory.__faker__.pyint(),
"iss": "https://id.twitch.tv/oauth2",
"sub": twitch_auth_factory.__faker__.pystr(),
"azp": twitch_auth_factory.__faker__.pystr(),
"preferred_username": twitch_auth_factory.__faker__.user_name(),
}
)
@pytest.fixture
async def user(user_factory: UserFactory, twitch_auth) -> User:
return user_factory.build(external_auth={"twitch": twitch_auth})
@pytest.fixture
async def persisted_user(user_repo: UserRepo, user: User) -> User:
return await user_repo.create(user)
@pytest.fixture
def create_user_svc(user_repo):
return CreateUserSvc(user_repo=user_repo)
@pytest.fixture
def update_user_svc(user_repo):
return UpdateUserSvc(user_repo=user_repo)
@pytest.fixture
def delete_user_svc(user_repo):
return DeleteUserSvc(user_repo=user_repo)
@pytest.fixture
def get_user_by_id_svc(user_repo):
return GetUserByIdSvc(user_repo=user_repo)
@pytest.fixture
def get_user_by_username_svc(user_repo):
return GetUserByUsernameSvc(user_repo=user_repo)
@pytest.fixture
def get_twitch_auth_by_auth_code_svc(
twitch_authenticator, fake_twitch_authenticator, user_repo, s
):
svc = GetTwitchAuthByAuthCodeSvc(authenticator=twitch_authenticator, s=s)
svc.authenticator = fake_twitch_authenticator
return svc
@pytest.fixture
async def chatbot_repo(s, db):
return ChatbotRepo(s=s)
@pytest.fixture
async def chatbot(chatbot_factory, user):
return chatbot_factory.build(user_id=user.id)
@pytest.fixture
async def five_chatbots(chatbot_factory, user):
return [chatbot_factory.build() for _ in range(5)]
@pytest.fixture
async def persisted_five_chatbots(five_chatbots, chatbot_repo):
return [await chatbot_repo.create(chatbot) for chatbot in five_chatbots]
@pytest.fixture
async def persisted_chatbot(chatbot_repo, chatbot, persisted_user):
return await chatbot_repo.create(chatbot)
@pytest.fixture
async def create_chatbot_svc(chatbot_repo):
return CreateChatbotSvc(repo=chatbot_repo)
@pytest.fixture
async def get_chatbot_by_user_id_svc(chatbot_repo):
return GetChatbotByUserIdSvc(repo=chatbot_repo)
@pytest.fixture
async def update_chatbot_svc(chatbot_repo):
return UpdateChatbotSvc(repo=chatbot_repo)
@pytest.fixture
async def is_mod_svc(chatbot_repo):
return IsModSvc(repo=chatbot_repo)
@pytest.fixture
async def quote_repo(s, db):
return QuoteRepo(s=s)
@pytest.fixture
async def quote(quote_factory):
return quote_factory.build()
@pytest.fixture
async def five_quotes(quote_factory):
return [quote_factory.build() for _ in range(5)]
@pytest.fixture
async def persisted_quote(quote_repo, quote):
quote.is_active = True
return await quote_repo.create(quote)
@pytest.fixture
async def persisted_five_quotes(five_quotes, quote_repo):
return [await quote_repo.create(quote) for quote in five_quotes]
@pytest.fixture
async def create_quote_svc(quote_repo):
return CreateQuoteSvc(repo=quote_repo)
@pytest.fixture
async def get_random_quote_svc(quote_repo):
return GetRandomQuoteSvc(repo=quote_repo)
@pytest.fixture
def backoff_callable():
def foo():
return "foo"
return foo
@pytest.fixture
def async_backoff_callable():
async def async_foo():
return "async foo"
return async_foo
@pytest.fixture
async def backoff_svc(backoff_callable, async_backoff_callable):
backoff_svc = BackoffService()
backoff_svc.add_callable(backoff_callable, 3)
backoff_svc.add_callable(async_backoff_callable, 3)
return backoff_svc
@pytest.fixture
async def hello_generator_svc():
return HelloGeneratorSvc()