diff --git a/CHANGES/1259.bugfix.rst b/CHANGES/1259.bugfix.rst new file mode 100644 index 00000000..e070549d --- /dev/null +++ b/CHANGES/1259.bugfix.rst @@ -0,0 +1 @@ +Fixed nested hashtag, cashtag and email message entities not being parsed correctly when these entities are inside another entity. diff --git a/aiogram/utils/text_decorations.py b/aiogram/utils/text_decorations.py index 97430a32..eaff6f2c 100644 --- a/aiogram/utils/text_decorations.py +++ b/aiogram/utils/text_decorations.py @@ -43,8 +43,11 @@ class TextDecoration(ABC): MessageEntityType.URL, MessageEntityType.MENTION, MessageEntityType.PHONE_NUMBER, + MessageEntityType.HASHTAG, + MessageEntityType.CASHTAG, + MessageEntityType.EMAIL, }: - # This entities should not be changed + # These entities should not be changed return text if entity.type in { MessageEntityType.BOLD, @@ -71,6 +74,8 @@ class TextDecoration(ABC): if entity.type == MessageEntityType.CUSTOM_EMOJI: return self.custom_emoji(value=text, custom_emoji_id=cast(str, entity.custom_emoji_id)) + # This case is not possible because of `if` above, but if any new entity is added to + # API it will be here too return self.quote(text) def unparse(self, text: str, entities: Optional[List[MessageEntity]] = None) -> str: diff --git a/tests/test_utils/test_text_decorations.py b/tests/test_utils/test_text_decorations.py index 056bd1cb..25f222f0 100644 --- a/tests/test_utils/test_text_decorations.py +++ b/tests/test_utils/test_text_decorations.py @@ -113,6 +113,14 @@ class TestTextDecoration: ): assert decorator.apply_entity(entity, "test") == result + def test_unknown_apply_entity(self): + assert ( + html_decoration.apply_entity( + MessageEntity(type="unknown", offset=0, length=5), "" + ) + == "<test>" + ) + @pytest.mark.parametrize( "decorator,before,after", [ @@ -243,6 +251,33 @@ class TestTextDecoration: [MessageEntity(type="bold", offset=0, length=8, url=None, user=None)], "👋🏾 Hi!", ], + [ + html_decoration, + "#test", + [ + MessageEntity(type="hashtag", offset=0, length=5), + MessageEntity(type="bold", offset=0, length=5), + ], + "#test", + ], + [ + html_decoration, + "$TEST", + [ + MessageEntity(type="cashtag", offset=0, length=5), + MessageEntity(type="bold", offset=0, length=5), + ], + "$TEST", + ], + [ + html_decoration, + "test@example.com", + [ + MessageEntity(type="email", offset=0, length=16), + MessageEntity(type="bold", offset=0, length=16), + ], + "test@example.com", + ], ], ) def test_unparse(