mirror of
https://github.com/BushlanovDev/max-bot-api-client-php.git
synced 2026-08-23 22:36:49 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 576f02efbd | |||
| da7a07145b | |||
| 7cdbfc0f47 | |||
| f29344d2ec | |||
| 3012272497 | |||
| 0dc10bd279 |
+1
-1
@@ -66,7 +66,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"analyse": "vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=256M",
|
"analyse": "vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=512M",
|
||||||
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes src",
|
"format": "vendor/bin/php-cs-fixer fix --allow-risky=yes src",
|
||||||
"test": "vendor/bin/phpunit",
|
"test": "vendor/bin/phpunit",
|
||||||
"test-coverage": "vendor/bin/phpunit --coverage-html coverage",
|
"test-coverage": "vendor/bin/phpunit --coverage-html coverage",
|
||||||
|
|||||||
+1
-1
@@ -363,7 +363,7 @@ class Api
|
|||||||
$this->buildNewMessageBody($text, $attachments, $format, $link, $notify),
|
$this->buildNewMessageBody($text, $attachments, $format, $link, $notify),
|
||||||
);
|
);
|
||||||
|
|
||||||
return $this->modelFactory->createMessage($response['message']);
|
return $this->modelFactory->createMessageFromSendResponse($response);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+7
-4
@@ -71,7 +71,9 @@ final readonly class Client implements ClientApiInterface
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
$fullUrl = $this->baseUrl . $uri . '?' . http_build_query($queryParams);
|
$fullUrl = $this->baseUrl . $uri . '?' . http_build_query($queryParams);
|
||||||
$request = $this->requestFactory->createRequest($method, $fullUrl);
|
$request = $this->requestFactory
|
||||||
|
->createRequest($method, $fullUrl)
|
||||||
|
->withHeader('Authorization', $this->accessToken);
|
||||||
|
|
||||||
if (!empty($body)) {
|
if (!empty($body)) {
|
||||||
try {
|
try {
|
||||||
@@ -82,8 +84,7 @@ final readonly class Client implements ClientApiInterface
|
|||||||
$stream = $this->streamFactory->createStream($payload);
|
$stream = $this->streamFactory->createStream($payload);
|
||||||
$request = $request
|
$request = $request
|
||||||
->withBody($stream)
|
->withBody($stream)
|
||||||
->withHeader('Content-Type', 'application/json; charset=utf-8')
|
->withHeader('Content-Type', 'application/json; charset=utf-8');
|
||||||
->withHeader('Authorization', $this->accessToken);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -143,6 +144,7 @@ final readonly class Client implements ClientApiInterface
|
|||||||
$request = $this->requestFactory
|
$request = $this->requestFactory
|
||||||
->createRequest('POST', $uri)
|
->createRequest('POST', $uri)
|
||||||
->withHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary)
|
->withHeader('Content-Type', 'multipart/form-data; boundary=' . $boundary)
|
||||||
|
->withHeader('Authorization', $this->accessToken)
|
||||||
->withBody($bodyStream);
|
->withBody($bodyStream);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -198,7 +200,8 @@ final readonly class Client implements ClientApiInterface
|
|||||||
->withBody($chunkStream)
|
->withBody($chunkStream)
|
||||||
->withHeader('Content-Type', 'application/octet-stream')
|
->withHeader('Content-Type', 'application/octet-stream')
|
||||||
->withHeader('Content-Disposition', 'attachment; filename="' . $fileName . '"')
|
->withHeader('Content-Disposition', 'attachment; filename="' . $fileName . '"')
|
||||||
->withHeader('Content-Range', "bytes {$startByte}-{$endByte}/{$fileSize}");
|
->withHeader('Content-Range', "bytes {$startByte}-{$endByte}/{$fileSize}")
|
||||||
|
->withHeader('Authorization', $this->accessToken);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$response = $this->httpClient->sendRequest($request);
|
$response = $this->httpClient->sendRequest($request);
|
||||||
|
|||||||
+30
-1
@@ -128,6 +128,33 @@ class ModelFactory
|
|||||||
: [];
|
: [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Message from the specific response structure of the sendMessage endpoint.
|
||||||
|
*
|
||||||
|
* @param array<string, mixed> $data The raw response from the client.
|
||||||
|
*
|
||||||
|
* @return Message
|
||||||
|
* @throws ReflectionException
|
||||||
|
*/
|
||||||
|
public function createMessageFromSendResponse(array $data): Message
|
||||||
|
{
|
||||||
|
$messageData = $data['message'];
|
||||||
|
|
||||||
|
$topLevelData = [
|
||||||
|
'chat_id' => $data['chat_id'] ?? null,
|
||||||
|
'recipient_id' => $data['recipient_id'] ?? null,
|
||||||
|
'message_id' => $data['message_id'] ?? null,
|
||||||
|
];
|
||||||
|
$messageData = array_merge($messageData, array_filter($topLevelData, fn($value) => $value !== null));
|
||||||
|
|
||||||
|
if (isset($messageData['message']) && is_array($messageData['message'])) {
|
||||||
|
$messageData['body'] = $messageData['message'];
|
||||||
|
unset($messageData['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->createMessage($messageData);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Message.
|
* Message.
|
||||||
*
|
*
|
||||||
@@ -267,7 +294,9 @@ class ModelFactory
|
|||||||
InlineButtonType::RequestGeoLocation => RequestGeoLocationButton::fromArray($data),
|
InlineButtonType::RequestGeoLocation => RequestGeoLocationButton::fromArray($data),
|
||||||
InlineButtonType::Chat => ChatButton::fromArray($data),
|
InlineButtonType::Chat => ChatButton::fromArray($data),
|
||||||
InlineButtonType::OpenApp => OpenAppButton::fromArray($data),
|
InlineButtonType::OpenApp => OpenAppButton::fromArray($data),
|
||||||
default => throw new LogicException('Unknown or unsupported inline button type: ' . ($data['type'] ?? 'none')),
|
default => throw new LogicException(
|
||||||
|
'Unknown or unsupported inline button type: ' . ($data['type'] ?? 'none')
|
||||||
|
),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ final readonly class Message extends AbstractModel
|
|||||||
* @param string|null $url Message public URL. Can be null for dialogs or non-public chats/channels.
|
* @param string|null $url Message public URL. Can be null for dialogs or non-public chats/channels.
|
||||||
* @param LinkedMessage|null $link Forwarded or replied message.
|
* @param LinkedMessage|null $link Forwarded or replied message.
|
||||||
* @param MessageStat|null $stat Message statistics. Available only for channels.
|
* @param MessageStat|null $stat Message statistics. Available only for channels.
|
||||||
|
* @param int|null $chatId Chat identifier.
|
||||||
|
* @param int|null $recipientId User identifier, if message was sent to user.
|
||||||
|
* @param string|null $messageId Unique identifier of message.
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public int $timestamp,
|
public int $timestamp,
|
||||||
@@ -26,6 +29,9 @@ final readonly class Message extends AbstractModel
|
|||||||
public ?string $url,
|
public ?string $url,
|
||||||
public ?LinkedMessage $link,
|
public ?LinkedMessage $link,
|
||||||
public ?MessageStat $stat,
|
public ?MessageStat $stat,
|
||||||
|
public ?int $chatId = null,
|
||||||
|
public ?int $recipientId = null,
|
||||||
|
public ?string $messageId = null,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+52
-25
@@ -336,7 +336,7 @@ final class ApiTest extends TestCase
|
|||||||
$apiResponse = [
|
$apiResponse = [
|
||||||
'message' => [
|
'message' => [
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'body' => ['mid' => 'mid.456.xyz', 'seq' => 101, 'text' => $text],
|
'message' => ['mid' => 'mid.456.xyz', 'seq' => 101, 'text' => $text],
|
||||||
'recipient' => ['chat_type' => 'dialog', 'user_id' => 123, 'chat_id' => null],
|
'recipient' => ['chat_type' => 'dialog', 'user_id' => 123, 'chat_id' => null],
|
||||||
'sender' => [
|
'sender' => [
|
||||||
'user_id' => 123,
|
'user_id' => 123,
|
||||||
@@ -348,9 +348,18 @@ final class ApiTest extends TestCase
|
|||||||
],
|
],
|
||||||
'url' => 'https://max.ru/message/123',
|
'url' => 'https://max.ru/message/123',
|
||||||
],
|
],
|
||||||
|
'chat_id' => 20414985,
|
||||||
|
'recipient_id' => 4328369,
|
||||||
|
'message_id' => 'mid.456.xyz',
|
||||||
];
|
];
|
||||||
|
|
||||||
$expectedMessageObject = Message::fromArray($apiResponse['message']);
|
$finalMessageData = $apiResponse['message'];
|
||||||
|
$finalMessageData['body'] = $finalMessageData['message'];
|
||||||
|
unset($finalMessageData['message']);
|
||||||
|
$finalMessageData['chat_id'] = $apiResponse['chat_id'];
|
||||||
|
$finalMessageData['recipient_id'] = $apiResponse['recipient_id'];
|
||||||
|
$finalMessageData['message_id'] = $apiResponse['message_id'];
|
||||||
|
$expectedMessageObject = Message::fromArray($finalMessageData);
|
||||||
|
|
||||||
$this->clientMock
|
$this->clientMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
@@ -360,8 +369,8 @@ final class ApiTest extends TestCase
|
|||||||
|
|
||||||
$this->modelFactoryMock
|
$this->modelFactoryMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('createMessage')
|
->method('createMessageFromSendResponse')
|
||||||
->with($apiResponse['message'])
|
->with($apiResponse)
|
||||||
->willReturn($expectedMessageObject);
|
->willReturn($expectedMessageObject);
|
||||||
|
|
||||||
$result = $this->api->sendMessage(
|
$result = $this->api->sendMessage(
|
||||||
@@ -416,12 +425,17 @@ final class ApiTest extends TestCase
|
|||||||
$apiResponse = [
|
$apiResponse = [
|
||||||
'message' => [
|
'message' => [
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'body' => ['mid' => 'mid.test.123', 'seq' => 1, 'text' => $text],
|
'message' => ['mid' => 'mid.test.123', 'seq' => 1, 'text' => $text],
|
||||||
'recipient' => ['chat_type' => 'dialog', 'user_id' => 123, 'chat_id' => null],
|
'recipient' => ['chat_type' => 'dialog', 'user_id' => 123, 'chat_id' => null],
|
||||||
]
|
],
|
||||||
|
'message_id' => 'mid.test.123',
|
||||||
];
|
];
|
||||||
|
|
||||||
$expectedMessageObject = Message::fromArray($apiResponse['message']);
|
$finalMessageData = $apiResponse['message'];
|
||||||
|
$finalMessageData['body'] = $finalMessageData['message'];
|
||||||
|
unset($finalMessageData['message']);
|
||||||
|
$finalMessageData['message_id'] = $apiResponse['message_id'];
|
||||||
|
$expectedMessageObject = Message::fromArray($finalMessageData);
|
||||||
|
|
||||||
$this->clientMock
|
$this->clientMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
@@ -436,8 +450,8 @@ final class ApiTest extends TestCase
|
|||||||
|
|
||||||
$this->modelFactoryMock
|
$this->modelFactoryMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('createMessage')
|
->method('createMessageFromSendResponse')
|
||||||
->with($apiResponse['message'])
|
->with($apiResponse)
|
||||||
->willReturn($expectedMessageObject);
|
->willReturn($expectedMessageObject);
|
||||||
|
|
||||||
$result = $this->api->sendMessage(
|
$result = $this->api->sendMessage(
|
||||||
@@ -803,11 +817,15 @@ final class ApiTest extends TestCase
|
|||||||
$apiResponse = [
|
$apiResponse = [
|
||||||
'message' => [
|
'message' => [
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'body' => ['mid' => 'mid.sticker.1', 'seq' => 10],
|
'message' => ['mid' => 'mid.sticker.1', 'seq' => 10],
|
||||||
'recipient' => ['chat_type' => 'dialog', 'user_id' => $chatId],
|
'recipient' => ['chat_type' => 'dialog', 'user_id' => $chatId],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
$expectedMessageObject = Message::fromArray($apiResponse['message']);
|
|
||||||
|
$finalMessageData = $apiResponse['message'];
|
||||||
|
$finalMessageData['body'] = $finalMessageData['message'];
|
||||||
|
unset($finalMessageData['message']);
|
||||||
|
$expectedMessageObject = Message::fromArray($finalMessageData);
|
||||||
|
|
||||||
$this->clientMock->expects($this->once())
|
$this->clientMock->expects($this->once())
|
||||||
->method('request')
|
->method('request')
|
||||||
@@ -815,8 +833,8 @@ final class ApiTest extends TestCase
|
|||||||
->willReturn($apiResponse);
|
->willReturn($apiResponse);
|
||||||
|
|
||||||
$this->modelFactoryMock->expects($this->once())
|
$this->modelFactoryMock->expects($this->once())
|
||||||
->method('createMessage')
|
->method('createMessageFromSendResponse')
|
||||||
->with($apiResponse['message'])
|
->with($apiResponse)
|
||||||
->willReturn($expectedMessageObject);
|
->willReturn($expectedMessageObject);
|
||||||
|
|
||||||
$result = $this->api->sendMessage(chatId: $chatId, attachments: [$stickerRequest]);
|
$result = $this->api->sendMessage(chatId: $chatId, attachments: [$stickerRequest]);
|
||||||
@@ -849,11 +867,14 @@ final class ApiTest extends TestCase
|
|||||||
$apiResponse = [
|
$apiResponse = [
|
||||||
'message' => [
|
'message' => [
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'body' => ['mid' => 'mid.contact.1', 'seq' => 11],
|
'message' => ['mid' => 'mid.contact.1', 'seq' => 11],
|
||||||
'recipient' => ['chat_type' => 'dialog', 'user_id' => $chatId],
|
'recipient' => ['chat_type' => 'dialog', 'user_id' => $chatId],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
$expectedMessageObject = Message::fromArray($apiResponse['message']);
|
$finalMessageData = $apiResponse['message'];
|
||||||
|
$finalMessageData['body'] = $finalMessageData['message'];
|
||||||
|
unset($finalMessageData['message']);
|
||||||
|
$expectedMessageObject = Message::fromArray($finalMessageData);
|
||||||
|
|
||||||
$this->clientMock->expects($this->once())
|
$this->clientMock->expects($this->once())
|
||||||
->method('request')
|
->method('request')
|
||||||
@@ -861,8 +882,8 @@ final class ApiTest extends TestCase
|
|||||||
->willReturn($apiResponse);
|
->willReturn($apiResponse);
|
||||||
|
|
||||||
$this->modelFactoryMock->expects($this->once())
|
$this->modelFactoryMock->expects($this->once())
|
||||||
->method('createMessage')
|
->method('createMessageFromSendResponse')
|
||||||
->with($apiResponse['message'])
|
->with($apiResponse)
|
||||||
->willReturn($expectedMessageObject);
|
->willReturn($expectedMessageObject);
|
||||||
|
|
||||||
$result = $this->api->sendMessage(chatId: $chatId, attachments: [$contactRequest]);
|
$result = $this->api->sendMessage(chatId: $chatId, attachments: [$contactRequest]);
|
||||||
@@ -895,11 +916,14 @@ final class ApiTest extends TestCase
|
|||||||
$apiResponse = [
|
$apiResponse = [
|
||||||
'message' => [
|
'message' => [
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'body' => ['mid' => 'mid.location.1', 'seq' => 12],
|
'message' => ['mid' => 'mid.location.1', 'seq' => 12],
|
||||||
'recipient' => ['chat_type' => 'dialog', 'user_id' => $chatId],
|
'recipient' => ['chat_type' => 'dialog', 'user_id' => $chatId],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
$expectedMessageObject = Message::fromArray($apiResponse['message']);
|
$finalMessageData = $apiResponse['message'];
|
||||||
|
$finalMessageData['body'] = $finalMessageData['message'];
|
||||||
|
unset($finalMessageData['message']);
|
||||||
|
$expectedMessageObject = Message::fromArray($finalMessageData);
|
||||||
|
|
||||||
$this->clientMock->expects($this->once())
|
$this->clientMock->expects($this->once())
|
||||||
->method('request')
|
->method('request')
|
||||||
@@ -907,8 +931,8 @@ final class ApiTest extends TestCase
|
|||||||
->willReturn($apiResponse);
|
->willReturn($apiResponse);
|
||||||
|
|
||||||
$this->modelFactoryMock->expects($this->once())
|
$this->modelFactoryMock->expects($this->once())
|
||||||
->method('createMessage')
|
->method('createMessageFromSendResponse')
|
||||||
->with($apiResponse['message'])
|
->with($apiResponse)
|
||||||
->willReturn($expectedMessageObject);
|
->willReturn($expectedMessageObject);
|
||||||
|
|
||||||
$result = $this->api->sendMessage(chatId: $chatId, attachments: [$locationRequest]);
|
$result = $this->api->sendMessage(chatId: $chatId, attachments: [$locationRequest]);
|
||||||
@@ -940,11 +964,14 @@ final class ApiTest extends TestCase
|
|||||||
$apiResponse = [
|
$apiResponse = [
|
||||||
'message' => [
|
'message' => [
|
||||||
'timestamp' => time(),
|
'timestamp' => time(),
|
||||||
'body' => ['mid' => 'mid.share.1', 'seq' => 13],
|
'message' => ['mid' => 'mid.share.1', 'seq' => 13],
|
||||||
'recipient' => ['chat_type' => 'dialog', 'user_id' => $chatId],
|
'recipient' => ['chat_type' => 'dialog', 'user_id' => $chatId],
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
$expectedMessageObject = Message::fromArray($apiResponse['message']);
|
$finalMessageData = $apiResponse['message'];
|
||||||
|
$finalMessageData['body'] = $finalMessageData['message'];
|
||||||
|
unset($finalMessageData['message']);
|
||||||
|
$expectedMessageObject = Message::fromArray($finalMessageData);
|
||||||
|
|
||||||
$this->clientMock->expects($this->once())
|
$this->clientMock->expects($this->once())
|
||||||
->method('request')
|
->method('request')
|
||||||
@@ -952,8 +979,8 @@ final class ApiTest extends TestCase
|
|||||||
->willReturn($apiResponse);
|
->willReturn($apiResponse);
|
||||||
|
|
||||||
$this->modelFactoryMock->expects($this->once())
|
$this->modelFactoryMock->expects($this->once())
|
||||||
->method('createMessage')
|
->method('createMessageFromSendResponse')
|
||||||
->with($apiResponse['message'])
|
->with($apiResponse)
|
||||||
->willReturn($expectedMessageObject);
|
->willReturn($expectedMessageObject);
|
||||||
|
|
||||||
$result = $this->api->sendMessage(chatId: $chatId, attachments: [$shareRequest]);
|
$result = $this->api->sendMessage(chatId: $chatId, attachments: [$shareRequest]);
|
||||||
|
|||||||
+71
-11
@@ -107,6 +107,12 @@ final class ClientTest extends TestCase
|
|||||||
->with('GET', $expectedUrl)
|
->with('GET', $expectedUrl)
|
||||||
->willReturn($this->requestMock);
|
->willReturn($this->requestMock);
|
||||||
|
|
||||||
|
$this->requestMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('withHeader')
|
||||||
|
->with('Authorization', self::FAKE_TOKEN)
|
||||||
|
->willReturn($this->requestMock);
|
||||||
|
|
||||||
$this->httpClientMock
|
$this->httpClientMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('sendRequest')
|
->method('sendRequest')
|
||||||
@@ -161,17 +167,18 @@ final class ClientTest extends TestCase
|
|||||||
->method('withHeader')
|
->method('withHeader')
|
||||||
->willReturnCallback(function (string $header, string $value) use (&$headerCallCount) {
|
->willReturnCallback(function (string $header, string $value) use (&$headerCallCount) {
|
||||||
if ($headerCallCount === 0) {
|
if ($headerCallCount === 0) {
|
||||||
$this->assertSame('Content-Type', $header);
|
|
||||||
$this->assertSame('application/json; charset=utf-8', $value);
|
|
||||||
} elseif ($headerCallCount === 1) {
|
|
||||||
$this->assertSame('Authorization', $header);
|
$this->assertSame('Authorization', $header);
|
||||||
$this->assertSame(self::FAKE_TOKEN, $value);
|
$this->assertSame(self::FAKE_TOKEN, $value);
|
||||||
|
} elseif ($headerCallCount === 1) {
|
||||||
|
$this->assertSame('Content-Type', $header);
|
||||||
|
$this->assertSame('application/json; charset=utf-8', $value);
|
||||||
}
|
}
|
||||||
|
|
||||||
$headerCallCount++;
|
$headerCallCount++;
|
||||||
|
|
||||||
return $this->requestMock;
|
return $this->requestMock;
|
||||||
});
|
});
|
||||||
|
|
||||||
$this->responseMock->method('getStatusCode')->willReturn(200);
|
$this->responseMock->method('getStatusCode')->willReturn(200);
|
||||||
$this->streamMock->method('__toString')->willReturn(json_encode($responsePayload));
|
$this->streamMock->method('__toString')->willReturn(json_encode($responsePayload));
|
||||||
|
|
||||||
@@ -307,11 +314,23 @@ final class ClientTest extends TestCase
|
|||||||
)
|
)
|
||||||
->willReturn($this->requestMock);
|
->willReturn($this->requestMock);
|
||||||
|
|
||||||
|
$headerCallCount = 0;
|
||||||
$this->requestMock
|
$this->requestMock
|
||||||
->expects($this->once())
|
->expects($this->exactly(2))
|
||||||
->method('withHeader')
|
->method('withHeader')
|
||||||
->with($this->stringStartsWith('Content-Type'), $this->stringStartsWith('multipart/form-data'))
|
->willReturnCallback(function (string $header, string $value) use (&$headerCallCount) {
|
||||||
->willReturn($this->requestMock);
|
if ($headerCallCount === 0) {
|
||||||
|
$this->assertSame('Content-Type', $header);
|
||||||
|
$this->assertStringStartsWith('multipart/form-data; boundary=', $value);
|
||||||
|
} elseif ($headerCallCount === 1) {
|
||||||
|
$this->assertSame('Authorization', $header);
|
||||||
|
$this->assertSame(self::FAKE_TOKEN, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headerCallCount++;
|
||||||
|
|
||||||
|
return $this->requestMock;
|
||||||
|
});
|
||||||
|
|
||||||
$this->requestFactoryMock
|
$this->requestFactoryMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
@@ -339,9 +358,26 @@ final class ClientTest extends TestCase
|
|||||||
rewind($tmpFileHandle);
|
rewind($tmpFileHandle);
|
||||||
|
|
||||||
$this->requestFactoryMock->method('createRequest')->willReturn($this->requestMock);
|
$this->requestFactoryMock->method('createRequest')->willReturn($this->requestMock);
|
||||||
$this->requestMock->method('withHeader')->willReturn($this->requestMock);
|
|
||||||
|
$headerCallCount = 0;
|
||||||
|
$this->requestMock
|
||||||
|
->expects($this->exactly(2))
|
||||||
|
->method('withHeader')
|
||||||
|
->willReturnCallback(function (string $header, string $value) use (&$headerCallCount) {
|
||||||
|
if ($headerCallCount === 0) {
|
||||||
|
$this->assertSame('Content-Type', $header);
|
||||||
|
$this->assertStringStartsWith('multipart/form-data; boundary=', $value);
|
||||||
|
} elseif ($headerCallCount === 1) {
|
||||||
|
$this->assertSame('Authorization', $header);
|
||||||
|
$this->assertSame(self::FAKE_TOKEN, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headerCallCount++;
|
||||||
|
|
||||||
|
return $this->requestMock;
|
||||||
|
});
|
||||||
|
|
||||||
$this->requestMock->method('withBody')->willReturn($this->requestMock);
|
$this->requestMock->method('withBody')->willReturn($this->requestMock);
|
||||||
// $this->httpClientMock->method('sendRequest')->willReturn($this->responseMock);
|
|
||||||
$this->responseMock->method('getStatusCode')->willReturn(200);
|
$this->responseMock->method('getStatusCode')->willReturn(200);
|
||||||
$this->streamMock->method('__toString')->willReturn(json_encode($responsePayload));
|
$this->streamMock->method('__toString')->willReturn(json_encode($responsePayload));
|
||||||
|
|
||||||
@@ -475,7 +511,30 @@ final class ClientTest extends TestCase
|
|||||||
|
|
||||||
$this->requestFactoryMock->method('createRequest')->willReturn($this->requestMock);
|
$this->requestFactoryMock->method('createRequest')->willReturn($this->requestMock);
|
||||||
$this->requestMock->method('withBody')->willReturnSelf();
|
$this->requestMock->method('withBody')->willReturnSelf();
|
||||||
$this->requestMock->method('withHeader')->willReturnSelf();
|
|
||||||
|
$headerCallCount = 0;
|
||||||
|
$this->requestMock
|
||||||
|
->expects($this->exactly(4))
|
||||||
|
->method('withHeader')
|
||||||
|
->willReturnCallback(function (string $header, string $value) use (&$headerCallCount, $fileName, $fileSize) {
|
||||||
|
if ($headerCallCount === 0) {
|
||||||
|
$this->assertSame('Content-Type', $header);
|
||||||
|
$this->assertSame('application/octet-stream', $value);
|
||||||
|
} elseif ($headerCallCount === 1) {
|
||||||
|
$this->assertSame('Content-Disposition', $header);
|
||||||
|
$this->assertSame('attachment; filename="' . $fileName . '"', $value);
|
||||||
|
} elseif ($headerCallCount === 2) {
|
||||||
|
$this->assertSame('Content-Range', $header);
|
||||||
|
$this->assertSame("bytes 0-8/{$fileSize}", $value);
|
||||||
|
} elseif ($headerCallCount === 3) {
|
||||||
|
$this->assertSame('Authorization', $header);
|
||||||
|
$this->assertSame(self::FAKE_TOKEN, $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
$headerCallCount++;
|
||||||
|
|
||||||
|
return $this->requestMock;
|
||||||
|
});
|
||||||
|
|
||||||
$this->httpClientMock
|
$this->httpClientMock
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
@@ -495,7 +554,8 @@ final class ClientTest extends TestCase
|
|||||||
#[Test]
|
#[Test]
|
||||||
public function resumableUploadSuccessfullyUploadsMultipleChunks(): void
|
public function resumableUploadSuccessfullyUploadsMultipleChunks(): void
|
||||||
{
|
{
|
||||||
$fileContents = str_repeat('A', 3 * 1024 * 1024); // 3 MB
|
$chunkSize = 1024 * 1024;
|
||||||
|
$fileContents = str_repeat('A', 3 * $chunkSize); // 3 MB
|
||||||
$fileResource = fopen('php://memory', 'w+');
|
$fileResource = fopen('php://memory', 'w+');
|
||||||
fwrite($fileResource, $fileContents);
|
fwrite($fileResource, $fileContents);
|
||||||
rewind($fileResource);
|
rewind($fileResource);
|
||||||
@@ -522,7 +582,7 @@ final class ClientTest extends TestCase
|
|||||||
->method('__toString')
|
->method('__toString')
|
||||||
->willReturnOnConsecutiveCalls('', '', '<retval>1</retval>');
|
->willReturnOnConsecutiveCalls('', '', '<retval>1</retval>');
|
||||||
|
|
||||||
$result = $this->client->resumableUpload($uploadUrl, $fileResource, $fileName, $fileSize, 1024 * 1024);
|
$result = $this->client->resumableUpload($uploadUrl, $fileResource, $fileName, $fileSize, $chunkSize);
|
||||||
|
|
||||||
$this->assertSame('<retval>1</retval>', $result);
|
$this->assertSame('<retval>1</retval>', $result);
|
||||||
fclose($fileResource);
|
fclose($fileResource);
|
||||||
|
|||||||
@@ -220,6 +220,36 @@ final class ModelFactoryTest extends TestCase
|
|||||||
$this->assertSame(UpdateType::MessageCreated, $subscriptions[0]->updateTypes[0]);
|
$this->assertSame(UpdateType::MessageCreated, $subscriptions[0]->updateTypes[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[Test]
|
||||||
|
public function createMessageFromSendResponseCorrectlyTransformsData(): void
|
||||||
|
{
|
||||||
|
$apiResponse = [
|
||||||
|
'message' => [
|
||||||
|
'recipient' => ['chat_id' => 20414985, 'chat_type' => 'dialog', 'user_id' => 4328369],
|
||||||
|
'timestamp' => 1760089962345,
|
||||||
|
'sender' => [
|
||||||
|
'user_id' => 24480184,
|
||||||
|
'first_name' => 'Autobot',
|
||||||
|
'is_bot' => true,
|
||||||
|
'last_activity_time' => 1760089962354,
|
||||||
|
],
|
||||||
|
'message' => ['mid' => 'mid.xyz', 'seq' => 1153, 'text' => '123123'],
|
||||||
|
],
|
||||||
|
'chat_id' => 20414985,
|
||||||
|
'recipient_id' => 4328369,
|
||||||
|
'message_id' => 'mid.xyz',
|
||||||
|
];
|
||||||
|
|
||||||
|
$message = $this->factory->createMessageFromSendResponse($apiResponse);
|
||||||
|
|
||||||
|
$this->assertInstanceOf(Message::class, $message);
|
||||||
|
$this->assertInstanceOf(MessageBody::class, $message->body);
|
||||||
|
$this->assertSame('mid.xyz', $message->body->mid);
|
||||||
|
$this->assertSame(20414985, $message->chatId);
|
||||||
|
$this->assertSame(4328369, $message->recipientId);
|
||||||
|
$this->assertSame('mid.xyz', $message->messageId);
|
||||||
|
}
|
||||||
|
|
||||||
#[Test]
|
#[Test]
|
||||||
public function createMessage(): void
|
public function createMessage(): void
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -64,6 +64,9 @@ final class MessageTest extends TestCase
|
|||||||
'stat' => [
|
'stat' => [
|
||||||
'views' => 500,
|
'views' => 500,
|
||||||
],
|
],
|
||||||
|
'chat_id' => null,
|
||||||
|
'recipient_id' => null,
|
||||||
|
'message_id' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
$message = Message::fromArray($data);
|
$message = Message::fromArray($data);
|
||||||
|
|||||||
Reference in New Issue
Block a user