diff --git a/src/pymax/types/domain/message.py b/src/pymax/types/domain/message.py index cd758bc..ed35ce5 100644 --- a/src/pymax/types/domain/message.py +++ b/src/pymax/types/domain/message.py @@ -108,13 +108,13 @@ class ReplyLink(MessageLink): :ivar message: Сообщение, на которое ответили. :vartype message: Message - :ivar chat_id: ID чата исходного сообщения. - :vartype chat_id: int + :ivar chat_id: ID чата исходного сообщения, если сервер его прислал. + :vartype chat_id: int | None """ type: Literal[LinkType.REPLY] = LinkType.REPLY message: Message - chat_id: int + chat_id: int | None = None class ForwardLink(MessageLink): @@ -126,13 +126,13 @@ class ForwardLink(MessageLink): :ivar message: Исходное сообщение. :vartype message: Message - :ivar chat_id: ID исходного чата. - :vartype chat_id: int + :ivar chat_id: ID исходного чата, если сервер его прислал. + :vartype chat_id: int | None """ type: Literal[LinkType.FORWARD] = LinkType.FORWARD message: Message - chat_id: int + chat_id: int | None = None chat_name: str | None = None chat_link: str | None = None chat_access_type: AccessType | None = None diff --git a/tests/domain/test_message_models.py b/tests/domain/test_message_models.py index baf57a9..5d0dece 100644 --- a/tests/domain/test_message_models.py +++ b/tests/domain/test_message_models.py @@ -2,6 +2,7 @@ from pymax.types.domain import ( AudioAttachment, + LinkType, Message, PollAttachment, UnknownAttachment, @@ -139,3 +140,48 @@ def test_message_elements_accept_missing_length_and_attribute_url() -> None: assert element.length is None assert element.attributes is not None assert element.attributes.url is None + + +def test_message_link_reply_without_chat_id_is_accepted() -> None: + """Сервер может прислать reply без chatId в link — сообщение не должно + отбрасываться целиком из-за одного необязательного поля.""" + payload = message_payload(1, 100) + payload["link"] = { + "type": "REPLY", + "message": message_payload(5, 100, text="quoted"), + } + + message = Message.model_validate(payload) + + assert message.link is not None + assert message.link.type == LinkType.REPLY + assert message.link.chat_id is None + assert message.link.message.text == "quoted" + + +def test_message_link_forward_without_chat_id_is_accepted() -> None: + payload = message_payload(1, 100) + payload["link"] = { + "type": "FORWARD", + "message": message_payload(6, 100, text="fwd"), + } + + message = Message.model_validate(payload) + + assert message.link is not None + assert message.link.type == LinkType.FORWARD + assert message.link.chat_id is None + + +def test_message_link_with_chat_id_unchanged() -> None: + payload = message_payload(1, 100) + payload["link"] = { + "type": "REPLY", + "message": message_payload(5, 100), + "chatId": 200, + } + + message = Message.model_validate(payload) + + assert message.link is not None + assert message.link.chat_id == 200