diff --git a/composer.json b/composer.json
index 393b71ad6..cf2966ad2 100644
--- a/composer.json
+++ b/composer.json
@@ -112,7 +112,8 @@
"@docs",
"@docs-fix",
"@cs-fix",
- "@psalm"
+ "@psalm",
+ "@test-light"
],
"test": [
"@paratest"
diff --git a/src/TL/Conversion/BotAPI.php b/src/TL/Conversion/BotAPI.php
index e57e48494..7da1588f6 100644
--- a/src/TL/Conversion/BotAPI.php
+++ b/src/TL/Conversion/BotAPI.php
@@ -223,71 +223,6 @@ trait BotAPI
$newd = array_merge($newd, $this->MTProtoToBotAPI($data['media']));
}
return $newd;
- case 'messageEntityCustomEmoji':
- $data['type'] = 'custom_emoji';
- $data['custom_emoji_id'] = $data['document_id'];
- unset($data['_'], $data['document_id']);
- return $data;
- case 'messageEntityPhone':
- unset($data['_']);
- $data['type'] = 'phone_number';
- return $data;
- case 'messageEntityBlockquote':
- unset($data['_']);
- $data['type'] = 'block_quote';
- return $data;
- case 'messageEntityMention':
- unset($data['_']);
- $data['type'] = 'mention';
- return $data;
- case 'messageEntityHashtag':
- unset($data['_']);
- $data['type'] = 'hashtag';
- return $data;
- case 'messageEntityBotCommand':
- unset($data['_']);
- $data['type'] = 'bot_command';
- return $data;
- case 'messageEntityUrl':
- unset($data['_']);
- $data['type'] = 'url';
- return $data;
- case 'messageEntityEmail':
- unset($data['_']);
- $data['type'] = 'email';
- return $data;
- case 'messageEntityBold':
- unset($data['_']);
- $data['type'] = 'bold';
- return $data;
- case 'messageEntityStrike':
- unset($data['_']);
- $data['type'] = 'strikethrough';
- return $data;
- case 'messageEntitySpoiler':
- unset($data['_']);
- $data['type'] = 'spoiler';
- return $data;
- case 'messageEntityUnderline':
- unset($data['_']);
- $data['type'] = 'underline';
- return $data;
- case 'messageEntityItalic':
- unset($data['_']);
- $data['type'] = 'italic';
- return $data;
- case 'messageEntityCode':
- unset($data['_']);
- $data['type'] = 'code';
- return $data;
- case 'messageEntityPre':
- unset($data['_']);
- $data['type'] = 'pre';
- return $data;
- case 'messageEntityTextUrl':
- unset($data['_']);
- $data['type'] = 'text_url';
- return $data;
case 'messageEntityMentionName':
case 'inputMessageEntityMentionName':
unset($data['_']);
@@ -416,6 +351,81 @@ trait BotAPI
'mime_type' => 'application/octet-stream',
];
return ['encrypted' => $res];
+ default:
+ return self::MTProtoEntityToBotAPI($data);
+ }
+ }
+ /**
+ * @internal
+ */
+ public static function MTProtoEntityToBotAPI(array $data): array
+ {
+ switch ($data['_']) {
+ case 'messageEntityCustomEmoji':
+ $data['type'] = 'custom_emoji';
+ $data['custom_emoji_id'] = $data['document_id'];
+ unset($data['_'], $data['document_id']);
+ return $data;
+ case 'messageEntityPhone':
+ unset($data['_']);
+ $data['type'] = 'phone_number';
+ return $data;
+ case 'messageEntityBlockquote':
+ unset($data['_']);
+ $data['type'] = 'block_quote';
+ return $data;
+ case 'messageEntityMention':
+ unset($data['_']);
+ $data['type'] = 'mention';
+ return $data;
+ case 'messageEntityHashtag':
+ unset($data['_']);
+ $data['type'] = 'hashtag';
+ return $data;
+ case 'messageEntityBotCommand':
+ unset($data['_']);
+ $data['type'] = 'bot_command';
+ return $data;
+ case 'messageEntityUrl':
+ unset($data['_']);
+ $data['type'] = 'url';
+ return $data;
+ case 'messageEntityEmail':
+ unset($data['_']);
+ $data['type'] = 'email';
+ return $data;
+ case 'messageEntityBold':
+ unset($data['_']);
+ $data['type'] = 'bold';
+ return $data;
+ case 'messageEntityStrike':
+ unset($data['_']);
+ $data['type'] = 'strikethrough';
+ return $data;
+ case 'messageEntitySpoiler':
+ unset($data['_']);
+ $data['type'] = 'spoiler';
+ return $data;
+ case 'messageEntityUnderline':
+ unset($data['_']);
+ $data['type'] = 'underline';
+ return $data;
+ case 'messageEntityItalic':
+ unset($data['_']);
+ $data['type'] = 'italic';
+ return $data;
+ case 'messageEntityCode':
+ unset($data['_']);
+ $data['type'] = 'code';
+ return $data;
+ case 'messageEntityPre':
+ unset($data['_']);
+ $data['type'] = 'pre';
+ return $data;
+ case 'messageEntityTextUrl':
+ unset($data['_']);
+ $data['type'] = 'text_url';
+ return $data;
default:
throw new Exception(sprintf(Lang::$current_lang['botapi_conversion_error'], $data['_']));
}
diff --git a/src/TL/Conversion/DOMEntities.php b/src/TL/Conversion/DOMEntities.php
index 48a08eae6..39c46ca50 100644
--- a/src/TL/Conversion/DOMEntities.php
+++ b/src/TL/Conversion/DOMEntities.php
@@ -78,7 +78,9 @@ final class DOMEntities extends Entities
'i', 'em' => ['_' => 'messageEntityItalic'],
'code' => ['_' => 'messageEntityCode'],
'spoiler', 'tg-spoiler' => ['_' => 'messageEntitySpoiler'],
- 'pre' => ['_' => 'messageEntityPre', 'language' => $node->getAttribute('language')],
+ 'pre' => $node->hasAttribute('language')
+ ? ['_' => 'messageEntityPre', 'language' => $node->getAttribute('language')]
+ : ['_' => 'messageEntityPre'],
'tg-emoji' => ['_' => 'messageEntityCustomEmoji', 'document_id' => (int) $node->getAttribute('emoji-id')],
'emoji' => ['_' => 'messageEntityCustomEmoji', 'document_id' => (int) $node->getAttribute('id')],
'a' => self::handleLink($node->getAttribute('href')),
diff --git a/src/TL/Conversion/MarkdownEntities.php b/src/TL/Conversion/MarkdownEntities.php
index 1afb7d078..755eadbbe 100644
--- a/src/TL/Conversion/MarkdownEntities.php
+++ b/src/TL/Conversion/MarkdownEntities.php
@@ -149,15 +149,19 @@ final class MarkdownEntities extends Entities
$pieceLen--;
}
if ($pieceLen > 0) {
- $entities []= [
+ $tmp = [
'_' => match ($token) {
'```' => 'messageEntityPre',
'`' => 'messageEntityCode',
},
- 'language' => $language,
'offset' => $start,
'length' => $pieceLen,
];
+ if ($language !== null) {
+ $tmp['language'] = $language;
+ }
+ $entities []= $tmp;
+ unset($tmp);
}
$offset = $posClose+\strlen($token);
diff --git a/tests/danog/MadelineProto/EntitiesTest.php b/tests/danog/MadelineProto/EntitiesTest.php
index 1eaa951a4..7e0d49367 100644
--- a/tests/danog/MadelineProto/EntitiesTest.php
+++ b/tests/danog/MadelineProto/EntitiesTest.php
@@ -4,11 +4,15 @@ declare(strict_types=1);
namespace danog\MadelineProto\Test;
+use danog\MadelineProto\MTProto;
use danog\MadelineProto\StrTools;
+use danog\MadelineProto\TL\Conversion\DOMEntities;
+use danog\MadelineProto\TL\Conversion\MarkdownEntities;
use danog\MadelineProto\Tools;
+use PHPUnit\Framework\TestCase;
/** @internal */
-class EntitiesTest extends MadelineTestCase
+class EntitiesTest extends TestCase
{
public function testMb(): void
{
@@ -27,40 +31,63 @@ class EntitiesTest extends MadelineTestCase
$this->assertEquals(['aπ', 'aπ'], StrTools::mbStrSplit('aπaπ', 3));
$this->assertEquals(['πΊπ¦', 'πΊπ¦'], StrTools::mbStrSplit('πΊπ¦πΊπ¦', 4));
}
+ private static function sendMessage(string $message, string $parse_mode): DOMEntities|MarkdownEntities
+ {
+ return match ($parse_mode) {
+ 'html' => (new DOMEntities($message)),
+ 'markdown' => (new MarkdownEntities($message)),
+ };
+ }
+ private static function MTProtoToBotAPI(DOMEntities|MarkdownEntities $entities): array
+ {
+ $result = ['text' => $entities->message];
+ $entities = $entities->entities;
+ foreach ($entities as &$entity) {
+ switch ($entity['_']) {
+ case 'messageEntityMentionName':
+ case 'inputMessageEntityMentionName':
+ unset($entity['_']);
+ $entity['type'] = 'text_mention';
+ $entity['user'] = $entity['user_id'];
+ unset($entity['user_id']);
+ break;
+ default:
+ $entity = MTProto::MTProtoEntityToBotAPI($entity);
+ }
+ }
+ $result['entities'] = $entities;
+ return $result;
+ }
/**
* @dataProvider provideEntities
*/
public function testEntities(string $mode, string $html, string $bare, array $entities, ?string $htmlReverse = null): void
{
- $resultMTProto = self::$MadelineProto->messages->sendMessage(peer: getenv('DEST'), message: $html, parse_mode: $mode);
- $resultMTProto = self::$MadelineProto->extractMessage($resultMTProto);
- $result = self::$MadelineProto->MTProtoToBotAPI($resultMTProto);
+ $resultMTProto = self::sendMessage(message: $html, parse_mode: $mode);
+ $result = self::MTProtoToBotAPI($resultMTProto);
$this->assertEquals($bare, $result['text']);
$this->assertEquals($entities, $result['entities']);
if (strtolower($mode) === 'html') {
$this->assertEquals(
str_replace(['
', ' ', 'mention:'], ['
', ' ', 'tg://user?id='], $htmlReverse ?? $html),
StrTools::entitiesToHtml(
- $resultMTProto['message'],
- $resultMTProto['entities'],
+ $resultMTProto->message,
+ $resultMTProto->entities,
true
),
);
- $resultMTProto = self::$MadelineProto->messages->sendMessage(peer: getenv('DEST'), message: StrTools::htmlEscape($html), parse_mode: $mode);
- $resultMTProto = self::$MadelineProto->extractMessage($resultMTProto);
- $result = self::$MadelineProto->MTProtoToBotAPI($resultMTProto);
+ $resultMTProto = self::sendMessage(message: StrTools::htmlEscape($html), parse_mode: $mode);
+ $result = self::MTProtoToBotAPI($resultMTProto);
$this->assertEquals($html, $result['text']);
$this->assertNoRelevantEntities($result['entities']);
} else {
- $resultMTProto = self::$MadelineProto->messages->sendMessage(peer: getenv('DEST'), message: Tools::markdownEscape($html), parse_mode: $mode);
- $resultMTProto = self::$MadelineProto->extractMessage($resultMTProto);
- $result = self::$MadelineProto->MTProtoToBotAPI($resultMTProto);
+ $resultMTProto = self::sendMessage(message: Tools::markdownEscape($html), parse_mode: $mode);
+ $result = self::MTProtoToBotAPI($resultMTProto);
$this->assertEquals($html, $result['text']);
$this->assertNoRelevantEntities($result['entities']);
- $resultMTProto = self::$MadelineProto->messages->sendMessage(peer: getenv('DEST'), message: "```\n".Tools::markdownCodeblockEscape($html)."\n```", parse_mode: $mode);
- $resultMTProto = self::$MadelineProto->extractMessage($resultMTProto);
- $result = self::$MadelineProto->MTProtoToBotAPI($resultMTProto);
+ $resultMTProto = self::sendMessage(message: "```\n".Tools::markdownCodeblockEscape($html)."\n```", parse_mode: $mode);
+ $result = self::MTProtoToBotAPI($resultMTProto);
$this->assertEquals($html, rtrim($result['text']));
$result['entities'][0]['language'] = ''; // Telegram now has automatic language detection
$this->assertEquals([['offset' => 0, 'length' => StrTools::mbStrlen($html), 'language' => '', 'type' => 'pre']], $result['entities']);
@@ -79,7 +106,6 @@ class EntitiesTest extends MadelineTestCase
public function provideEntities(): array
{
$this->setUpBeforeClass();
- $mention = self::$MadelineProto->getPwrChat(getenv('TEST_USERNAME'), false);
return [
[
'html',
@@ -179,7 +205,7 @@ class EntitiesTest extends MadelineTestCase
],
[
'html',
- 'test
test test
testtest
blockquotehttps://google.com daniil@daniil.it +39398172758722 @daniilgentili
test
testtest
blockquotehttps://google.com daniil@daniil.it +39398172758722 @daniilgentili
test
testtest
blockquotehttps://google.com daniil@daniil.it +39398172758722 @daniilgentili
test
testtest
blockquotehttps://google.com daniil@daniil.it +39398172758722 @daniilgentili