mirror of
https://github.com/BushlanovDev/max-bot-api-client-php.git
synced 2026-08-19 06:13:19 +00:00
Added MessageStat & Attachments
This commit is contained in:
+88
-2
@@ -5,11 +5,32 @@ declare(strict_types=1);
|
||||
namespace BushlanovDev\MaxMessengerBot;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Enums\InlineButtonType;
|
||||
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
|
||||
use BushlanovDev\MaxMessengerBot\Enums\ReplyButtonType;
|
||||
use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\AbstractAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\AudioAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\AbstractInlineButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\CallbackButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\ChatButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\LinkButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\RequestContactButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\RequestGeoLocationButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\AbstractReplyButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\SendContactButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\SendGeoLocationButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\SendMessageButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\ContactAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\DataAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\FileAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\InlineKeyboardAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\LocationAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\PhotoAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\ReplyKeyboardAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\ShareAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\StickerAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\VideoAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotInfo;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Chat;
|
||||
use BushlanovDev\MaxMessengerBot\Models\ChatList;
|
||||
@@ -142,15 +163,80 @@ class ModelFactory
|
||||
*/
|
||||
public function createAttachment(array $data): AbstractAttachment
|
||||
{
|
||||
return match (AttachmentType::tryFrom($data['type'] ?? '')) {
|
||||
$attachmentType = AttachmentType::tryFrom($data['type'] ?? '');
|
||||
if ($attachmentType === AttachmentType::ReplyKeyboard
|
||||
&& isset($data['buttons']) && is_array($data['buttons'])) {
|
||||
$data['buttons'] = array_map(
|
||||
fn($rowOfButtons) => array_map([$this, 'createReplyButton'], $rowOfButtons),
|
||||
$data['buttons'],
|
||||
);
|
||||
}
|
||||
|
||||
if ($attachmentType === AttachmentType::InlineKeyboard
|
||||
&& isset($data['payload']['buttons']) && is_array($data['payload']['buttons'])) {
|
||||
$data['payload']['buttons'] = array_map(
|
||||
fn($rowOfButtons) => array_map([$this, 'createInlineButton'], $rowOfButtons),
|
||||
$data['payload']['buttons']
|
||||
);
|
||||
}
|
||||
|
||||
return match ($attachmentType) {
|
||||
AttachmentType::Data => DataAttachment::fromArray($data),
|
||||
AttachmentType::Share => ShareAttachment::fromArray($data),
|
||||
AttachmentType::Image => PhotoAttachment::fromArray($data),
|
||||
AttachmentType::Video => VideoAttachment::fromArray($data),
|
||||
AttachmentType::Audio => AudioAttachment::fromArray($data),
|
||||
AttachmentType::File => FileAttachment::fromArray($data),
|
||||
AttachmentType::Sticker => StickerAttachment::fromArray($data),
|
||||
AttachmentType::Contact => ContactAttachment::fromArray($data),
|
||||
AttachmentType::InlineKeyboard => InlineKeyboardAttachment::fromArray($data),
|
||||
AttachmentType::ReplyKeyboard => ReplyKeyboardAttachment::fromArray($data),
|
||||
AttachmentType::Location => LocationAttachment::fromArray($data),
|
||||
default => throw new LogicException("Unknown or unsupported attachment type: " . ($data['type'] ?? 'none')),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a specific ReplyButton model based on the 'type' field.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
*
|
||||
* @return AbstractReplyButton
|
||||
* @throws ReflectionException
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function createReplyButton(array $data): AbstractReplyButton
|
||||
{
|
||||
return match (ReplyButtonType::tryFrom($data['type'] ?? '')) {
|
||||
ReplyButtonType::Message => SendMessageButton::fromArray($data),
|
||||
ReplyButtonType::UserContact => SendContactButton::fromArray($data),
|
||||
ReplyButtonType::UserGeoLocation => SendGeoLocationButton::fromArray($data),
|
||||
default => throw new LogicException(
|
||||
'Unknown or unsupported Attachment type: ' . ($data['type'] ?? 'none')
|
||||
'Unknown or unsupported reply button type: ' . ($data['type'] ?? 'none')
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a specific InlineButton model based on the 'type' field.
|
||||
*
|
||||
* @param array<string, mixed> $data
|
||||
* @return AbstractInlineButton
|
||||
* @throws ReflectionException
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function createInlineButton(array $data): AbstractInlineButton
|
||||
{
|
||||
return match (InlineButtonType::tryFrom($data['type'] ?? '')) {
|
||||
InlineButtonType::Callback => CallbackButton::fromArray($data),
|
||||
InlineButtonType::Link => LinkButton::fromArray($data),
|
||||
InlineButtonType::RequestContact => RequestContactButton::fromArray($data),
|
||||
InlineButtonType::RequestGeoLocation => RequestGeoLocationButton::fromArray($data),
|
||||
InlineButtonType::Chat => ChatButton::fromArray($data),
|
||||
default => throw new LogicException("Unknown or unsupported inline button type: " . ($data['type'] ?? 'none')),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* List of messages.
|
||||
*
|
||||
|
||||
@@ -137,7 +137,7 @@ abstract readonly class AbstractModel
|
||||
return $typeName::from($value);
|
||||
}
|
||||
|
||||
if (is_subclass_of($typeName, self::class)) {
|
||||
if (is_subclass_of($typeName, self::class) && is_array($value)) {
|
||||
return $typeName::fromArray($value);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\MediaAttachmentPayload;
|
||||
|
||||
final readonly class AudioAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param MediaAttachmentPayload $payload Audio attachment payload.
|
||||
* @param string|null $transcription Audio transcription.
|
||||
*/
|
||||
public function __construct(
|
||||
public MediaAttachmentPayload $payload,
|
||||
public ?string $transcription,
|
||||
) {
|
||||
parent::__construct(AttachmentType::Audio);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\ContactAttachmentPayload;
|
||||
|
||||
final readonly class ContactAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param ContactAttachmentPayload $payload Contact attachment payload.
|
||||
*/
|
||||
public function __construct(public ContactAttachmentPayload $payload)
|
||||
{
|
||||
parent::__construct(AttachmentType::Contact);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\FileAttachmentPayload;
|
||||
|
||||
final readonly class FileAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param FileAttachmentPayload $payload File attachment payload.
|
||||
* @param string $filename Uploaded file name.
|
||||
* @param int $size File size in bytes.
|
||||
*/
|
||||
public function __construct(
|
||||
public FileAttachmentPayload $payload,
|
||||
public string $filename,
|
||||
public int $size,
|
||||
) {
|
||||
parent::__construct(AttachmentType::File);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\KeyboardPayload;
|
||||
|
||||
final readonly class InlineKeyboardAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param KeyboardPayload $payload Keyboard payload.
|
||||
*/
|
||||
public function __construct(public KeyboardPayload $payload) {
|
||||
parent::__construct(AttachmentType::InlineKeyboard);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
|
||||
final readonly class LocationAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param float $latitude
|
||||
* @param float $longitude
|
||||
*/
|
||||
public function __construct(
|
||||
public float $latitude,
|
||||
public float $longitude,
|
||||
) {
|
||||
parent::__construct(AttachmentType::Location);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
use BushlanovDev\MaxMessengerBot\Models\User;
|
||||
|
||||
/**
|
||||
* Payload of a contact attachment.
|
||||
*/
|
||||
final readonly class ContactAttachmentPayload extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param string|null $vcfInfo User info in VCF format.
|
||||
* @param User|null $maxInfo User info if the contact is a Max user.
|
||||
*/
|
||||
public function __construct(
|
||||
public ?string $vcfInfo,
|
||||
public ?User $maxInfo,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
|
||||
/**
|
||||
* Payload for a file attachment.
|
||||
*/
|
||||
final readonly class FileAttachmentPayload extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param string $url Media attachment URL.
|
||||
* @param string $token Token to reuse the same attachment in other messages.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $url,
|
||||
public string $token,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\AbstractInlineButton;
|
||||
|
||||
/**
|
||||
* Represents an inline keyboard structure.
|
||||
*/
|
||||
final readonly class KeyboardPayload extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param AbstractInlineButton[][] $buttons Two-dimensional array of buttons.
|
||||
*/
|
||||
public function __construct(public array $buttons)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
|
||||
/**
|
||||
* Payload for media attachments like audio or video.
|
||||
*/
|
||||
final readonly class MediaAttachmentPayload extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param string $url Media attachment URL.
|
||||
* @param string $token Token to reuse the same attachment in other messages.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $url,
|
||||
public string $token,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
|
||||
/**
|
||||
* Payload for a photo attachment.
|
||||
*/
|
||||
final readonly class PhotoAttachmentPayload extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param string $url Media attachment URL.
|
||||
* @param string $token Token to reuse the same attachment in other messages.
|
||||
* @param int $photoId Unique identifier of this image.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $url,
|
||||
public string $token,
|
||||
public int $photoId,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
|
||||
/**
|
||||
* Payload for a sticker attachment.
|
||||
*/
|
||||
final readonly class StickerAttachmentPayload extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param string $url Media attachment URL.
|
||||
* @param string $code Sticker identifier.
|
||||
*/
|
||||
public function __construct(
|
||||
public string $url,
|
||||
public string $code,
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
|
||||
/**
|
||||
* Represents a video thumbnail image.
|
||||
*/
|
||||
final readonly class VideoThumbnail extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param string $url Media attachment URL.
|
||||
*/
|
||||
public function __construct(public string $url)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentPayload;
|
||||
|
||||
final readonly class PhotoAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param PhotoAttachmentPayload $payload Photo attachment payload.
|
||||
*/
|
||||
public function __construct(public PhotoAttachmentPayload $payload)
|
||||
{
|
||||
parent::__construct(AttachmentType::Image);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\AbstractReplyButton;
|
||||
|
||||
final readonly class ReplyKeyboardAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param AbstractReplyButton[][] $buttons
|
||||
*/
|
||||
public function __construct(public array $buttons) {
|
||||
parent::__construct(AttachmentType::ReplyKeyboard);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\StickerAttachmentPayload;
|
||||
|
||||
final readonly class StickerAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param StickerAttachmentPayload $payload Sticker attachment payload.
|
||||
* @param int $width
|
||||
* @param int $height
|
||||
*/
|
||||
public function __construct(
|
||||
public StickerAttachmentPayload $payload,
|
||||
public int $width,
|
||||
public int $height,
|
||||
) {
|
||||
parent::__construct(AttachmentType::Sticker);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\MediaAttachmentPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\VideoThumbnail;
|
||||
|
||||
final readonly class VideoAttachment extends AbstractAttachment
|
||||
{
|
||||
/**
|
||||
* @param MediaAttachmentPayload $payload Video attachment payload.
|
||||
* @param VideoThumbnail|null $thumbnail Video thumbnail.
|
||||
* @param int|null $width Video width.
|
||||
* @param int|null $height Video height.
|
||||
* @param int|null $duration Video duration in seconds.
|
||||
*/
|
||||
public function __construct(
|
||||
public MediaAttachmentPayload $payload,
|
||||
public ?VideoThumbnail $thumbnail,
|
||||
public ?int $width,
|
||||
public ?int $height,
|
||||
public ?int $duration,
|
||||
) {
|
||||
parent::__construct(AttachmentType::Video);
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ final readonly class Message extends AbstractModel
|
||||
* @param User|null $sender User who sent this message. Can be null if message has been posted on behalf of a channel.
|
||||
* @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 MessageStat|null $stat Message statistics. Available only for channels.
|
||||
*/
|
||||
public function __construct(
|
||||
public int $timestamp,
|
||||
@@ -24,6 +25,7 @@ final readonly class Message extends AbstractModel
|
||||
public ?User $sender,
|
||||
public ?string $url,
|
||||
public ?LinkedMessage $link,
|
||||
public ?MessageStat $stat,
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Models;
|
||||
|
||||
/**
|
||||
* Message statistics.
|
||||
*/
|
||||
final readonly class MessageStat extends AbstractModel
|
||||
{
|
||||
/**
|
||||
* @param int $views Number of views.
|
||||
*/
|
||||
public function __construct(public int $views)
|
||||
{
|
||||
}
|
||||
}
|
||||
+195
-5
@@ -9,9 +9,24 @@ use BushlanovDev\MaxMessengerBot\Enums\ChatAdminPermission;
|
||||
use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
|
||||
use BushlanovDev\MaxMessengerBot\ModelFactory;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\AbstractAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\AbstractInlineButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\CallbackButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\ChatButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\LinkButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\RequestContactButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\RequestGeoLocationButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\AbstractReplyButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\SendContactButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\SendMessageButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\DataAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\InlineKeyboardAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\LocationAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\KeyboardPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\ShareAttachmentRequestPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\PhotoAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\ReplyKeyboardAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\ShareAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotCommand;
|
||||
use BushlanovDev\MaxMessengerBot\Models\BotInfo;
|
||||
@@ -40,6 +55,7 @@ use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
|
||||
use BushlanovDev\MaxMessengerBot\Models\VideoUrls;
|
||||
use LogicException;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
@@ -76,6 +92,21 @@ use PHPUnit\Framework\TestCase;
|
||||
#[UsesClass(LinkMarkup::class)]
|
||||
#[UsesClass(AbstractMarkup::class)]
|
||||
#[UsesClass(StrongMarkup::class)]
|
||||
#[UsesClass(PhotoAttachmentPayload::class)]
|
||||
#[UsesClass(PhotoAttachment::class)]
|
||||
#[UsesClass(AbstractReplyButton::class)]
|
||||
#[UsesClass(SendContactButton::class)]
|
||||
#[UsesClass(SendMessageButton::class)]
|
||||
#[UsesClass(ReplyKeyboardAttachment::class)]
|
||||
#[UsesClass(AbstractInlineButton::class)]
|
||||
#[UsesClass(ChatButton::class)]
|
||||
#[UsesClass(RequestContactButton::class)]
|
||||
#[UsesClass(CallbackButton::class)]
|
||||
#[UsesClass(RequestGeoLocationButton::class)]
|
||||
#[UsesClass(LinkButton::class)]
|
||||
#[UsesClass(LocationAttachment::class)]
|
||||
#[UsesClass(InlineKeyboardAttachment::class)]
|
||||
#[UsesClass(KeyboardPayload::class)]
|
||||
final class ModelFactoryTest extends TestCase
|
||||
{
|
||||
private ModelFactory $factory;
|
||||
@@ -540,6 +571,7 @@ final class ModelFactoryTest extends TestCase
|
||||
'description' => null,
|
||||
'image_url' => null,
|
||||
],
|
||||
['type' => 'image', 'payload' => ['photo_id' => 1, 'token' => 't', 'url' => 'u']]
|
||||
],
|
||||
'markup' => null,
|
||||
],
|
||||
@@ -548,17 +580,21 @@ final class ModelFactoryTest extends TestCase
|
||||
];
|
||||
|
||||
$message = $this->factory->createMessage($rawData);
|
||||
$attachments = $message->body->attachments;
|
||||
|
||||
$this->assertInstanceOf(Message::class, $message);
|
||||
$this->assertInstanceOf(MessageBody::class, $message->body);
|
||||
$this->assertIsArray($message->body->attachments);
|
||||
$this->assertCount(2, $message->body->attachments);
|
||||
$this->assertIsArray($attachments);
|
||||
$this->assertCount(3, $attachments);
|
||||
|
||||
$this->assertInstanceOf(DataAttachment::class, $message->body->attachments[0]);
|
||||
$this->assertSame('payload_from_reply_button', $message->body->attachments[0]->data);
|
||||
$this->assertInstanceOf(DataAttachment::class, $attachments[0]);
|
||||
$this->assertSame('payload_from_reply_button', $attachments[0]->data);
|
||||
|
||||
$this->assertInstanceOf(ShareAttachment::class, $message->body->attachments[1]);
|
||||
$this->assertSame('Test Share', $message->body->attachments[1]->title);
|
||||
$this->assertSame('Test Share', $attachments[1]->title);
|
||||
|
||||
$this->assertInstanceOf(PhotoAttachment::class, $attachments[2]);
|
||||
$this->assertSame(1, $attachments[2]->payload->photoId);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
@@ -598,4 +634,158 @@ final class ModelFactoryTest extends TestCase
|
||||
|
||||
$this->factory->createMarkupElement(['type' => 'brand_new_unsupported_type']);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function createAttachmentCorrectlyHydratesReplyKeyboard(): void
|
||||
{
|
||||
$data = [
|
||||
'type' => 'reply_keyboard',
|
||||
'buttons' => [
|
||||
[['type' => 'message', 'text' => 'Hello']],
|
||||
[['type' => 'user_contact', 'text' => 'My Contact']]
|
||||
]
|
||||
];
|
||||
|
||||
$attachment = $this->factory->createAttachment($data);
|
||||
|
||||
$this->assertInstanceOf(ReplyKeyboardAttachment::class, $attachment);
|
||||
$this->assertCount(2, $attachment->buttons);
|
||||
$this->assertInstanceOf(SendMessageButton::class, $attachment->buttons[0][0]);
|
||||
$this->assertInstanceOf(SendContactButton::class, $attachment->buttons[1][0]);
|
||||
$this->assertSame('My Contact', $attachment->buttons[1][0]->text);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function createReplyButtonThrowsExceptionForUnknownType(): void
|
||||
{
|
||||
$this->expectException(LogicException::class);
|
||||
$this->expectExceptionMessage('Unknown or unsupported reply button type: new_fancy_button');
|
||||
|
||||
$this->factory->createReplyButton(['type' => 'new_fancy_button']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for successful inline button creation.
|
||||
* @return array<string, array{0: array<string, mixed>, 1: class-string}>
|
||||
*/
|
||||
public static function inlineButtonProvider(): array
|
||||
{
|
||||
return [
|
||||
'CallbackButton' => [
|
||||
['type' => 'callback', 'text' => 'Press', 'payload' => 'p'],
|
||||
CallbackButton::class,
|
||||
],
|
||||
'LinkButton' => [
|
||||
['type' => 'link', 'text' => 'Visit', 'url' => 'https://a.com'],
|
||||
LinkButton::class,
|
||||
],
|
||||
'RequestContactButton' => [
|
||||
['type' => 'request_contact', 'text' => 'Share Contact'],
|
||||
RequestContactButton::class,
|
||||
],
|
||||
'RequestGeoLocationButton' => [
|
||||
['type' => 'request_geo_location', 'text' => 'Share Location', 'quick' => false],
|
||||
RequestGeoLocationButton::class,
|
||||
],
|
||||
'ChatButton' => [
|
||||
['type' => 'chat', 'text' => 'Join Chat', 'chat_title' => 'My Chat'],
|
||||
ChatButton::class,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[DataProvider('inlineButtonProvider')]
|
||||
public function createInlineButtonSuccessfully(array $data, string $expectedClass): void
|
||||
{
|
||||
$button = $this->factory->createInlineButton($data);
|
||||
|
||||
$this->assertInstanceOf($expectedClass, $button);
|
||||
$this->assertSame($data['text'], $button->text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for invalid inline button data.
|
||||
* @return array<string, array{0: array<string, mixed>, 1: string}>
|
||||
*/
|
||||
public static function invalidInlineButtonProvider(): array
|
||||
{
|
||||
return [
|
||||
'unknown type' => [
|
||||
['type' => 'unknown_button_type', 'text' => 'Unknown'],
|
||||
'Unknown or unsupported inline button type: unknown_button_type',
|
||||
],
|
||||
'missing type' => [
|
||||
['text' => 'No type here'],
|
||||
'Unknown or unsupported inline button type: none',
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[DataProvider('invalidInlineButtonProvider')]
|
||||
public function createInlineButtonThrowsExceptionForInvalidType(array $invalidData, string $expectedMessage): void
|
||||
{
|
||||
$this->expectException(LogicException::class);
|
||||
$this->expectExceptionMessage($expectedMessage);
|
||||
|
||||
$this->factory->createInlineButton($invalidData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for testing various attachment types in createAttachment.
|
||||
* @return array<string, array{0: array<string, mixed>, 1: class-string, 2: callable}>
|
||||
*/
|
||||
public static function attachmentTypeProvider(): array
|
||||
{
|
||||
return [
|
||||
'Data Attachment' => [
|
||||
['type' => 'data', 'data' => 'test_payload'],
|
||||
DataAttachment::class,
|
||||
function (TestCase $test, DataAttachment $attachment) {
|
||||
$test->assertSame('test_payload', $attachment->data);
|
||||
}
|
||||
],
|
||||
|
||||
'Location Attachment' => [
|
||||
['type' => 'location', 'latitude' => 55.751244, 'longitude' => 37.618423],
|
||||
LocationAttachment::class,
|
||||
function (TestCase $test, LocationAttachment $attachment) {
|
||||
$test->assertSame(55.751244, $attachment->latitude);
|
||||
}
|
||||
],
|
||||
|
||||
'Inline Keyboard Attachment' => [
|
||||
[
|
||||
'type' => 'inline_keyboard',
|
||||
'payload' => [
|
||||
'buttons' => [
|
||||
[['type' => 'callback', 'text' => 'Test', 'payload' => 'p']]
|
||||
]
|
||||
]
|
||||
],
|
||||
InlineKeyboardAttachment::class,
|
||||
function (TestCase $test, InlineKeyboardAttachment $attachment) {
|
||||
$test->assertInstanceOf(KeyboardPayload::class, $attachment->payload);
|
||||
$test->assertIsArray($attachment->payload->buttons);
|
||||
$test->assertInstanceOf(CallbackButton::class, $attachment->payload->buttons[0][0]);
|
||||
$test->assertSame('p', $attachment->payload->buttons[0][0]->payload);
|
||||
}
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[DataProvider('attachmentTypeProvider')]
|
||||
public function createAttachmentSuccessfullyCreatesVariousTypes(
|
||||
array $data,
|
||||
string $expectedClass,
|
||||
callable $assertionCallback,
|
||||
): void {
|
||||
$attachment = $this->factory->createAttachment($data);
|
||||
|
||||
$this->assertInstanceOf($expectedClass, $attachment);
|
||||
|
||||
$assertionCallback($this, $attachment);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,9 +7,11 @@ namespace BushlanovDev\MaxMessengerBot\Tests\Models;
|
||||
use BushlanovDev\MaxMessengerBot\Attributes\ArrayOf;
|
||||
use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
use DateTimeInterface;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use ReflectionClass;
|
||||
use stdClass;
|
||||
|
||||
#[CoversClass(AbstractModel::class)]
|
||||
@@ -176,6 +178,30 @@ final class AbstractModelMappingTest extends TestCase
|
||||
$this->assertEquals($expectedArray, $resultArray);
|
||||
$this->assertArrayNotHasKey('uninitialized_prop', $resultArray);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function castValueReturnsValueAsIsForUnmanagedScalarAssignedToObjectType(): void
|
||||
{
|
||||
$dateString = '2025-08-26';
|
||||
|
||||
$reflectionClass = new ReflectionClass(ModelForUnmanagedType::class);
|
||||
$abstractModelReflection = $reflectionClass->getParentClass();
|
||||
$castValueMethod = $abstractModelReflection->getMethod('castValue');
|
||||
$castValueMethod->setAccessible(true);
|
||||
|
||||
$property = $reflectionClass->getProperty('eventDate');
|
||||
|
||||
$result = $castValueMethod->invoke(null, $dateString, $property);
|
||||
|
||||
$this->assertSame($dateString, $result);
|
||||
}
|
||||
}
|
||||
|
||||
final readonly class ModelForUnmanagedType extends AbstractModel
|
||||
{
|
||||
public function __construct(public DateTimeInterface $eventDate)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
final readonly class DummyModelForUninitializedProperty extends AbstractModel
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\AudioAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\MediaAttachmentPayload;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(AudioAttachment::class)]
|
||||
#[UsesClass(MediaAttachmentPayload::class)]
|
||||
final class AudioAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArray(): void
|
||||
{
|
||||
$data = ['type' => 'audio', 'payload' => ['url' => 'u', 'token' => 't'], 'transcription' => 'Hello world.'];
|
||||
$attachment = AudioAttachment::fromArray($data);
|
||||
$this->assertInstanceOf(AudioAttachment::class, $attachment);
|
||||
$this->assertSame('Hello world.', $attachment->transcription);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\ContactAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\ContactAttachmentPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\User;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(ContactAttachment::class)]
|
||||
#[UsesClass(ContactAttachmentPayload::class)]
|
||||
#[UsesClass(User::class)]
|
||||
final class ContactAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArray(): void
|
||||
{
|
||||
$data = ['type' => 'contact', 'payload' => ['vcf_info' => 'vcf', 'max_info' => null]];
|
||||
$attachment = ContactAttachment::fromArray($data);
|
||||
$this->assertInstanceOf(ContactAttachment::class, $attachment);
|
||||
$this->assertSame('vcf', $attachment->payload->vcfInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\FileAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\FileAttachmentPayload;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(FileAttachment::class)]
|
||||
#[UsesClass(FileAttachmentPayload::class)]
|
||||
final class FileAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArray(): void
|
||||
{
|
||||
$data = [
|
||||
'type' => 'file',
|
||||
'payload' => ['url' => 'u', 'token' => 't'],
|
||||
'filename' => 'doc.pdf',
|
||||
'size' => 1024,
|
||||
];
|
||||
$attachment = FileAttachment::fromArray($data);
|
||||
$this->assertInstanceOf(FileAttachment::class, $attachment);
|
||||
$this->assertSame('doc.pdf', $attachment->filename);
|
||||
$this->assertSame(1024, $attachment->size);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\CallbackButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\InlineKeyboardAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\KeyboardPayload;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(InlineKeyboardAttachment::class)]
|
||||
#[UsesClass(KeyboardPayload::class)]
|
||||
#[UsesClass(CallbackButton::class)]
|
||||
final class InlineKeyboardAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArray(): void
|
||||
{
|
||||
$data = [
|
||||
'type' => 'inline_keyboard',
|
||||
'payload' => ['buttons' => [[['type' => 'callback', 'text' => 'Press', 'payload' => 'p']]]],
|
||||
];
|
||||
$attachment = InlineKeyboardAttachment::fromArray($data);
|
||||
$this->assertInstanceOf(InlineKeyboardAttachment::class, $attachment);
|
||||
$this->assertInstanceOf(KeyboardPayload::class, $attachment->payload);
|
||||
$this->assertCount(1, $attachment->payload->buttons);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\LocationAttachment;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(LocationAttachment::class)]
|
||||
final class LocationAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArray(): void
|
||||
{
|
||||
$data = ['type' => 'location', 'latitude' => 55.75, 'longitude' => 37.61];
|
||||
$attachment = LocationAttachment::fromArray($data);
|
||||
$this->assertInstanceOf(LocationAttachment::class, $attachment);
|
||||
$this->assertSame(55.75, $attachment->latitude);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\ContactAttachmentPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\User;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(ContactAttachmentPayload::class)]
|
||||
#[UsesClass(User::class)]
|
||||
final class ContactAttachmentPayloadTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedAndSerialized(): void
|
||||
{
|
||||
$user = User::fromArray(
|
||||
['user_id' => 101, 'first_name' => 'MaxUser', 'is_bot' => false, 'last_activity_time' => time()]
|
||||
);
|
||||
$payload = new ContactAttachmentPayload('vcf_info_string', $user);
|
||||
$this->assertSame('vcf_info_string', $payload->vcfInfo);
|
||||
$this->assertSame($user, $payload->maxInfo);
|
||||
$this->assertEquals(['vcf_info' => 'vcf_info_string', 'max_info' => $user->toArray()], $payload->toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\FileAttachmentPayload;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(FileAttachmentPayload::class)]
|
||||
final class FileAttachmentPayloadTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedAndSerialized(): void
|
||||
{
|
||||
$payload = new FileAttachmentPayload('https://example.com/doc.pdf', 'file_token_456');
|
||||
$this->assertSame('https://example.com/doc.pdf', $payload->url);
|
||||
$this->assertSame('file_token_456', $payload->token);
|
||||
$this->assertEquals(['url' => 'https://example.com/doc.pdf', 'token' => 'file_token_456'], $payload->toArray());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\ModelFactory;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\AbstractAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\AbstractInlineButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\CallbackButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Inline\LinkButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\InlineKeyboardAttachment;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\KeyboardPayload;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(KeyboardPayload::class)]
|
||||
#[UsesClass(ModelFactory::class)]
|
||||
#[UsesClass(AbstractAttachment::class)]
|
||||
#[UsesClass(AbstractInlineButton::class)]
|
||||
#[UsesClass(CallbackButton::class)]
|
||||
#[UsesClass(LinkButton::class)]
|
||||
#[UsesClass(InlineKeyboardAttachment::class)]
|
||||
final class KeyboardPayloadTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArrayViaFactory(): void
|
||||
{
|
||||
$data = [
|
||||
'type' => 'inline_keyboard',
|
||||
'payload' => [
|
||||
'buttons' => [
|
||||
[
|
||||
['type' => 'callback', 'text' => 'Press Me', 'payload' => 'payload_123'],
|
||||
],
|
||||
[
|
||||
['type' => 'link', 'text' => 'Docs', 'url' => 'https://dev.max.ru'],
|
||||
['type' => 'callback', 'text' => 'Cancel', 'payload' => 'cancel_op'],
|
||||
],
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
$factory = new ModelFactory();
|
||||
$attachment = $factory->createAttachment($data);
|
||||
|
||||
$this->assertInstanceOf(InlineKeyboardAttachment::class, $attachment);
|
||||
$this->assertInstanceOf(KeyboardPayload::class, $attachment->payload);
|
||||
|
||||
$buttons = $attachment->payload->buttons;
|
||||
$this->assertCount(2, $buttons);
|
||||
|
||||
$this->assertCount(1, $buttons[0]);
|
||||
$this->assertInstanceOf(CallbackButton::class, $buttons[0][0]);
|
||||
$this->assertSame('payload_123', $buttons[0][0]->payload);
|
||||
|
||||
$this->assertCount(2, $buttons[1]);
|
||||
$this->assertInstanceOf(LinkButton::class, $buttons[1][0]);
|
||||
$this->assertSame('https://dev.max.ru', $buttons[1][0]->url);
|
||||
$this->assertInstanceOf(CallbackButton::class, $buttons[1][1]);
|
||||
$this->assertSame('cancel_op', $buttons[1][1]->payload);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\MediaAttachmentPayload;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(MediaAttachmentPayload::class)]
|
||||
final class MediaAttachmentPayloadTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedAndSerialized(): void
|
||||
{
|
||||
$payload = new MediaAttachmentPayload('https://example.com/video.mp4', 'video_token_123');
|
||||
$this->assertSame('https://example.com/video.mp4', $payload->url);
|
||||
$this->assertSame('video_token_123', $payload->token);
|
||||
$this->assertEquals(
|
||||
['url' => 'https://example.com/video.mp4', 'token' => 'video_token_123'],
|
||||
$payload->toArray(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -4,105 +4,33 @@ declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Attributes\ArrayOf;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoToken;
|
||||
use InvalidArgumentException;
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentPayload;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\DataProvider;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(PhotoAttachmentRequestPayload::class)]
|
||||
#[UsesClass(PhotoToken::class)]
|
||||
#[UsesClass(ArrayOf::class)]
|
||||
#[CoversClass(PhotoAttachmentPayload::class)]
|
||||
#[UsesClass(AbstractModel::class)]
|
||||
final class PhotoAttachmentPayloadTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedWithUrlOnly(): void
|
||||
public function canBeCreatedAndSerialized(): void
|
||||
{
|
||||
$payload = new PhotoAttachmentRequestPayload(url: 'https://example.com/photo.jpg');
|
||||
|
||||
$this->assertSame('https://example.com/photo.jpg', $payload->url);
|
||||
$this->assertNull($payload->token);
|
||||
$this->assertNull($payload->photos);
|
||||
|
||||
$expectedArray = [
|
||||
'url' => 'https://example.com/photo.jpg',
|
||||
'token' => null,
|
||||
'photos' => null,
|
||||
$data = [
|
||||
'photo_id' => 987654321,
|
||||
'token' => 'some_received_photo_token',
|
||||
'url' => 'https://cdn.max.ru/photos/image.jpg'
|
||||
];
|
||||
$this->assertEquals($expectedArray, $payload->toArray());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function canBeCreatedWithTokenOnly(): void
|
||||
{
|
||||
$payload = new PhotoAttachmentRequestPayload(token: 'uploaded_token_abc');
|
||||
$payload = PhotoAttachmentPayload::fromArray($data);
|
||||
|
||||
$this->assertSame('uploaded_token_abc', $payload->token);
|
||||
$this->assertNull($payload->url);
|
||||
$this->assertNull($payload->photos);
|
||||
$this->assertInstanceOf(PhotoAttachmentPayload::class, $payload);
|
||||
$this->assertSame(987654321, $payload->photoId);
|
||||
$this->assertSame('some_received_photo_token', $payload->token);
|
||||
$this->assertSame('https://cdn.max.ru/photos/image.jpg', $payload->url);
|
||||
|
||||
$expectedArray = [
|
||||
'token' => 'uploaded_token_abc',
|
||||
'url' => null,
|
||||
'photos' => null,
|
||||
];
|
||||
$this->assertEquals($expectedArray, $payload->toArray());
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function canBeCreatedWithPhotosOnly(): void
|
||||
{
|
||||
$photos = [
|
||||
new PhotoToken('token_1'),
|
||||
new PhotoToken('token_2'),
|
||||
];
|
||||
$payload = new PhotoAttachmentRequestPayload(photos: $photos);
|
||||
|
||||
$this->assertSame($photos, $payload->photos);
|
||||
$this->assertNull($payload->url);
|
||||
$this->assertNull($payload->token);
|
||||
|
||||
$expectedArray = [
|
||||
'photos' => [
|
||||
['token' => 'token_1'],
|
||||
['token' => 'token_2'],
|
||||
],
|
||||
'url' => null,
|
||||
'token' => null,
|
||||
];
|
||||
$this->assertEquals($expectedArray, $payload->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for invalid constructor arguments.
|
||||
*
|
||||
* @return array<string, array{0: string|null, 1: string|null, 2: array|null}>
|
||||
*/
|
||||
public static function invalidPayloadProvider(): array
|
||||
{
|
||||
return [
|
||||
'all null (no arguments)' => [null, null, null],
|
||||
'url and token provided' => ['https://a.com', 'token123', null],
|
||||
'url and photos provided' => ['https://a.com', null, [new PhotoToken('t')]],
|
||||
'token and photos provided' => [null, 'token123', [new PhotoToken('t')]],
|
||||
'all three arguments provided' => ['https://a.com', 'token123', [new PhotoToken('t')]],
|
||||
];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[DataProvider('invalidPayloadProvider')]
|
||||
public function constructorThrowsExceptionForInvalidArguments(
|
||||
?string $url,
|
||||
?string $token,
|
||||
?array $photos
|
||||
): void {
|
||||
$this->expectException(InvalidArgumentException::class);
|
||||
$this->expectExceptionMessage('Provide exactly one of "url", "token", or "photos" for PhotoAttachmentRequestPayload.');
|
||||
|
||||
new PhotoAttachmentRequestPayload($url, $token, $photos);
|
||||
$this->assertEquals($data, $payload->toArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\StickerAttachmentPayload;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(StickerAttachmentPayload::class)]
|
||||
final class StickerAttachmentPayloadTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedAndSerialized(): void
|
||||
{
|
||||
$payload = new StickerAttachmentPayload('https://example.com/sticker.webp', 'sticker_code_abc');
|
||||
$this->assertSame('https://example.com/sticker.webp', $payload->url);
|
||||
$this->assertSame('sticker_code_abc', $payload->code);
|
||||
$this->assertEquals(
|
||||
['url' => 'https://example.com/sticker.webp', 'code' => 'sticker_code_abc'],
|
||||
$payload->toArray(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments\Payloads;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\VideoThumbnail;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(VideoThumbnail::class)]
|
||||
#[UsesClass(AbstractModel::class)]
|
||||
final class VideoThumbnailTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedAndSerialized(): void
|
||||
{
|
||||
$data = [
|
||||
'url' => 'https://example.com/video_thumbnail.jpg',
|
||||
];
|
||||
|
||||
$thumbnail = VideoThumbnail::fromArray($data);
|
||||
|
||||
$this->assertInstanceOf(VideoThumbnail::class, $thumbnail);
|
||||
$this->assertSame('https://example.com/video_thumbnail.jpg', $thumbnail->url);
|
||||
|
||||
$this->assertEquals($data, $thumbnail->toArray());
|
||||
|
||||
$directInstance = new VideoThumbnail('https://example.com/video_thumbnail.jpg');
|
||||
$this->assertSame('https://example.com/video_thumbnail.jpg', $directInstance->url);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\PhotoAttachment;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(PhotoAttachment::class)]
|
||||
#[UsesClass(PhotoAttachmentPayload::class)]
|
||||
final class PhotoAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArray(): void
|
||||
{
|
||||
$data = ['type' => 'image', 'payload' => ['photo_id' => 1, 'token' => 't', 'url' => 'u']];
|
||||
$attachment = PhotoAttachment::fromArray($data);
|
||||
$this->assertInstanceOf(PhotoAttachment::class, $attachment);
|
||||
$this->assertInstanceOf(PhotoAttachmentPayload::class, $attachment->payload);
|
||||
$this->assertSame(1, $attachment->payload->photoId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\ModelFactory;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\AbstractReplyButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\SendContactButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Buttons\Reply\SendMessageButton;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\ReplyKeyboardAttachment;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(ReplyKeyboardAttachment::class)]
|
||||
#[UsesClass(AbstractReplyButton::class)]
|
||||
#[UsesClass(SendContactButton::class)]
|
||||
#[UsesClass(SendMessageButton::class)]
|
||||
#[UsesClass(ModelFactory::class)]
|
||||
final class ReplyKeyboardAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArrayViaFactory(): void
|
||||
{
|
||||
$data = [
|
||||
'type' => 'reply_keyboard',
|
||||
'buttons' => [
|
||||
[['type' => 'message', 'text' => 'Hello']],
|
||||
[['type' => 'user_contact', 'text' => 'My Contact']]
|
||||
]
|
||||
];
|
||||
|
||||
$factory = new ModelFactory();
|
||||
$attachment = $factory->createAttachment($data);
|
||||
|
||||
$this->assertInstanceOf(ReplyKeyboardAttachment::class, $attachment);
|
||||
$this->assertCount(2, $attachment->buttons);
|
||||
$this->assertInstanceOf(SendContactButton::class, $attachment->buttons[1][0]);
|
||||
$this->assertSame('My Contact', $attachment->buttons[1][0]->text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\StickerAttachmentPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\StickerAttachment;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(StickerAttachment::class)]
|
||||
#[UsesClass(StickerAttachmentPayload::class)]
|
||||
final class StickerAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArray(): void
|
||||
{
|
||||
$data = ['type' => 'sticker', 'payload' => ['url' => 'u', 'code' => 'c'], 'width' => 128, 'height' => 128];
|
||||
$attachment = StickerAttachment::fromArray($data);
|
||||
$this->assertInstanceOf(StickerAttachment::class, $attachment);
|
||||
$this->assertSame(128, $attachment->width);
|
||||
$this->assertSame('c', $attachment->payload->code);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\MediaAttachmentPayload;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\VideoThumbnail;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Attachments\VideoAttachment;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\Attributes\UsesClass;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(VideoAttachment::class)]
|
||||
#[UsesClass(MediaAttachmentPayload::class)]
|
||||
#[UsesClass(VideoThumbnail::class)]
|
||||
final class VideoAttachmentTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedFromArray(): void
|
||||
{
|
||||
$data = [
|
||||
'type' => 'video',
|
||||
'payload' => ['url' => 'u', 'token' => 't'],
|
||||
'thumbnail' => ['url' => 'thumb_url'],
|
||||
'width' => 1920,
|
||||
'height' => 1080,
|
||||
'duration' => 120,
|
||||
];
|
||||
$attachment = VideoAttachment::fromArray($data);
|
||||
$this->assertInstanceOf(VideoAttachment::class, $attachment);
|
||||
$this->assertInstanceOf(MediaAttachmentPayload::class, $attachment->payload);
|
||||
$this->assertInstanceOf(VideoThumbnail::class, $attachment->thumbnail);
|
||||
$this->assertSame(120, $attachment->duration);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
|
||||
|
||||
use BushlanovDev\MaxMessengerBot\Models\MessageStat;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
#[CoversClass(MessageStat::class)]
|
||||
final class MessageStatTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function canBeCreatedAndSerialized(): void
|
||||
{
|
||||
$data = ['views' => 1234];
|
||||
$stat = MessageStat::fromArray($data);
|
||||
|
||||
$this->assertInstanceOf(MessageStat::class, $stat);
|
||||
$this->assertSame(1234, $stat->views);
|
||||
$this->assertEquals($data, $stat->toArray());
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ namespace BushlanovDev\MaxMessengerBot\Tests\Models;
|
||||
use BushlanovDev\MaxMessengerBot\Models\LinkedMessage;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Message;
|
||||
use BushlanovDev\MaxMessengerBot\Models\MessageBody;
|
||||
use BushlanovDev\MaxMessengerBot\Models\MessageStat;
|
||||
use BushlanovDev\MaxMessengerBot\Models\Recipient;
|
||||
use BushlanovDev\MaxMessengerBot\Models\User;
|
||||
use PHPUnit\Framework\Attributes\CoversClass;
|
||||
@@ -19,6 +20,7 @@ use PHPUnit\Framework\TestCase;
|
||||
#[UsesClass(Recipient::class)]
|
||||
#[UsesClass(User::class)]
|
||||
#[UsesClass(LinkedMessage::class)]
|
||||
#[UsesClass(MessageStat::class)]
|
||||
final class MessageTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
@@ -59,6 +61,9 @@ final class MessageTest extends TestCase
|
||||
'sender' => null,
|
||||
'chat_id' => null,
|
||||
],
|
||||
'stat' => [
|
||||
'views' => 500,
|
||||
],
|
||||
];
|
||||
|
||||
$message = Message::fromArray($data);
|
||||
@@ -69,6 +74,8 @@ final class MessageTest extends TestCase
|
||||
$this->assertInstanceOf(Recipient::class, $message->recipient);
|
||||
$this->assertInstanceOf(User::class, $message->sender);
|
||||
$this->assertSame($data['url'], $message->url);
|
||||
$this->assertInstanceOf(MessageStat::class, $message->stat);
|
||||
$this->assertSame(500, $message->stat->views);
|
||||
|
||||
$array = $message->toArray();
|
||||
|
||||
|
||||
@@ -84,6 +84,7 @@ final class WebhookHandlerTest extends TestCase
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
);
|
||||
|
||||
return new MessageCreatedUpdate(
|
||||
|
||||
Reference in New Issue
Block a user