diff --git a/CHANGELOG.md b/CHANGELOG.md index bfe1077..824bc2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ > Changes to public API is marked as `^` +- v4.1.5 + - Fixed `.send_message` with long messages. + - Fixed `.reply` with non-str argument. + - Fixed `.body` with command and multiline body. + - v4.1.4 - Fixed bugs in windows diff --git a/kutana/backends/vkontakte/backend.py b/kutana/backends/vkontakte/backend.py index dd3d96c..1cd9602 100644 --- a/kutana/backends/vkontakte/backend.py +++ b/kutana/backends/vkontakte/backend.py @@ -159,6 +159,9 @@ async def resolve_screen_name(self, screen_name): {"screen_name": screen_name} ) + if not result: + return {} + if len(NAIVE_CACHE) >= 500_000: NAIVE_CACHE.clear() diff --git a/kutana/context.py b/kutana/context.py index 3e83578..ad6256a 100644 --- a/kutana/context.py +++ b/kutana/context.py @@ -112,6 +112,8 @@ def split_large_text(text, length=4096): :returns: tuple of chunks """ + text = str(text) + yield text[0: length] for i in range(length, len(text), length): @@ -159,7 +161,7 @@ async def send_message(self, target_id, message, attachments=(), **kwargs): target_id, part, (), - None, + {}, )) responses.append(await self.backend.perform_send( diff --git a/kutana/routers.py b/kutana/routers.py index 5c57230..4c03dd3 100644 --- a/kutana/routers.py +++ b/kutana/routers.py @@ -16,7 +16,7 @@ def _populate_cache(self, ctx): prefixes = ctx.config["prefixes"] self._cache = re.compile( - pattern=r"({prefix})({command})($|\s.*)".format( + pattern=r"({prefix})({command})(?:$|\s([\s\S]*))".format( prefix="|".join(re.escape(p) for p in prefixes), command="|".join(re.escape(c) for c in commands), ), diff --git a/setup.py b/setup.py index d8e9015..ab8e7b2 100644 --- a/setup.py +++ b/setup.py @@ -8,7 +8,7 @@ import setuptools -VERSION = "4.1.4" +VERSION = "4.1.5" with open("README.md", "r") as fh: diff --git a/tests/test_context.py b/tests/test_context.py index 2a21d9a..a19399a 100644 --- a/tests/test_context.py +++ b/tests/test_context.py @@ -1,8 +1,16 @@ import asyncio import pytest +from asynctest import MagicMock, CoroutineMock from kutana import Context +def test_reply_non_str(): + ctx = Context(backend=MagicMock(perform_send=CoroutineMock())) + ctx.default_target_id = 1 + asyncio.get_event_loop().run_until_complete(ctx.reply(123)) + ctx.backend.perform_send.assert_called_with(1, '123', (), {}) + + def test_context(): called = [] @@ -39,6 +47,16 @@ async def perform_api_call(self, method, kwargs): ] +def test_lont_message_for_kwargs(): + ctx = Context(backend=CoroutineMock(perform_send=CoroutineMock())) + ctx.default_target_id = 1 + + asyncio.get_event_loop().run_until_complete(ctx.reply("a" * (4096 * 2 - 1))) + + ctx.backend.perform_send.assert_any_await(1, "a" * 4096, (), {}) + ctx.backend.perform_send.assert_any_await(1, "a" * 4095, (), {}) + + def test_dynamic_attributes(): ctx = Context() diff --git a/tests/test_plugin.py b/tests/test_plugin.py index 9fe7056..3f87bd2 100644 --- a/tests/test_plugin.py +++ b/tests/test_plugin.py @@ -121,6 +121,22 @@ async def _(msg, ctx): assert debug.answers[1][2] == (".echo", (), {}) assert debug.answers[1][3] == (".ec\n123", (), {}) +def test_command_full_body(): + app, debug, hu = make_kutana_no_run() + + pl = Plugin("") + + @pl.on_commands(["echo"]) + async def _(msg, ctx): + await ctx.reply(ctx.body) + + app.add_plugin(pl) + + hu(Message(None, UpdateType.MSG, ".echo abc\nabc\nabc", (), 1, 0, 0, 0)) + + assert len(debug.answers[1]) == 1 + assert debug.answers[1][0] == ("abc\nabc\nabc", (), {}) + def test_attachments(): app, debug, hu = make_kutana_no_run() diff --git a/tests/test_vkontakte.py b/tests/test_vkontakte.py index 90ab124..365d7ce 100644 --- a/tests/test_vkontakte.py +++ b/tests/test_vkontakte.py @@ -108,6 +108,16 @@ async def test(): asyncio.get_event_loop().run_until_complete(test()) +@patch("kutana.backends.Vkontakte._request") +def test_resolve_screen_name_empty(mock_request): + mock_request.return_value = [] + + async def test(): + vkontakte = Vkontakte(token="token", session=aiohttp.ClientSession()) + assert await vkontakte.resolve_screen_name("asdjfgakyuhagkuf") == {} + asyncio.get_event_loop().run_until_complete(test()) + + @patch("aiohttp.ClientSession.post") def test_perform_updates_request(mock_post): def make_mock(exc):