diff --git a/composer.json b/composer.json
index 227ca73e..6cf0763a 100644
--- a/composer.json
+++ b/composer.json
@@ -40,6 +40,8 @@
"phpunit/phpunit": "^8",
"amphp/php-cs-fixer-config": "dev-master",
"haydenpierce/class-finder": "^0.4",
+ "amphp/websocket-client": "dev-master as 1",
+ "amphp/websocket": "dev-master as 1",
"ext-ctype": "*",
"danog/7to70": "^1",
"danog/7to5": "^1"
@@ -62,6 +64,11 @@
"src/polyfill.php"
]
},
+ "autoload-dev": {
+ "psr-4": {
+ "danog\\MadelineProto\\Test\\": "tests/danog/"
+ }
+ },
"repositories": [{
"type": "git",
"url": "https://github.com/danog/dns"
@@ -80,6 +87,6 @@
"cs": "PHP_CS_FIXER_IGNORE_ENV=1 php-cs-fixer fix -v --diff --dry-run",
"cs-fix": "PHP_CS_FIXER_IGNORE_ENV=1 php-cs-fixer fix -v --diff",
"docs": "php tools/build_docs.php",
- "test": "@php -dzend.assertions=1 -dassert.exception=1 ./vendor/bin/phpunit --coverage-text"
+ "test": "@php -dzend.assertions=1 -dassert.exception=1 ./vendor/bin/phpunit --coverage-text --config tests/phpunit.xml"
}
}
diff --git a/src/danog/MadelineProto/Connection.php b/src/danog/MadelineProto/Connection.php
index 5ec53e7e..1d73927e 100644
--- a/src/danog/MadelineProto/Connection.php
+++ b/src/danog/MadelineProto/Connection.php
@@ -466,7 +466,7 @@ class Connection extends Session
*
* @return void
*/
- public function setExtra(DataCenterConnection $extra, int $id)
+ public function setExtra($extra, int $id)
{
$this->shared = $extra;
$this->id = $id;
@@ -478,7 +478,7 @@ class Connection extends Session
*
* @return MTProto
*/
- public function getExtra(): MTProto
+ public function getExtra()
{
return $this->API;
}
diff --git a/src/danog/MadelineProto/DataCenterConnection.php b/src/danog/MadelineProto/DataCenterConnection.php
index 9276f66b..2e1c915a 100644
--- a/src/danog/MadelineProto/DataCenterConnection.php
+++ b/src/danog/MadelineProto/DataCenterConnection.php
@@ -597,7 +597,7 @@ class DataCenterConnection implements JsonSerializable
*
* @return void
*/
- public function setExtra(MTProto $API)
+ public function setExtra($API)
{
$this->API = $API;
}
@@ -606,7 +606,7 @@ class DataCenterConnection implements JsonSerializable
*
* @return MTProto
*/
- public function getExtra(): MTProto
+ public function getExtra()
{
return $this->API;
}
diff --git a/src/danog/MadelineProto/MTProtoSession/CallHandler.php b/src/danog/MadelineProto/MTProtoSession/CallHandler.php
index 6edb2f30..b91f987c 100644
--- a/src/danog/MadelineProto/MTProtoSession/CallHandler.php
+++ b/src/danog/MadelineProto/MTProtoSession/CallHandler.php
@@ -87,20 +87,21 @@ trait CallHandler
public function methodCallAsyncRead(string $method, $args = [], array $aargs = ['msg_id' => null]): Promise
{
$deferred = new Deferred();
- $this->methodCallAsyncWrite($method, $args, $aargs)->onResolve(function ($e, $read_deferred) use ($deferred) {
- if ($e) {
- $deferred->fail($e);
- } else {
- if (\is_array($read_deferred)) {
- $read_deferred = \array_map(function ($value) {
- return $value->promise();
- }, $read_deferred);
- $deferred->resolve(all($read_deferred));
+ $this->methodCallAsyncWrite($method, $args, $aargs)->onResolve(
+ static function (\Throwable $e, $readDeferred) use ($deferred): void {
+ if ($e) {
+ $deferred->fail($e);
} else {
- $deferred->resolve($read_deferred->promise());
+ if (\is_array($readDeferred)) {
+ $readDeferred = \array_map(fn (Deferred $value) => $value->promise(), $readDeferred);
+ $deferred->resolve(all($readDeferred));
+ } else {
+ $readDeferred->promise()->onResolve(fn(\Throwable $e, $res) => var_dump($e, $res));
+ $deferred->resolve($readDeferred->promise());
+ }
}
}
- });
+ );
return $aargs['noResponse'] ?? false ? new Success() : $deferred->promise();
}
/**
diff --git a/src/danog/MadelineProto/Stream/MTProtoTransport/FullStream.php b/src/danog/MadelineProto/Stream/MTProtoTransport/FullStream.php
index a92178d6..6aa2adee 100644
--- a/src/danog/MadelineProto/Stream/MTProtoTransport/FullStream.php
+++ b/src/danog/MadelineProto/Stream/MTProtoTransport/FullStream.php
@@ -46,9 +46,9 @@ class FullStream implements BufferedStreamInterface, MTProtoBufferInterface
*
* @param ConnectionContext $ctx
*
- * @return Promise
+ * @return \Generator
*/
- public function connect(ConnectionContext $ctx, string $header = ''): Promise
+ public function connect(ConnectionContext $ctx, string $header = ''): \Generator
{
$this->in_seq_no = -1;
$this->out_seq_no = -1;
diff --git a/src/danog/MadelineProto/Stream/Transport/WsStream.php b/src/danog/MadelineProto/Stream/Transport/WsStream.php
index d22c6996..217c4ba9 100644
--- a/src/danog/MadelineProto/Stream/Transport/WsStream.php
+++ b/src/danog/MadelineProto/Stream/Transport/WsStream.php
@@ -64,7 +64,7 @@ class WsStream implements RawStreamInterface, ProxyStreamInterface
*/
public function connect(ConnectionContext $ctx, string $header = ''): \Generator
{
- if (!\class_exists(Connector::class)) {
+ if (!\class_exists(Handshake::class)) {
throw new \danog\MadelineProto\Exception('Please install amphp/websocket-client by running "composer require amphp/websocket-client:dev-master"');
}
$this->dc = $ctx->getIntDc();
diff --git a/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php b/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php
index 3c058625..1de8a07f 100644
--- a/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php
+++ b/src/danog/MadelineProto/TL/Conversion/BotAPIFiles.php
@@ -111,7 +111,7 @@ trait BotAPIFiles
return $res;
case THUMBNAIL:
$res['InputFileLocation'] = [
- '_' => $photoSize->getThumbFileType() <= PHOTO ? 'inputPhotoFileLocation' : 'inputDocumentFileLocation',
+ '_' => $photoSize->getThumbFileType() <= PHOTO ? 'inputDocumentFileLocation' : 'inputPhotoFileLocation',
'id' => $fileId->getId(),
'access_hash' => $fileId->getAccessHash(),
'file_reference' => $fileId->getFileReference(),
@@ -204,7 +204,7 @@ trait BotAPIFiles
'file_reference' => $fileId->getFileReference(),
'dc_id' => $fileId->getDcId(),
'mime_type' => '',
- 'attributes' => [$attribute]
+ 'attributes' => $attribute ? [$attribute] : []
];
$res['MessageMedia'] = ['_' => 'messageMediaDocument', 'document' => $constructor, 'caption' => ''];
return $res;
diff --git a/tests/danog/MadelineProto/API.php b/tests/danog/MadelineProto/API.php
deleted file mode 100644
index 1f1fb330..00000000
--- a/tests/danog/MadelineProto/API.php
+++ /dev/null
@@ -1,59 +0,0 @@
- \random_int(PHP_INT_MIN, PHP_INT_MAX)];
- $MadelineProto = new \danog\MadelineProto\API(
- [
- 'app_info' => [
- 'api_id' => 25628,
- 'api_hash' => '1fe17cda7d355166cdaa71f04122873c',
- ],
- 'connection_settings' => [
- 'all' => [
- 'ipv6' => $ipv6,
- 'test_mode' => $test_mode,
- 'protocol' => $protocol,
- 'obfuscated' => $obfuscated,
- 'transport' => $transport,
- ],
- ],
- ]
- );
- $pong = $MadelineProto->ping($ping);
- $this->assertContainsEquals('_', $pong, 'pong');
- $this->assertContainsEquals('ping_id', $pong, $ping['ping_id']);
- }
-
- public function protocolProvider(): \Generator
- {
- foreach ([false, true] as $test_mode) {
- foreach ([false, true] as $ipv6) {
- foreach (['tcp', 'ws', 'wss'] as $transport) {
- foreach ([true, false] as $obfuscated) {
- if ($transport !== 'tcp' && !$obfuscated) {
- continue;
- }
- foreach (['tcp_abridged', 'tcp_intermediate', 'tcp_intermediate_padded', 'tcp_full'] as $protocol) {
- if ($protocol === 'tcp_full' && $obfuscated) {
- continue;
- }
- yield [$transport, $obfuscated, $protocol, $test_mode, $ipv6];
- }
- }
- }
- yield ['tcp', false, 'http', $test_mode, $ipv6];
- yield ['tcp', false, 'https', $test_mode, $ipv6];
- }
- }
- }
-}
diff --git a/tests/danog/MadelineProto/DataCenterTest.php b/tests/danog/MadelineProto/DataCenterTest.php
new file mode 100644
index 00000000..39c9d731
--- /dev/null
+++ b/tests/danog/MadelineProto/DataCenterTest.php
@@ -0,0 +1,94 @@
+ [
+ 'all' => [
+ 'ipv6' => $ipv6,
+ 'test_mode' => $test_mode,
+ 'protocol' => $protocol,
+ 'obfuscated' => $obfuscated,
+ 'transport' => $transport
+ ],
+ ]
+ ]
+ );
+ $datacenter = new DataCenter(
+ new class($settings) {
+ /**
+ * Constructor.
+ *
+ * @param array $settings Logger settings
+ */
+ public function __construct(array $settings)
+ {
+ $this->logger = Logger::getLoggerFromSettings($settings);
+ $this->settings = $settings;
+ }
+ /**
+ * Get logger.
+ *
+ * @return Logger
+ */
+ public function getLogger(): Logger
+ {
+ return $this->logger;
+ }
+ },
+ $settings['connection'],
+ $settings['connection_settings'],
+ );
+
+ Tools::wait($datacenter->dcConnect(2));
+ $this->assertTrue(true);
+ }
+
+ public function protocolProvider(): \Generator
+ {
+ foreach ([false, true] as $test_mode) {
+ foreach ([false, true] as $ipv6) {
+ foreach (['tcp', 'ws', 'wss'] as $transport) {
+ foreach ([true, false] as $obfuscated) {
+ if ($transport !== 'tcp' && !$obfuscated) {
+ continue;
+ }
+ foreach (['abridged', 'intermediate', 'intermediate_padded', 'full'] as $protocol) {
+ if ($protocol === 'full' && $obfuscated) {
+ continue;
+ }
+ yield [$transport, $obfuscated, $protocol, $test_mode, $ipv6];
+ }
+ }
+ }
+ yield ['tcp', false, 'http', $test_mode, $ipv6];
+ yield ['tcp', false, 'https', $test_mode, $ipv6];
+ }
+ }
+ }
+}
diff --git a/tests/danog/MadelineProto/FileIdTest.php b/tests/danog/MadelineProto/FileIdTest.php
new file mode 100644
index 00000000..2888a5c6
--- /dev/null
+++ b/tests/danog/MadelineProto/FileIdTest.php
@@ -0,0 +1,140 @@
+ [
+ 'api_id' => \getenv('API_ID'),
+ 'api_hash' => \getenv('API_HASH'),
+ ],
+ 'logger' => [
+ 'logger' => Logger::ECHO_LOGGER,
+ 'logger_level' => Logger::ULTRA_VERBOSE
+ ]
+ ]
+ );
+ self::$MadelineProto->botLogin(\getenv('BOT_TOKEN'));
+ }
+
+ /**
+ * @param string $fileId File ID
+ * @param string $type Expected type
+ *
+ * @dataProvider provideFileIdsAndType
+ */
+ public function testDownload(string $type, string $fileIdStr, string $uniqueFileIdStr)
+ {
+ self::$MadelineProto->downloadToFile($fileIdStr, '/dev/null');
+ }
+ /**
+ * @param string $fileId File ID
+ * @param string $type Expected type
+ *
+ * @dataProvider provideFileIdsAndType
+ */
+ public function testResend(string $type, string $fileIdStr, string $uniqueFileIdStr)
+ {
+ self::$MadelineProto->messages->sendMedia(
+ [
+ 'peer' => \getenv('DEST'),
+ 'media' => $fileIdStr
+ ]
+ );
+ }
+
+ public function provideFileIdsAndType(): \Generator
+ {
+ $dest = \getenv('DEST');
+ $token = \getenv('BOT_TOKEN');
+ foreach ($this->provideChats() as $chat) {
+ $result = \json_decode(\file_get_contents("https://api.telegram.org/bot$token/getChat?chat_id=$chat"), true)['result']['photo'];
+ yield [
+ 'profile_photo',
+ $result['small_file_id'],
+ $result['small_file_unique_id'],
+ ];
+ yield [
+ 'profile_photo',
+ $result['big_file_id'],
+ $result['big_file_unique_id'],
+ ];
+ }
+ foreach ($this->provideUrls() as $type => $url) {
+ if ($type === 'video_note') {
+ \copy($url, \basename($url));
+
+ $handle = \curl_init("https://api.telegram.org/bot$token/sendVideoNote?chat_id=$dest");
+ \curl_setopt($handle, CURLOPT_POST, true);
+ \curl_setopt($handle, CURLOPT_POSTFIELDS, [
+ $type => new CURLFile(\basename($url))
+ ]);
+ \curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
+ $botResult = \json_decode(\curl_exec($handle), true);
+ \curl_close($handle);
+
+ \unlink(\basename($url));
+ } else {
+ $botResult = \json_decode(\file_get_contents("https://api.telegram.org/bot$token/send$type?chat_id=$dest&$type=$url"), true);
+ }
+ $botResult = $botResult['result'][$type];
+ if ($type !== 'photo') {
+ $botResult = [$botResult];
+ }
+ foreach ($botResult as $subResult) {
+ yield [
+ $type,
+ $subResult['file_id'],
+ $subResult['file_unique_id']
+ ];
+ if (isset($subResult['thumb'])) {
+ yield [
+ 'thumbnail',
+ $subResult['thumb']['file_id'],
+ $subResult['thumb']['file_unique_id']
+ ];
+ }
+ }
+ }
+ return $result;
+ }
+ public function provideChats(): array
+ {
+ return [\getenv('DEST'), '@MadelineProto'];
+ }
+ public function provideUrls(): array
+ {
+ return [
+ 'sticker' => 'https://github.com/danog/MadelineProto/blob/master/tests/lel.webp?raw=true',
+ 'photo' => 'https://github.com/danog/MadelineProto/blob/master/tests/faust.jpg',
+ 'audio' => 'https://github.com/danog/MadelineProto/blob/master/tests/mosconi.mp3?raw=true',
+ 'video' => 'https://github.com/danog/MadelineProto/blob/master/tests/swing.mp4?raw=true',
+ 'animation' => 'https://github.com/danog/MadelineProto/blob/master/tests/pony.mp4?raw=true',
+ 'document' => 'https://github.com/danog/danog.github.io/raw/master/lol/index_htm_files/0.gif',
+ 'voice' => 'https://daniil.it/audio_2020-02-01_18-09-08.ogg',
+ //'video_note' => 'https://daniil.it/round.mp4'
+ ];
+ }
+}
diff --git a/tests/phpunit.xml b/tests/phpunit.xml
index a7acb4db..88cb5382 100644
--- a/tests/phpunit.xml
+++ b/tests/phpunit.xml
@@ -1,7 +1,20 @@
-
-
-
-
-
-
+
+
+
+ ../tests
+
+
+