mirror of
https://github.com/agessaman/meshcore-bot.git
synced 2026-11-04 03:52:34 +00:00
The two commands carried near-identical copies of fetch-until-short, split-at-a-natural-break and two-part send. modules/joke_text.py now holds them as plain functions (a mixin module under modules/commands would be loaded as a plugin and recorded as a failure). Each command keeps its public method names, its emoji, its own split points (joke also splits on newlines) and its own pause: joke still waits 2 s between the two parts, dadjoke does not. Lengths stay counted in characters against 130, as before.
46 lines
2.2 KiB
Python
46 lines
2.2 KiB
Python
"""modules.joke_text: fetch-until-short, split, and two-part send."""
|
|
|
|
from unittest.mock import AsyncMock, Mock, patch
|
|
|
|
from modules.joke_text import JOKE_CHAR_LIMIT, fetch_fitting_joke, send_joke, split_joke_text
|
|
|
|
LONG = "x" * (JOKE_CHAR_LIMIT + 5)
|
|
|
|
|
|
async def test_fetch_retries_until_short_unless_long_allowed():
|
|
fetch = AsyncMock(side_effect=[{"t": LONG}, {"t": "short"}])
|
|
fmt = lambda d: d["t"] # noqa: E731
|
|
assert await fetch_fitting_joke(fetch, fmt, allow_long=False, logger=Mock(), label="joke") == {"t": "short"}
|
|
fetch = AsyncMock(return_value={"t": LONG})
|
|
assert await fetch_fitting_joke(fetch, fmt, allow_long=True, logger=Mock(), label="joke") == {"t": LONG}
|
|
assert fetch.await_count == 1
|
|
|
|
|
|
async def test_fetch_gives_up_with_the_last_long_joke_or_none():
|
|
logger = Mock()
|
|
fetch = AsyncMock(return_value={"t": LONG})
|
|
got = await fetch_fitting_joke(fetch, lambda d: d["t"], allow_long=False, logger=logger, label="dad joke")
|
|
assert got == {"t": LONG} and fetch.await_count == 5
|
|
logger.warning.assert_called_once_with("Could not get short dad joke after 5 attempts")
|
|
assert await fetch_fitting_joke(AsyncMock(return_value=None), str, allow_long=False, logger=logger, label="j") is None
|
|
|
|
|
|
def test_split_prefers_listed_points_then_middle_space():
|
|
assert split_joke_text("🎭 Why? Because.", "🎭", ("? ",)) == ["🎭 Why? ", "🎭 Because."]
|
|
assert split_joke_text("🥸 aaaa bbbb cccc", "🥸", ()) == ["🥸 aaaa bbbb", "🥸 cccc"]
|
|
|
|
|
|
async def test_send_splits_long_jokes_and_pauses_only_when_asked():
|
|
send = AsyncMock()
|
|
long_joke = "🎭 " + "a" * 100 + ". " + "b" * 100
|
|
with patch("modules.joke_text.asyncio.sleep", AsyncMock()) as sleep:
|
|
await send_joke(send, "msg", long_joke, lambda t: split_joke_text(t, "🎭", (". ",)), pause_seconds=2.0)
|
|
sleep.assert_awaited_once_with(2.0)
|
|
assert send.await_count == 2
|
|
assert send.await_args_list[1].kwargs == {"skip_user_rate_limit": True}
|
|
send = AsyncMock()
|
|
with patch("modules.joke_text.asyncio.sleep", AsyncMock()) as sleep:
|
|
await send_joke(send, "msg", "🥸 short", lambda t: [t])
|
|
sleep.assert_not_awaited()
|
|
send.assert_awaited_once_with("msg", "🥸 short")
|