149 lines
4 KiB
Python
149 lines
4 KiB
Python
import types
|
|
|
|
import pytest
|
|
|
|
from huesoporro.bot import SaveMessagesCog
|
|
|
|
|
|
class DummyDB:
|
|
def __init__(self, *args, **kwargs):
|
|
pass
|
|
|
|
|
|
class FakeChannel:
|
|
def __init__(self):
|
|
self.sent: list[str] = []
|
|
|
|
async def send(self, content: str):
|
|
self.sent.append(content)
|
|
|
|
|
|
class FakeAuthor:
|
|
def __init__(self, name: str):
|
|
self.name = name
|
|
|
|
|
|
class FakeMessage:
|
|
def __init__(self, content: str | None, author_name: str = "alice"):
|
|
self.content = content
|
|
self.author = FakeAuthor(author_name)
|
|
self.channel = FakeChannel()
|
|
|
|
|
|
class FakeBot:
|
|
def __init__(self, nick: str = "Junie", channel: str = "testchan"):
|
|
self.nick = nick
|
|
self.channel = channel
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def patch_markov_and_svcs(monkeypatch):
|
|
monkeypatch.setattr("huesoporro.bot.MarkovDatabase", DummyDB)
|
|
|
|
class _DummyStoreSvc:
|
|
def __init__(self, db):
|
|
self.db = db
|
|
|
|
async def run(self, content: str | None):
|
|
return None
|
|
|
|
class _DummyGenSvc:
|
|
def __init__(self, db):
|
|
self.db = db
|
|
|
|
async def run(self, seed: str):
|
|
return None
|
|
|
|
monkeypatch.setattr("huesoporro.bot.SentenceStorerSvc", _DummyStoreSvc)
|
|
monkeypatch.setattr("huesoporro.bot.SentenceGeneratorSvc", _DummyGenSvc)
|
|
|
|
|
|
@pytest.fixture
|
|
def cog(monkeypatch) -> SaveMessagesCog:
|
|
bot = FakeBot()
|
|
return SaveMessagesCog(bot) # type: ignore[arg-type]
|
|
|
|
|
|
def make_async_fn(result=None, exc: Exception | None = None):
|
|
async def _fn(*args, **kwargs):
|
|
if exc:
|
|
raise exc
|
|
return result
|
|
|
|
return _fn
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_handle_bot_mention_returns_none_on_empty_content(cog: SaveMessagesCog):
|
|
msg = FakeMessage(content=None)
|
|
res = await cog._handle_bot_mention(msg) # type: ignore[attr-defined]
|
|
assert res is None
|
|
assert msg.channel.sent == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_handle_bot_mention_returns_none_when_no_mention(cog: SaveMessagesCog):
|
|
msg = FakeMessage(content="hello world")
|
|
res = await cog._handle_bot_mention(msg) # type: ignore[attr-defined]
|
|
assert res is None
|
|
assert msg.channel.sent == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_handle_bot_mention_returns_none_when_only_mention(
|
|
cog: SaveMessagesCog, monkeypatch
|
|
):
|
|
msg = FakeMessage(content=cog.bot.nick) # type: ignore[attr-defined]
|
|
res = await cog._handle_bot_mention(msg) # type: ignore[attr-defined]
|
|
assert res is None
|
|
assert msg.channel.sent == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_handle_bot_mention_generates_and_sends_reply(
|
|
cog: SaveMessagesCog, monkeypatch
|
|
):
|
|
msg = FakeMessage(content="juNie hello there")
|
|
|
|
monkeypatch.setattr(
|
|
cog, "generate_svc", types.SimpleNamespace(run=make_async_fn("foo bar"))
|
|
)
|
|
|
|
res = await cog._handle_bot_mention(msg) # type: ignore[attr-defined]
|
|
|
|
assert res == "foo bar"
|
|
assert len(msg.channel.sent) == 1
|
|
assert msg.channel.sent[0].startswith(f"@{msg.author.name} ")
|
|
assert msg.channel.sent[0].endswith("foo bar")
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_handle_bot_mention_no_send_when_generator_returns_none(
|
|
cog: SaveMessagesCog, monkeypatch
|
|
):
|
|
msg = FakeMessage(content=f"{cog.bot.nick} hello") # type: ignore[attr-defined]
|
|
|
|
monkeypatch.setattr(
|
|
cog, "generate_svc", types.SimpleNamespace(run=make_async_fn(None))
|
|
)
|
|
|
|
res = await cog._handle_bot_mention(msg) # type: ignore[attr-defined]
|
|
assert res is None
|
|
assert msg.channel.sent == []
|
|
|
|
|
|
@pytest.mark.asyncio
|
|
async def test_handle_bot_mention_swallows_exceptions_and_returns_none(
|
|
cog: SaveMessagesCog, monkeypatch
|
|
):
|
|
msg = FakeMessage(content=f"{cog.bot.nick} hello") # type: ignore[attr-defined]
|
|
|
|
monkeypatch.setattr(
|
|
cog,
|
|
"generate_svc",
|
|
types.SimpleNamespace(run=make_async_fn(exc=RuntimeError("boom"))),
|
|
)
|
|
|
|
res = await cog._handle_bot_mention(msg) # type: ignore[attr-defined]
|
|
assert res is None
|
|
assert msg.channel.sent == []
|