mirror of
https://github.com/BushlanovDev/max-bot-api-client-php.git
synced 2026-08-20 07:23:01 +00:00
Added editBotInfo & editChat & getVideoAttachmentDetails
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
[](https://github.com/BushlanovDev/max-bot-api-client-php/actions)
|
||||
[](https://github.com/BushlanovDev/max-bot-api-client-php/actions)
|
||||
[](https://packagist.org/packages/bushlanov-dev/max-bot-api-client-php)
|
||||
[](https://github.com/BushlanovDev/max-bot-api-client-php)
|
||||
[](LICENSE)
|
||||
|
||||
@@ -9,9 +10,6 @@
|
||||
> На мой взгляд `Max Messenger` является ни чем иным как малварью, созданной для слежки за гражданами РФ. Настоятельно
|
||||
> не рекомендую использовать его на реальных устройствах, с настоящим номером телефона, и для личной переписки.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> Библиотека в стадии активной разработки.
|
||||
|
||||
## Быстрый старт
|
||||
|
||||
> Если вы новичок, то можете прочитать [официальную документацию](https://dev.max.ru/), написанную разработчиками Max.
|
||||
@@ -81,14 +79,14 @@ $webhookHandler->addHandler(UpdateType::BotStarted, function (BotStartedUpdate $
|
||||
#### Bots
|
||||
|
||||
- [x] `GET /me` (`getBotInfo`) - *Получение информации о боте.*
|
||||
- [ ] `PATCH /me` (`editBotInfo`) - *Редактирование информации о боте.*
|
||||
- [x] `PATCH /me` (`editBotInfo`) - *Редактирование информации о боте.*
|
||||
|
||||
#### Chats
|
||||
|
||||
- [x] `GET /chats` (`getChats`) - *Получение списка всех чатов бота.*
|
||||
- [x] `GET /chats/{chatLink}` (`getChatByLink`) - *Получение информации о чате по ссылке.*
|
||||
- [x] `GET /chats/{chatId}` (`getChat`) - *Получение информации о чате по ID.*
|
||||
- [ ] `PATCH /chats/{chatId}` (`editChat`) - *Редактирование информации о чате.*
|
||||
- [x] `PATCH /chats/{chatId}` (`editChat`) - *Редактирование информации о чате.*
|
||||
- [x] `DELETE /chats/{chatId}` (`deleteChat`) - *Удаление чата.*
|
||||
- [x] `POST /chats/{chatId}/actions` (`sendAction`) - *Отправка действия в чат (например, "печатает...").*
|
||||
- [x] `GET /chats/{chatId}/pin` (`getPinnedMessage`) - *Получение закрепленного сообщения.*
|
||||
@@ -121,7 +119,7 @@ $webhookHandler->addHandler(UpdateType::BotStarted, function (BotStartedUpdate $
|
||||
- [x] `PUT /messages` (`editMessage`) - *Редактирование сообщения.*
|
||||
- [x] `DELETE /messages` (`deleteMessage`) - *Удаление сообщения.*
|
||||
- [x] `GET /messages/{messageId}` (`getMessageById`) - *Получение сообщения по ID.*
|
||||
- [ ] `GET /videos/{videoToken}` (`getVideoAttachmentDetails`) - *Получение детальной информации о видео.*
|
||||
- [x] `GET /videos/{videoToken}` (`getVideoAttachmentDetails`) - *Получение детальной информации о видео.*
|
||||
- [x] `POST /answers` (`answerOnCallback`) - *Ответ на нажатие callback-кнопки.*
|
||||
|
||||
## Лицензия
|
||||
|
||||
+80
-1
@@ -19,11 +19,13 @@ use BushlanovDev\MaxMessengerBot\Models\Attachments\Requests\FileAttachmentReque
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Requests\PhotoAttachmentRequest;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Requests\VideoAttachmentRequest;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotInfo;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotPatch;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Chat;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatAdmin;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatList;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatMember;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatMembersList;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatPatch;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Message;
|
||||
use BushlanovDev\MaxMessengerBot\Models\MessageLink;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Result;
|
||||
@@ -31,6 +33,7 @@ use BushlanovDev\MaxMessengerBot\Models\Subscription;
|
||||
use BushlanovDev\MaxMessengerBot\Models\UpdateList;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Updates\AbstractUpdate;
|
||||
use BushlanovDev\MaxMessengerBot\Models\UploadEndpoint;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
|
||||
use InvalidArgumentException;
|
||||
use LogicException;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
@@ -51,7 +54,7 @@ class Api
|
||||
private const string METHOD_GET = 'GET';
|
||||
private const string METHOD_POST = 'POST';
|
||||
private const string METHOD_DELETE = 'DELETE';
|
||||
// private const string METHOD_PATCH = 'PATCH';
|
||||
private const string METHOD_PATCH = 'PATCH';
|
||||
private const string METHOD_PUT = 'PUT';
|
||||
|
||||
private const string ACTION_ME = '/me';
|
||||
@@ -67,6 +70,7 @@ class Api
|
||||
private const string ACTION_CHATS_MEMBERS = '/chats/%d/members';
|
||||
private const string ACTION_UPDATES = '/updates';
|
||||
private const string ACTION_ANSWERS = '/answers';
|
||||
private const string ACTION_VIDEO_DETAILS = '/videos/%s';
|
||||
|
||||
private readonly ClientApiInterface $client;
|
||||
|
||||
@@ -1068,6 +1072,81 @@ class Api
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits the bot info.
|
||||
*
|
||||
* Example: editBotInfo(new BotPatch(name: 'New Bot Name', description: null));
|
||||
*
|
||||
* @param BotPatch $botPatch
|
||||
*
|
||||
* @return BotInfo
|
||||
* @throws ClientApiException
|
||||
* @throws NetworkException
|
||||
* @throws ReflectionException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public function editBotInfo(BotPatch $botPatch): BotInfo
|
||||
{
|
||||
return $this->modelFactory->createBotInfo(
|
||||
$this->client->request(
|
||||
self::METHOD_PATCH,
|
||||
self::ACTION_ME,
|
||||
[],
|
||||
$botPatch->toArray(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Edits chat info such as title, icon, etc.
|
||||
* Instantiate ChatPatch with named arguments for the fields you want to change.
|
||||
*
|
||||
* Example:
|
||||
* $patch = new ChatPatch(title: 'New Cool Title');
|
||||
* $api->editChat(12345, $patch);
|
||||
*
|
||||
* @param int $chatId The identifier of the chat to edit.
|
||||
* @param ChatPatch $chatPatch An object containing the fields to update.
|
||||
*
|
||||
* @return Chat
|
||||
* @throws ClientApiException
|
||||
* @throws NetworkException
|
||||
* @throws ReflectionException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public function editChat(int $chatId, ChatPatch $chatPatch): Chat
|
||||
{
|
||||
return $this->modelFactory->createChat(
|
||||
$this->client->request(
|
||||
self::METHOD_PATCH,
|
||||
self::ACTION_CHATS . '/' . $chatId,
|
||||
[],
|
||||
$chatPatch->toArray(),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns detailed information about a video attachment, including playback URLs.
|
||||
*
|
||||
* @param string $videoToken The token of the video attachment.
|
||||
*
|
||||
* @return VideoAttachmentDetails
|
||||
* @throws ClientApiException
|
||||
* @throws NetworkException
|
||||
* @throws ReflectionException
|
||||
* @throws SerializationException
|
||||
*/
|
||||
public function getVideoAttachmentDetails(string $videoToken): VideoAttachmentDetails
|
||||
{
|
||||
return $this->modelFactory->createVideoAttachmentDetails(
|
||||
$this->client->request(
|
||||
self::METHOD_GET,
|
||||
sprintf(self::ACTION_VIDEO_DETAILS, $videoToken),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to build the 'NewMessageBody' array structure consistently.
|
||||
*
|
||||
|
||||
@@ -27,6 +27,7 @@ use BushlanovDev\MaxMessengerBot\Models\Updates\MessageRemovedUpdate;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Updates\UserAddedToChatUpdate;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Updates\UserRemovedFromChatUpdate;
|
||||
use BushlanovDev\MaxMessengerBot\Models\UploadEndpoint;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
|
||||
use LogicException;
|
||||
use ReflectionException;
|
||||
|
||||
@@ -234,4 +235,17 @@ class ModelFactory
|
||||
{
|
||||
return ChatMembersList::fromArray($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a VideoAttachmentDetails object from raw API data.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @return VideoAttachmentDetails
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function createVideoAttachmentDetails(array $data): VideoAttachmentDetails
|
||||
{
|
||||
return VideoAttachmentDetails::fromArray($data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,65 @@ abstract readonly class AbstractModel
|
||||
return new static(...$constructorArgs); // @phpstan-ignore-line
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($this);
|
||||
$properties = $reflectionClass->getProperties(ReflectionProperty::IS_PUBLIC);
|
||||
$result = [];
|
||||
|
||||
foreach ($properties as $property) {
|
||||
if (!$property->isInitialized($this)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$phpPropertyName = $property->getName();
|
||||
$value = $property->getValue($this);
|
||||
|
||||
$jsonKey = self::toSnakeCase($phpPropertyName);
|
||||
|
||||
$result[$jsonKey] = $this->convertValue($value);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function toSnakeCase(string $input): string
|
||||
{
|
||||
return strtolower((string)preg_replace('/(?<!^)[A-Z]/', '_$0', $input));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
protected function convertValue(mixed $value): mixed
|
||||
{
|
||||
if ($value instanceof AbstractModel) {
|
||||
return $value->toArray();
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
return array_map([$this, 'convertValue'], $value);
|
||||
}
|
||||
|
||||
if ($value instanceof BackedEnum) {
|
||||
return $value->value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param ReflectionProperty $property
|
||||
@@ -114,63 +173,4 @@ abstract readonly class AbstractModel
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $input
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private static function toSnakeCase(string $input): string
|
||||
{
|
||||
return strtolower((string)preg_replace('/(?<!^)[A-Z]/', '_$0', $input));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
public function toArray(): array
|
||||
{
|
||||
$reflectionClass = new ReflectionClass($this);
|
||||
$properties = $reflectionClass->getProperties(ReflectionProperty::IS_PUBLIC);
|
||||
$result = [];
|
||||
|
||||
foreach ($properties as $property) {
|
||||
if (!$property->isInitialized($this)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$phpPropertyName = $property->getName();
|
||||
$value = $property->getValue($this);
|
||||
|
||||
$jsonKey = self::toSnakeCase($phpPropertyName);
|
||||
|
||||
$result[$jsonKey] = $this->convertValue($value);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return mixed
|
||||
* @throws ReflectionException
|
||||
*/
|
||||
private function convertValue(mixed $value): mixed
|
||||
{
|
||||
if ($value instanceof AbstractModel) {
|
||||
return $value->toArray();
|
||||
}
|
||||
|
||||
if (is_array($value)) {
|
||||
return array_map([$this, 'convertValue'], $value);
|
||||
}
|
||||
|
||||
if ($value instanceof BackedEnum) {
|
||||
return $value->value;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models;
|
||||
|
||||
/**
|
||||
* An abstract base for PATCH request models. It uses a variadic constructor
|
||||
* to capture named arguments, tracking which fields were explicitly set.
|
||||
*/
|
||||
abstract readonly class AbstractPatchModel extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @var array<int|string, mixed>
|
||||
*/
|
||||
protected array $patchData;
|
||||
|
||||
/**
|
||||
* Captures all passed named arguments into an associative array.
|
||||
*
|
||||
* @param mixed ...$params
|
||||
*/
|
||||
public function __construct(...$params)
|
||||
{
|
||||
$this->patchData = $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, mixed>
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
final public function toArray(): array
|
||||
{
|
||||
$result = [];
|
||||
foreach ($this->patchData as $key => $value) {
|
||||
$jsonKey = $this->toSnakeCase((string)$key);
|
||||
$result[$jsonKey] = $this->convertValue($value);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
|
||||
/**
|
||||
* Represents the data to patch for a bot. Instantiate with named arguments.
|
||||
*
|
||||
* Example: new BotPatch(name: 'New Bot Name', description: null);
|
||||
*
|
||||
* @property-read string|null $name
|
||||
* @property-read string|null $description
|
||||
* @property-read BotCommand[]|null $commands
|
||||
* @property-read PhotoAttachmentRequestPayload|null $photo
|
||||
*/
|
||||
final readonly class BotPatch extends AbstractPatchModel
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
|
||||
/**
|
||||
* Represents the data to patch for a chat. Instantiate with named arguments.
|
||||
*
|
||||
* Example: new ChatPatch(title: 'New Chat Title');
|
||||
*
|
||||
* @property-read PhotoAttachmentRequestPayload|null $icon
|
||||
* @property-read string|null $title
|
||||
* @property-read string|null $pin Message ID to be pinned.
|
||||
* @property-read bool|null $notify
|
||||
*/
|
||||
final readonly class ChatPatch extends AbstractPatchModel
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
|
||||
/**
|
||||
* Contains detailed information about a video attachment.
|
||||
*/
|
||||
final readonly class VideoAttachmentDetails extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param string $token The video attachment token.
|
||||
* @param int $width The width of the video in pixels.
|
||||
* @param int $height The height of the video in pixels.
|
||||
* @param int $duration The duration of the video in seconds.
|
||||
* @param VideoUrls|null $urls URLs to download or play the video. Can be null if the video is unavailable.
|
||||
* @param PhotoAttachmentRequestPayload|null $thumbnail The video's thumbnail image information.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $token,
|
||||
public int $width,
|
||||
public int $height,
|
||||
public int $duration,
|
||||
public ?VideoUrls $urls = null,
|
||||
public ?PhotoAttachmentRequestPayload $thumbnail = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models;
|
||||
|
||||
/**
|
||||
* Contains URLs for a video attachment in various resolutions.
|
||||
*/
|
||||
final readonly class VideoUrls extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param string|null $mp4_1080 Video URL in 1080p resolution, if available.
|
||||
* @param string|null $mp4_720 Video URL in 720p resolution, if available.
|
||||
* @param string|null $mp4_480 Video URL in 480p resolution, if available.
|
||||
* @param string|null $mp4_360 Video URL in 360p resolution, if available.
|
||||
* @param string|null $mp4_240 Video URL in 240p resolution, if available.
|
||||
* @param string|null $mp4_144 Video URL in 144p resolution, if available.
|
||||
* @param string|null $hls Live streaming URL (HLS), if available.
|
||||
*/
|
||||
public function __construct(
|
||||
public ?string $mp4_1080 = null,
|
||||
public ?string $mp4_720 = null,
|
||||
public ?string $mp4_480 = null,
|
||||
public ?string $mp4_360 = null,
|
||||
public ?string $mp4_240 = null,
|
||||
public ?string $mp4_144 = null,
|
||||
public ?string $hls = null,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -36,11 +36,13 @@ use BushlanovDev\MaxMessengerBot\Models\Attachments\Requests\ShareAttachmentRequ
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Requests\StickerAttachmentRequest;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Requests\VideoAttachmentRequest;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotInfo;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotPatch;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Chat;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatAdmin;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatList;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatMember;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatMembersList;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatPatch;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Message;
|
||||
use BushlanovDev\MaxMessengerBot\Models\MessageBody;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Recipient;
|
||||
@@ -53,6 +55,8 @@ use BushlanovDev\MaxMessengerBot\Models\Updates\BotStartedUpdate;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Updates\MessageCreatedUpdate;
|
||||
use BushlanovDev\MaxMessengerBot\Models\UploadEndpoint;
|
||||
use BushlanovDev\MaxMessengerBot\Models\User;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoUrls;
|
||||
use BushlanovDev\MaxMessengerBot\WebhookHandler;
|
||||
use GuzzleHttp\Psr7\ServerRequest;
|
||||
use InvalidArgumentException;
|
||||
@@ -110,6 +114,10 @@ use RuntimeException;
|
||||
#[UsesClass(ArrayOf::class)]
|
||||
#[UsesClass(ChatMembersList::class)]
|
||||
#[UsesClass(ChatAdmin::class)]
|
||||
#[UsesClass(BotPatch::class)]
|
||||
#[UsesClass(ChatPatch::class)]
|
||||
#[UsesClass(VideoAttachmentDetails::class)]
|
||||
#[UsesClass(VideoUrls::class)]
|
||||
final class ApiTest extends TestCase
|
||||
{
|
||||
use PHPMock;
|
||||
@@ -2099,4 +2107,109 @@ final class ApiTest extends TestCase
|
||||
$result = $this->api->editMessage($messageId, attachments: []);
|
||||
$this->assertSame($expectedResult, $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function editBotInfoSendsCorrectPatchBody(): void
|
||||
{
|
||||
$patch = new BotPatch(name: 'New Bot Name', description: null);
|
||||
|
||||
$expectedBody = [
|
||||
'name' => 'New Bot Name',
|
||||
'description' => null,
|
||||
];
|
||||
|
||||
$rawResponseData = [
|
||||
'user_id' => 123,
|
||||
'first_name' => 'New Bot Name',
|
||||
'is_bot' => true,
|
||||
'last_activity_time' => 1,
|
||||
'description' => null,
|
||||
];
|
||||
$expectedBotInfo = new BotInfo(123, 'New Bot Name', null, null, true, 1, null, null, null, null);
|
||||
|
||||
$this->clientMock
|
||||
->expects($this->once())
|
||||
->method('request')
|
||||
->with('PATCH', '/me', [], $expectedBody)
|
||||
->willReturn($rawResponseData);
|
||||
|
||||
$this->modelFactoryMock
|
||||
->expects($this->once())
|
||||
->method('createBotInfo')
|
||||
->with($rawResponseData)
|
||||
->willReturn($expectedBotInfo);
|
||||
|
||||
$this->api->editBotInfo($patch);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function editChatSendsCorrectPatchBody(): void
|
||||
{
|
||||
$chatId = 12345;
|
||||
$uri = sprintf('/chats/%d', $chatId);
|
||||
$patch = new ChatPatch(title: 'New Chat Title', notify: false);
|
||||
|
||||
$expectedBody = [
|
||||
'title' => 'New Chat Title',
|
||||
'notify' => false,
|
||||
];
|
||||
|
||||
$rawResponse = [
|
||||
'chat_id' => $chatId,
|
||||
'title' => 'New Chat Title',
|
||||
'type' => 'chat',
|
||||
'status' => 'active',
|
||||
'last_event_time' => 1,
|
||||
'participants_count' => 1,
|
||||
'is_public' => false,
|
||||
];
|
||||
$expectedChat = Chat::fromArray($rawResponse);
|
||||
|
||||
$this->clientMock
|
||||
->expects($this->once())
|
||||
->method('request')
|
||||
->with('PATCH', $uri, [], $expectedBody)
|
||||
->willReturn($rawResponse);
|
||||
|
||||
$this->modelFactoryMock
|
||||
->expects($this->once())
|
||||
->method('createChat')
|
||||
->with($rawResponse)
|
||||
->willReturn($expectedChat);
|
||||
|
||||
$result = $this->api->editChat($chatId, $patch);
|
||||
$this->assertSame($expectedChat, $result);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function getVideoAttachmentDetailsCallsClientCorrectly(): void
|
||||
{
|
||||
$videoToken = 'some_video_token_xyz';
|
||||
$uri = sprintf('/videos/%s', $videoToken);
|
||||
|
||||
$rawResponse = [
|
||||
'token' => $videoToken,
|
||||
'width' => 1920,
|
||||
'height' => 1080,
|
||||
'duration' => 120,
|
||||
'urls' => ['mp4_1080' => 'http://example.com/video.mp4'],
|
||||
];
|
||||
$expectedDetails = VideoAttachmentDetails::fromArray($rawResponse);
|
||||
|
||||
$this->clientMock
|
||||
->expects($this->once())
|
||||
->method('request')
|
||||
->with('GET', $uri)
|
||||
->willReturn($rawResponse);
|
||||
|
||||
$this->modelFactoryMock
|
||||
->expects($this->once())
|
||||
->method('createVideoAttachmentDetails')
|
||||
->with($rawResponse)
|
||||
->willReturn($expectedDetails);
|
||||
|
||||
$result = $this->api->getVideoAttachmentDetails($videoToken);
|
||||
|
||||
$this->assertSame($expectedDetails, $result);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ use BushlanovDev\MaxMessengerBot\Attributes\ArrayOf;
|
||||
use BushlanovDev\MaxMessengerBot\Enums\ChatAdminPermission;
|
||||
use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
|
||||
use BushlanovDev\MaxMessengerBot\ModelFactory;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotCommand;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotInfo;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Chat;
|
||||
@@ -28,6 +29,8 @@ use BushlanovDev\MaxMessengerBot\Models\Updates\MessageChatCreatedUpdate;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Updates\MessageCreatedUpdate;
|
||||
use BushlanovDev\MaxMessengerBot\Models\UploadEndpoint;
|
||||
use BushlanovDev\MaxMessengerBot\Models\User;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoUrls;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
@@ -55,6 +58,9 @@ use PHPUnit\Framework\TestCase;
|
||||
#[UsesClass(ChatList::class)]
|
||||
#[UsesClass(ChatMember::class)]
|
||||
#[UsesClass(ChatMembersList::class)]
|
||||
#[UsesClass(VideoAttachmentDetails::class)]
|
||||
#[UsesClass(PhotoAttachmentRequestPayload::class)]
|
||||
#[UsesClass(VideoUrls::class)]
|
||||
final class ModelFactoryTest extends TestCase
|
||||
{
|
||||
private ModelFactory $factory;
|
||||
@@ -480,4 +486,24 @@ final class ModelFactoryTest extends TestCase
|
||||
$this->assertEmpty($list->members);
|
||||
$this->assertNull($list->marker);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function createVideoAttachmentDetailsSuccessfully(): void
|
||||
{
|
||||
$rawData = [
|
||||
'token' => 'vid_token',
|
||||
'width' => 1280,
|
||||
'height' => 720,
|
||||
'duration' => 60,
|
||||
'urls' => ['mp4_720' => 'http://a.com/720.mp4'],
|
||||
'thumbnail' => ['token' => 'thumb_token'],
|
||||
];
|
||||
|
||||
$details = $this->factory->createVideoAttachmentDetails($rawData);
|
||||
|
||||
$this->assertInstanceOf(VideoAttachmentDetails::class, $details);
|
||||
$this->assertSame('vid_token', $details->token);
|
||||
$this->assertInstanceOf(VideoUrls::class, $details->urls);
|
||||
$this->assertInstanceOf(PhotoAttachmentRequestPayload::class, $details->thumbnail);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotPatch;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(BotPatch::class)]
|
||||
#[UsesClass(PhotoAttachmentRequestPayload::class)]
|
||||
final class BotPatchTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function toArrayIncludesOnlyExplicitlySetFields(): void
|
||||
{
|
||||
$patch = new BotPatch(name: 'New Name');
|
||||
$this->assertEquals(['name' => 'New Name'], $patch->toArray());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function toArrayIncludesFieldsSetToNull(): void
|
||||
{
|
||||
$patch = new BotPatch(description: null);
|
||||
$this->assertEquals(['description' => null], $patch->toArray());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function toArrayHandlesMultipleSetFields(): void
|
||||
{
|
||||
$photoPayload = new PhotoAttachmentRequestPayload(token: 'photo123');
|
||||
$patch = new BotPatch(
|
||||
name: 'Updated Bot',
|
||||
description: null,
|
||||
photo: $photoPayload
|
||||
);
|
||||
|
||||
$expected = [
|
||||
'name' => 'Updated Bot',
|
||||
'description' => null,
|
||||
'photo' => [
|
||||
'url' => null,
|
||||
'token' => 'photo123',
|
||||
'photos' => null,
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $patch->toArray());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function toArrayIsEmptyWhenNoArgumentsPassed(): void
|
||||
{
|
||||
$patch = new BotPatch();
|
||||
$this->assertEmpty($patch->toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatPatch;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(ChatPatch::class)]
|
||||
#[UsesClass(PhotoAttachmentRequestPayload::class)]
|
||||
final class ChatPatchTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function toArrayIncludesOnlySetFields(): void
|
||||
{
|
||||
$patch = new ChatPatch(title: 'New Title');
|
||||
$this->assertEquals(['title' => 'New Title'], $patch->toArray());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function toArrayHandlesMultipleFields(): void
|
||||
{
|
||||
$photoPayload = new PhotoAttachmentRequestPayload(token: 'icon_token');
|
||||
$patch = new ChatPatch(
|
||||
title: 'Updated Chat',
|
||||
pin: 'mid.12345',
|
||||
icon: $photoPayload
|
||||
);
|
||||
|
||||
$expected = [
|
||||
'title' => 'Updated Chat',
|
||||
'pin' => 'mid.12345',
|
||||
'icon' => [
|
||||
'url' => null,
|
||||
'token' => 'icon_token',
|
||||
'photos' => null,
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertEquals($expected, $patch->toArray());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function toArrayIsEmptyForEmptyPatch(): void
|
||||
{
|
||||
$patch = new ChatPatch();
|
||||
$this->assertEmpty($patch->toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoUrls;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(VideoAttachmentDetails::class)]
|
||||
#[UsesClass(VideoUrls::class)]
|
||||
#[UsesClass(PhotoAttachmentRequestPayload::class)]
|
||||
final class VideoAttachmentDetailsTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedWithAllData(): void
|
||||
{
|
||||
$data = [
|
||||
'token' => 'video_token_123',
|
||||
'width' => 1920,
|
||||
'height' => 1080,
|
||||
'duration' => 125,
|
||||
'urls' => ['mp4_1080' => 'http://example.com/video.mp4'],
|
||||
'thumbnail' => ['token' => 'thumb_token_456'],
|
||||
];
|
||||
|
||||
$details = VideoAttachmentDetails::fromArray($data);
|
||||
|
||||
$this->assertInstanceOf(VideoAttachmentDetails::class, $details);
|
||||
$this->assertSame('video_token_123', $details->token);
|
||||
$this->assertSame(125, $details->duration);
|
||||
$this->assertInstanceOf(VideoUrls::class, $details->urls);
|
||||
$this->assertInstanceOf(PhotoAttachmentRequestPayload::class, $details->thumbnail);
|
||||
$this->assertSame('http://example.com/video.mp4', $details->urls->mp4_1080);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoUrls;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(VideoUrls::class)]
|
||||
final class VideoUrlsTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedWithAllFields(): void
|
||||
{
|
||||
$data = [
|
||||
'mp4_720' => 'http://example.com/video_720p.mp4',
|
||||
'mp4_480' => 'http://example.com/video_480p.mp4',
|
||||
];
|
||||
|
||||
$urls = VideoUrls::fromArray($data);
|
||||
|
||||
$this->assertInstanceOf(VideoUrls::class, $urls);
|
||||
$this->assertSame('http://example.com/video_720p.mp4', $urls->mp4_720);
|
||||
$this->assertNull($urls->mp4_1080);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user