Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion pybotx/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
ChatCreationError,
ChatCreationProhibitedError,
InvalidUsersListError,
ThreadAlreadyExistsError,
ThreadCreationError,
ThreadCreationProhibitedError,
)
Expand Down Expand Up @@ -264,8 +265,8 @@
"SyncSmartAppEventHandlerFunc",
"SyncSmartAppEventHandlerNotFoundError",
"SyncSourceTypes",
"ThreadAlreadyExistsError",
"ThreadCreationError",
"ThreadCreationEventNotFoundError",
"ThreadCreationProhibitedError",
"UnknownBotAccountError",
"UnknownSystemEventError",
Expand Down
16 changes: 14 additions & 2 deletions pybotx/client/chats_api/create_thread.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
from typing import Literal
from typing import Literal, NoReturn
from uuid import UUID

import httpx

from pybotx.client.authorized_botx_method import AuthorizedBotXMethod
from pybotx.client.botx_method import response_exception_thrower
from pybotx.client.exceptions.chats import (
ThreadAlreadyExistsError,
ThreadCreationError,
ThreadCreationProhibitedError,
)
Expand Down Expand Up @@ -31,12 +34,21 @@ def to_domain(self) -> UUID:
return self.result.thread_id


def conflict_error_handler(response: httpx.Response) -> NoReturn:
reason = response.json().get("reason")

if reason == "thread_already_created":
raise ThreadAlreadyExistsError.from_response(response)

raise ThreadCreationError.from_response(response)


class CreateThreadMethod(AuthorizedBotXMethod):
status_handlers = {
**AuthorizedBotXMethod.status_handlers,
403: response_exception_thrower(ThreadCreationProhibitedError),
404: response_exception_thrower(EventNotFoundError),
422: response_exception_thrower(ThreadCreationError),
409: conflict_error_handler,
}

async def execute(
Expand Down
14 changes: 8 additions & 6 deletions pybotx/client/exceptions/chats.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,24 @@ class ChatCreationError(BaseClientError):
"""Error while chat creation."""


class ThreadAlreadyExistsError(BaseClientError):
"""Thread is already exists."""


class ThreadCreationError(BaseClientError):
"""Error while thread creation (invalid scheme)."""
"""Creating a thread for a deleted message."""


class ThreadCreationProhibitedError(BaseClientError):
"""
Error while permission checks.

1. Bot has no permissions to create thread
2. Threads are not allowed for that message
2. Threads are not allowed for this chat
3. Bot is not a chat member where message is located
4. Message is located in personal chat
5. Usupported event type
6. Unsuppoerted chat type
7. Thread is already created
8. No access for message
9. Message in stealth mode
10. Message is deleted
7. No access for message
8. Message in stealth mode
"""
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "pybotx"
version = "0.75.4"
version = "0.75.5"
description = "A python library for interacting with eXpress BotX API"
authors = [
"Sidnev Nikolay <nsidnev@ccsteam.ru>",
Expand Down
45 changes: 18 additions & 27 deletions tests/client/chats_api/test_create_thread.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from collections.abc import Callable
from http import HTTPStatus
from typing import Any, Callable
from typing import Any
from uuid import UUID

import httpx
Expand All @@ -12,6 +13,7 @@
BotAccountWithSecret,
EventNotFoundError,
HandlerCollector,
ThreadAlreadyExistsError,
ThreadCreationError,
ThreadCreationProhibitedError,
lifespan_wrapper,
Expand Down Expand Up @@ -57,11 +59,10 @@ async def test__create_thread__succeed(
bot_account: BotAccountWithSecret,
) -> None:
# - Arrange -
thread_id = "2a8c0d1e-c4d1-4308-b024-6e1a9f4a4b6d"
endpoint = create_mocked_endpoint(
{
"status": "ok",
"result": {"thread_id": thread_id},
"result": {"thread_id": sync_id},
},
HTTPStatus.OK,
)
Expand All @@ -76,7 +77,7 @@ async def test__create_thread__succeed(
)

# - Assert -
assert str(created_thread_id) == thread_id
assert str(created_thread_id) == sync_id
assert endpoint.called


Expand Down Expand Up @@ -143,16 +144,6 @@ async def test__create_thread__succeed(
HTTPStatus.FORBIDDEN,
ThreadCreationProhibitedError,
),
(
{
"status": "error",
"reason": "thread_already_created",
"errors": ["Thread already created"],
"error_data": {"bot_id": "24348246-6791-4ac0-9d86-b948cd6a0e46"},
},
HTTPStatus.FORBIDDEN,
ThreadCreationProhibitedError,
),
(
{
"status": "error",
Expand All @@ -176,32 +167,32 @@ async def test__create_thread__succeed(
(
{
"status": "error",
"reason": "event_already_deleted",
"errors": ["This event already deleted"],
"reason": "event_not_found",
"errors": ["Event not found"],
"error_data": {"bot_id": "24348246-6791-4ac0-9d86-b948cd6a0e46"},
},
HTTPStatus.FORBIDDEN,
ThreadCreationProhibitedError,
HTTPStatus.NOT_FOUND,
EventNotFoundError,
),
(
{
"status": "error",
"reason": "event_not_found",
"errors": ["Event not found"],
"reason": "event_already_deleted",
"errors": ["This event already deleted"],
"error_data": {"bot_id": "24348246-6791-4ac0-9d86-b948cd6a0e46"},
},
HTTPStatus.NOT_FOUND,
EventNotFoundError,
HTTPStatus.CONFLICT,
ThreadCreationError,
),
(
{
"status": "error",
"reason": "|specified reason|",
"errors": ["|specified errors|"],
"error_data": {},
"reason": "thread_already_created",
"errors": ["Thread already created"],
"error_data": {"bot_id": "24348246-6791-4ac0-9d86-b948cd6a0e46"},
},
HTTPStatus.UNPROCESSABLE_ENTITY,
ThreadCreationError,
HTTPStatus.CONFLICT,
ThreadAlreadyExistsError,
),
(
{
Expand Down
Loading