Repository: ExpressApp/pybotx (language: python)

Issue:
Бот падает при отправке пустого файла.
Привет.
Бот падает если отправить пустой файл. (до попадания в обработчик команд)
[test — копия.txt](https://github.com/ExpressApp/pybotx/files/13457620/test.txt)
```
  File ".../.venv/lib/python3.11/site-packages/pybotx/models/message/incoming_message.py", line 254, in to_domain
    attachment_domain = convert_api_attachment_to_domain(
                        └ <function convert_api_attachment_to_domain at 0x7f755384aa20>
  File ".../.venv/lib/python3.11/site-packages/pybotx/models/attachments.py", line 252, in convert_api_attachment_to_domain
    content = decode_rfc2397(api_attachment.data.content)
              │              │              │    └ ''
              │              │              └ BotAPIAttachmentDocumentData(content='', file_name='test — копия.txt')
              │              └ BotAPIAttachmentDocument(type=<APIAttachmentTypes.DOCUMENT: 'document'>, data=BotAPIAttachmentDocumentData(content='', file_n...
              └ <function decode_rfc2397 at 0x7f7553876b60>
  File ".../.venv/lib/python3.11/site-packages/pybotx/models/attachments.py", line 322, in decode_rfc2397
    return base64.b64decode(encoded_content.split(",", 1)[1].encode())
           │      │         │               └ <method 'split' of 'str' objects>
           │      │         └ ''
           │      └ <function b64decode at 0x7f75b26a3880>
           └ <module 'base64' from '/usr/lib64/python3.11/base64.py'>

IndexError: list index out of range
```

![image](https://github.com/ExpressApp/pybotx/assets/71669154/51442ef4-a764-4aec-b371-2eb2e69f87d3)

Бот падает при отправке пустого файла.
Привет.
Бот падает если отправить пустой файл. (до попадания в обработчик команд)
[test — копия.txt](https://github.com/ExpressApp/pybotx/files/13457620/test.txt)
```
  File ".../.venv/lib/python3.11/site-packages/pybotx/models/message/incoming_message.py", line 254, in to_domain
    attachment_domain = convert_api_attachment_to_domain(
                        └ <function convert_api_attachment_to_domain at 0x7f755384aa20>
  File ".../.venv/lib/python3.11/site-packages/pybotx/models/attachments.py", line 252, in convert_api_attachment_to_domain
    content = decode_rfc2397(api_attachment.data.content)
              │              │              │    └ ''
              │              │              └ BotAPIAttachmentDocumentData(content='', file_name='test — копия.txt')
              │              └ BotAPIAttachmentDocument(type=<APIAttachmentTypes.DOCUMENT: 'document'>, data=BotAPIAttachmentDocumentData(content='', file_n...
              └ <function decode_rfc2397 at 0x7f7553876b60>
  File ".../.venv/lib/python3.11/site-packages/pybotx/models/attachments.py", line 322, in decode_rfc2397
    return base64.b64decode(encoded_content.split(",", 1)[1].encode())
           │      │         │               └ <method 'split' of 'str' objects>
           │      │         └ ''
           │      └ <function b64decode at 0x7f75b26a3880>
           └ <module 'base64' from '/usr/lib64/python3.11/base64.py'>

IndexError: list index out of range
```

![image](https://github.com/ExpressApp/pybotx/assets/71669154/51442ef4-a764-4aec-b371-2eb2e69f87d3)



Discussion / hints:

Fix patch:
diff --git a/pybotx/models/attachments.py b/pybotx/models/attachments.py
index 30fe73a4..1a92488f 100644
--- a/pybotx/models/attachments.py
+++ b/pybotx/models/attachments.py
@@ -319,6 +319,9 @@ def convert_api_attachment_to_domain(  # noqa: WPS212
 
 def decode_rfc2397(encoded_content: str) -> bytes:
     # "data:image/gif;base64,aGVsbG8=" -> b"hello"
+    if not encoded_content:
+        return b""
+
     return base64.b64decode(encoded_content.split(",", 1)[1].encode())
 
 
diff --git a/pyproject.toml b/pyproject.toml
index 9e1baaca..2ac7ebf8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "pybotx"
-version = "0.61.0"
+version = "0.61.1"
 description = "A python library for interacting with eXpress BotX API"
 authors = [
     "Sidnev Nikolay <nsidnev@ccsteam.ru>",


Test patch:
diff --git a/tests/test_attachments.py b/tests/test_attachments.py
index 3585d3e3..f3fd15a3 100644
--- a/tests/test_attachments.py
+++ b/tests/test_attachments.py
@@ -306,3 +306,45 @@ async def test__async_execute_raw_bot_command__unknown_attachment_type(
 
     # - Assert -
     assert "Received unknown attachment type" in loguru_caplog.text
+
+
+async def test__async_execute_raw_bot_command__empty_attachment(
+    api_incoming_message_factory: Callable[..., Dict[str, Any]],
+    bot_account: BotAccountWithSecret,
+    loguru_caplog: pytest.LogCaptureFixture,
+) -> None:
+    # - Arrange -
+    empty_attachment = {
+        "data": {
+            "content": "",
+            "file_name": "empty_file.txt",
+        },
+        "type": "document",
+    }
+    payload = api_incoming_message_factory(attachment=empty_attachment)
+
+    collector = HandlerCollector()
+    incoming_message: Optional[IncomingMessage] = None
+
+    @collector.default_message_handler
+    async def default_handler(message: IncomingMessage, bot: Bot) -> None:
+        nonlocal incoming_message
+        incoming_message = message
+        # Drop `raw_command` from asserting
+        incoming_message.raw_command = None
+
+    built_bot = Bot(collectors=[collector], bot_accounts=[bot_account])
+
+    # - Act -
+    async with lifespan_wrapper(built_bot) as bot:
+        bot.async_execute_raw_bot_command(payload)
+
+    # - Assert -
+    assert incoming_message
+    assert incoming_message.file == AttachmentDocument(
+        type=AttachmentTypes.DOCUMENT,
+        filename="empty_file.txt",
+        size=0,
+        is_async_file=False,
+        content=b"",
+    )