feat: add backoff service and some message reactions
This commit is contained in:
parent
2cad170eb3
commit
3bc4e19de1
11 changed files with 394 additions and 24 deletions
|
|
@ -7,6 +7,7 @@ from caribou.migrate import load_migrations
|
|||
from src.huesoporro.infra.db import Database
|
||||
from src.huesoporro.models import ChatbotSettings, TwitchAuth, User
|
||||
from src.huesoporro.settings import Settings
|
||||
from src.huesoporro.svc.backoff_service import BackoffService
|
||||
from src.huesoporro.svc.is_mod import IsModSvc
|
||||
|
||||
|
||||
|
|
@ -16,7 +17,8 @@ def user() -> User:
|
|||
user="huesoporro",
|
||||
expires_at=1671234567.0,
|
||||
twitch_auth=TwitchAuth(
|
||||
access_token="test_access_token", refresh_token="test_refresh_token"
|
||||
access_token="test_access_token", # noqa: S106
|
||||
refresh_token="test_refresh_token", # noqa: S106
|
||||
),
|
||||
)
|
||||
|
||||
|
|
@ -27,8 +29,8 @@ def s(tmp_path: Path, user: User) -> 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]
|
||||
jwt_secret="test_jwt_secret", # type: ignore[arg-type]
|
||||
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.user],
|
||||
)
|
||||
|
||||
|
|
@ -54,3 +56,27 @@ async def chatbot_settings(db: Database, user) -> ChatbotSettings:
|
|||
cbs = ChatbotSettings(mods=[user.user, "allowed_user"])
|
||||
await db.save_chatbot_settings(user=user, chatbot_settings=cbs)
|
||||
return cbs
|
||||
|
||||
|
||||
@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
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
import asyncio
|
||||
import time
|
||||
|
||||
import pytest
|
||||
|
||||
from src.huesoporro.models import ChatbotSettings, User
|
||||
|
|
@ -33,3 +36,61 @@ async def test_is_mod_svc_returns_false_for_user_not_in_modlist(
|
|||
):
|
||||
is_mod = await is_mod_svc.run(user=user, username="TestUser2", channel=user.user)
|
||||
assert not is_mod
|
||||
|
||||
|
||||
async def test_backoff_svc_returns_for_first_attempt(
|
||||
backoff_svc, backoff_callable, async_backoff_callable
|
||||
):
|
||||
assert backoff_svc.call(backoff_callable) == "foo"
|
||||
|
||||
assert await backoff_svc.call_async(async_backoff_callable) == "async foo"
|
||||
|
||||
|
||||
async def test_backoff_svc_returns_none_for_second_attempt(
|
||||
backoff_svc, backoff_callable, async_backoff_callable
|
||||
):
|
||||
assert backoff_svc.call(backoff_callable) == "foo"
|
||||
assert backoff_svc.call(backoff_callable) is None
|
||||
|
||||
assert await backoff_svc.call_async(async_backoff_callable) == "async foo"
|
||||
assert await backoff_svc.call_async(async_backoff_callable) is None
|
||||
|
||||
|
||||
async def test_backoff_svc_returns_for_second_attempt_after_delay(
|
||||
backoff_svc, backoff_callable, async_backoff_callable
|
||||
):
|
||||
assert backoff_svc.call(backoff_callable) == "foo"
|
||||
assert backoff_svc.call(backoff_callable) is None
|
||||
time.sleep(3)
|
||||
assert backoff_svc.call(backoff_callable) == "foo"
|
||||
|
||||
assert await backoff_svc.call_async(async_backoff_callable) == "async foo"
|
||||
assert await backoff_svc.call_async(async_backoff_callable) is None
|
||||
await asyncio.sleep(3)
|
||||
assert await backoff_svc.call_async(async_backoff_callable) == "async foo"
|
||||
|
||||
|
||||
async def test_backoff_svc_raises_value_error_for_unknown_callable(backoff_svc):
|
||||
with pytest.raises(ValueError, match="not registered with backoff service"):
|
||||
backoff_svc.call(lambda: "foo")
|
||||
|
||||
|
||||
async def test_backoff_svc_raises_value_error_for_unknown_async_callable(backoff_svc):
|
||||
with pytest.raises(ValueError, match="not registered with backoff service"):
|
||||
await backoff_svc.call_async(lambda: "foo")
|
||||
|
||||
|
||||
async def test_backoff_svc_raises_value_error_for_async_called_from_sync(
|
||||
backoff_svc, backoff_callable
|
||||
):
|
||||
with pytest.raises(
|
||||
ValueError, match="Cannot call sync function with .call_async()"
|
||||
):
|
||||
await backoff_svc.call_async(backoff_callable)
|
||||
|
||||
|
||||
async def test_backoff_svc_raises_value_error_for_sync_called_from_async(
|
||||
backoff_svc, async_backoff_callable
|
||||
):
|
||||
with pytest.raises(ValueError, match="Cannot call async function with .call()"):
|
||||
backoff_svc.call(async_backoff_callable)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue