Added DataAttachment & LinkedMessage & Markups

This commit is contained in:
Alex
2025-08-03 15:07:05 +03:00
parent 51b105b847
commit c5d55a5c0f
45 changed files with 990 additions and 164 deletions
+1
View File
@@ -16,4 +16,5 @@ enum AttachmentType: string
case ReplyKeyboard = 'reply_keyboard';
case Location = 'location';
case Share = 'share';
case Data = 'data';
}
+18
View File
@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Enums;
enum MarkupType: string
{
case Strong = 'strong';
case Emphasized = 'emphasized';
case Monospaced = 'monospaced';
case Link = 'link';
case Strikethrough = 'strikethrough';
case Underline = 'underline';
case UserMention = 'user_mention';
case Heading = 'heading';
case Highlighted = 'highlighted';
}
+74
View File
@@ -4,12 +4,27 @@ declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot;
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
use BushlanovDev\MaxMessengerBot\Models\Attachments\AbstractAttachment;
use BushlanovDev\MaxMessengerBot\Models\Attachments\DataAttachment;
use BushlanovDev\MaxMessengerBot\Models\Attachments\ShareAttachment;
use BushlanovDev\MaxMessengerBot\Models\BotInfo;
use BushlanovDev\MaxMessengerBot\Models\Chat;
use BushlanovDev\MaxMessengerBot\Models\ChatList;
use BushlanovDev\MaxMessengerBot\Models\ChatMember;
use BushlanovDev\MaxMessengerBot\Models\ChatMembersList;
use BushlanovDev\MaxMessengerBot\Models\Markup\AbstractMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\EmphasizedMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\HeadingMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\HighlightedMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\LinkMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\MonospacedMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\StrikethroughMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\StrongMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\UnderlineMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\UserMentionMarkup;
use BushlanovDev\MaxMessengerBot\Models\Message;
use BushlanovDev\MaxMessengerBot\Models\Result;
use BushlanovDev\MaxMessengerBot\Models\Subscription;
@@ -100,9 +115,42 @@ class ModelFactory
*/
public function createMessage(array $data): Message
{
if (isset($data['body']['attachments']) && is_array($data['body']['attachments'])) {
$data['body']['attachments'] = array_map(
[$this, 'createAttachment'],
$data['body']['attachments'],
);
}
if (isset($data['body']['markup']) && is_array($data['body']['markup'])) {
$data['body']['markup'] = array_map(
[$this, 'createMarkupElement'],
$data['body']['markup'],
);
}
return Message::fromArray($data);
}
/**
* Creates a specific Attachment model based on the 'type' field.
*
* @param array<string, mixed> $data
*
* @return AbstractAttachment
* @throws ReflectionException
*/
public function createAttachment(array $data): AbstractAttachment
{
return match (AttachmentType::tryFrom($data['type'] ?? '')) {
AttachmentType::Data => DataAttachment::fromArray($data),
AttachmentType::Share => ShareAttachment::fromArray($data),
default => throw new LogicException(
'Unknown or unsupported Attachment type: ' . ($data['type'] ?? 'none')
),
};
}
/**
* List of messages.
*
@@ -248,4 +296,30 @@ class ModelFactory
{
return VideoAttachmentDetails::fromArray($data);
}
/**
* Creates a specific Markup model based on the 'type' field.
*
* @param array<string, mixed> $data
*
* @return AbstractMarkup
* @throws ReflectionException
*/
public function createMarkupElement(array $data): AbstractMarkup
{
return match (MarkupType::tryFrom($data['type'] ?? '')) {
MarkupType::Strong => StrongMarkup::fromArray($data),
MarkupType::Emphasized => EmphasizedMarkup::fromArray($data),
MarkupType::Monospaced => MonospacedMarkup::fromArray($data),
MarkupType::Strikethrough => StrikethroughMarkup::fromArray($data),
MarkupType::Underline => UnderlineMarkup::fromArray($data),
MarkupType::Heading => HeadingMarkup::fromArray($data),
MarkupType::Highlighted => HighlightedMarkup::fromArray($data),
MarkupType::Link => LinkMarkup::fromArray($data),
MarkupType::UserMention => UserMentionMarkup::fromArray($data),
default => throw new LogicException(
'Unknown or unsupported markup type: ' . ($data['type'] ?? 'none')
),
};
}
}
+8 -1
View File
@@ -118,6 +118,10 @@ abstract readonly class AbstractModel
$typeName = $type->getName();
if (is_object($value) && is_a($value, $typeName)) {
return $value;
}
if ($type->isBuiltin()) {
return match ($typeName) {
'int' => (int)$value,
@@ -168,7 +172,10 @@ abstract readonly class AbstractModel
}
if (is_subclass_of($itemClassName, self::class)) {
return array_map(fn($item) => $itemClassName::fromArray($item), $value);
return array_map(
fn($item) => is_a($item, $itemClassName) ? $item : $itemClassName::fromArray($item),
$value,
);
}
return $value;
@@ -0,0 +1,18 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
/**
* Represents a generic attachment received from the API.
*/
abstract readonly class AbstractAttachment extends AbstractModel
{
public function __construct(public AttachmentType $type)
{
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
/**
* Represents an attachment containing a payload from a SendMessageButton.
*/
final readonly class DataAttachment extends AbstractAttachment
{
/**
* @param string $data The payload from the button.
*/
public function __construct(public string $data)
{
parent::__construct(AttachmentType::Data);
}
}
@@ -0,0 +1,23 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Attachments;
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\ShareAttachmentRequestPayload;
/**
* Represents a share (URL preview) attachment.
*/
final readonly class ShareAttachment extends AbstractAttachment
{
public function __construct(
public ShareAttachmentRequestPayload $payload,
public ?string $title,
public ?string $description,
public ?string $imageUrl,
) {
parent::__construct(AttachmentType::Share);
}
}
+2 -2
View File
@@ -24,7 +24,7 @@ final readonly class Chat extends AbstractModel
* @param int|null $ownerId Identifier of chat owner. Visible only for chat admins
* @param string|null $link Link on chat.
* @param string|null $description Chat description.
* @param User|null $dialogWithUser Another user in conversation. For `dialog` type chats only.
* @param UserWithPhoto|null $dialogWithUser Another user in conversation. For `dialog` type chats only.
* @param int|null $messagesCount Messages count in chat. Only for group chats and channels. Not available for dialogs.
* @param string|null $chatMessageId Identifier of message that contains `chat` button initialized chat.
* @param Message|null $pinnedMessage Pinned message in chat or channel. Returned only when single chat is requested.
@@ -41,7 +41,7 @@ final readonly class Chat extends AbstractModel
public ?int $ownerId,
public ?string $link,
public ?string $description,
public ?User $dialogWithUser,
public ?UserWithPhoto $dialogWithUser,
public ?int $messagesCount,
public ?string $chatMessageId,
public ?Message $pinnedMessage,
+27
View File
@@ -0,0 +1,27 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models;
use BushlanovDev\MaxMessengerBot\Enums\MessageLinkType;
/**
* Represents a forwarded or replied message linked to the main message.
*/
final readonly class LinkedMessage extends AbstractModel
{
/**
* @param MessageLinkType $type Type of linked message (forward or reply).
* @param MessageBody $message The body of the original message.
* @param User|null $sender The sender of the original message. Can be null if posted on behalf of a channel.
* @param int|null $chatId The chat where the message was originally posted (for forwarded messages).
*/
public function __construct(
public MessageLinkType $type,
public MessageBody $message,
public ?User $sender,
public ?int $chatId,
) {
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
use BushlanovDev\MaxMessengerBot\Models\AbstractModel;
/**
* Base class for a text markup element.
*/
abstract readonly class AbstractMarkup extends AbstractModel
{
/**
* @param MarkupType $type The type of the markup element.
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
*/
public function __construct(
public MarkupType $type,
public int $from,
public int $length,
) {
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents an *emphasized* (italic) part of the text.
*/
final readonly class EmphasizedMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
*/
public function __construct(
int $from,
int $length,
) {
parent::__construct(MarkupType::Emphasized, $from, $length);
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents a # header part of the text.
*/
final readonly class HeadingMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
*/
public function __construct(
int $from,
int $length,
) {
parent::__construct(MarkupType::Heading, $from, $length);
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents a ^^highlighted^^ part of the text.
*/
final readonly class HighlightedMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
*/
public function __construct(
int $from,
int $length,
) {
parent::__construct(MarkupType::Highlighted, $from, $length);
}
}
+26
View File
@@ -0,0 +1,26 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents a link in the text.
*/
final readonly class LinkMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
* @param string $url Link's URL.
*/
public function __construct(
int $from,
int $length,
public string $url,
) {
parent::__construct(MarkupType::Link, $from, $length);
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents a `monospaced` part of the text.
*/
final readonly class MonospacedMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
*/
public function __construct(
int $from,
int $length,
) {
parent::__construct(MarkupType::Monospaced, $from, $length);
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents a ~strikethrough~ part of the text.
*/
final readonly class StrikethroughMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
*/
public function __construct(
int $from,
int $length,
) {
parent::__construct(MarkupType::Strikethrough, $from, $length);
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents a **strong** (bold) part of the text.
*/
final readonly class StrongMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
*/
public function __construct(
int $from,
int $length,
) {
parent::__construct(MarkupType::Strong, $from, $length);
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents an ++underlined++ part of the text.
*/
final readonly class UnderlineMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
*/
public function __construct(
int $from,
int $length,
) {
parent::__construct(MarkupType::Underline, $from, $length);
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
/**
* Represents a user mention in the text.
*/
final readonly class UserMentionMarkup extends AbstractMarkup
{
/**
* @param int $from Element start index (zero-based) in text.
* @param int $length Length of the markup element.
* @param string|null $userLink "@username" of the mentioned user.
* @param int|null $userId Identifier of the mentioned user without a username.
*/
public function __construct(
int $from,
int $length,
public ?string $userLink,
public ?int $userId,
) {
parent::__construct(MarkupType::UserMention, $from, $length);
}
}
+4 -2
View File
@@ -13,15 +13,17 @@ final readonly class Message extends AbstractModel
* @param int $timestamp Unix-time when message was created.
* @param MessageBody $body Body of created message. Text + attachments.
* @param Recipient $recipient Message recipient. Could be user or chat.
* @param Sender|null $sender User who sent this message. Can be null if message has been posted on behalf of a channel.
* @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.
*/
public function __construct(
public int $timestamp,
public MessageBody $body,
public Recipient $recipient,
public ?Sender $sender,
public ?User $sender,
public ?string $url,
public ?LinkedMessage $link,
) {
}
}
+10
View File
@@ -4,6 +4,10 @@ declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models;
use BushlanovDev\MaxMessengerBot\Attributes\ArrayOf;
use BushlanovDev\MaxMessengerBot\Models\Attachments\AbstractAttachment;
use BushlanovDev\MaxMessengerBot\Models\Markup\AbstractMarkup;
/**
* Body of created message. Text + attachments.
*/
@@ -13,11 +17,17 @@ final readonly class MessageBody extends AbstractModel
* @param string $mid Unique identifier of message.
* @param int $seq Sequence identifier of message in chat.
* @param string|null $text Message text.
* @param AbstractAttachment[]|null $attachments Message attachments.
* @param AbstractMarkup[]|null $markup Message text markup.
*/
public function __construct(
public string $mid,
public int $seq,
public ?string $text,
#[ArrayOf(AbstractAttachment::class)]
public ?array $attachments,
#[ArrayOf(AbstractMarkup::class)]
public ?array $markup,
) {
}
}
+2 -7
View File
@@ -11,11 +11,9 @@ final readonly class User extends AbstractModel
* @param string $firstName Users first name.
* @param string|null $lastName Users last name.
* @param string|null $username Unique public user name. Can be `null` if user is not accessible or it is not set.
* @param bool $isBot `true` if user is bot.
* @param bool $isBot Is the user a bot.
* @param int $lastActivityTime Time of last user activity in Max (Unix timestamp in milliseconds).
* @param string|null $description User description. Can be `null` if user did not fill it out.
* @param string|null $avatarUrl URL of avatar.
* @param string|null $fullAvatarUrl URL of avatar of a bigger size.
* Can be outdated if user disabled its "online" status in settings.
*/
public function __construct(
public int $userId,
@@ -24,9 +22,6 @@ final readonly class User extends AbstractModel
public ?string $username,
public bool $isBot,
public int $lastActivityTime,
public ?string $description,
public ?string $avatarUrl,
public ?string $fullAvatarUrl,
) {
}
}
@@ -4,18 +4,18 @@ declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Models;
/**
* User who sent this message.
*/
final readonly class Sender extends AbstractModel
final readonly class UserWithPhoto extends AbstractModel
{
/**
* @param int $userId Users identifier.
* @param string $firstName Users first name.
* @param string|null $lastName Users last name.
* @param string|null $username Unique public user name. Can be null if user is not accessible or it is not set.
* @param bool $isBot Is the user a bot.
* @param int $lastActivityTime Time of last user activity in Max (Unix timestamp in milliseconds). Can be outdated if user disabled its "online" status in settings.
* @param string|null $username Unique public user name. Can be `null` if user is not accessible or it is not set.
* @param bool $isBot `true` if user is bot.
* @param int $lastActivityTime Time of last user activity in Max (Unix timestamp in milliseconds).
* @param string|null $description UserWithPhoto description. Can be `null` if user did not fill it out.
* @param string|null $avatarUrl URL of avatar.
* @param string|null $fullAvatarUrl URL of avatar of a bigger size.
*/
public function __construct(
public int $userId,
@@ -24,6 +24,9 @@ final readonly class Sender extends AbstractModel
public ?string $username,
public bool $isBot,
public int $lastActivityTime,
public ?string $description,
public ?string $avatarUrl,
public ?string $fullAvatarUrl,
) {
}
}
+2 -4
View File
@@ -47,14 +47,13 @@ use BushlanovDev\MaxMessengerBot\Models\Message;
use BushlanovDev\MaxMessengerBot\Models\MessageBody;
use BushlanovDev\MaxMessengerBot\Models\Recipient;
use BushlanovDev\MaxMessengerBot\Models\Result;
use BushlanovDev\MaxMessengerBot\Models\Sender;
use BushlanovDev\MaxMessengerBot\Models\User;
use BushlanovDev\MaxMessengerBot\Models\Subscription;
use BushlanovDev\MaxMessengerBot\Models\UpdateList;
use BushlanovDev\MaxMessengerBot\Models\Updates\AbstractUpdate;
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;
@@ -82,7 +81,7 @@ use RuntimeException;
#[UsesClass(Message::class)]
#[UsesClass(MessageBody::class)]
#[UsesClass(Recipient::class)]
#[UsesClass(Sender::class)]
#[UsesClass(User::class)]
#[UsesClass(CallbackButton::class)]
#[UsesClass(InlineKeyboardAttachmentRequestPayload::class)]
#[UsesClass(InlineKeyboardAttachmentRequest::class)]
@@ -93,7 +92,6 @@ use RuntimeException;
#[UsesClass(Chat::class)]
#[UsesClass(UpdateList::class)]
#[UsesClass(WebhookHandler::class)]
#[UsesClass(User::class)]
#[UsesClass(AbstractUpdate::class)]
#[UsesClass(BotStartedUpdate::class)]
#[UsesClass(MessageCreatedUpdate::class)]
+98 -6
View File
@@ -8,7 +8,11 @@ use BushlanovDev\MaxMessengerBot\Attributes\ArrayOf;
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\DataAttachment;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\PhotoAttachmentRequestPayload;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\ShareAttachmentRequestPayload;
use BushlanovDev\MaxMessengerBot\Models\Attachments\ShareAttachment;
use BushlanovDev\MaxMessengerBot\Models\BotCommand;
use BushlanovDev\MaxMessengerBot\Models\BotInfo;
use BushlanovDev\MaxMessengerBot\Models\Chat;
@@ -16,11 +20,14 @@ use BushlanovDev\MaxMessengerBot\Models\ChatList;
use BushlanovDev\MaxMessengerBot\Models\ChatMember;
use BushlanovDev\MaxMessengerBot\Models\ChatMembersList;
use BushlanovDev\MaxMessengerBot\Models\Image;
use BushlanovDev\MaxMessengerBot\Models\Markup\AbstractMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\LinkMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\StrongMarkup;
use BushlanovDev\MaxMessengerBot\Models\Message;
use BushlanovDev\MaxMessengerBot\Models\MessageBody;
use BushlanovDev\MaxMessengerBot\Models\Recipient;
use BushlanovDev\MaxMessengerBot\Models\Result;
use BushlanovDev\MaxMessengerBot\Models\Sender;
use BushlanovDev\MaxMessengerBot\Models\User;
use BushlanovDev\MaxMessengerBot\Models\Subscription;
use BushlanovDev\MaxMessengerBot\Models\UpdateList;
use BushlanovDev\MaxMessengerBot\Models\Updates\BotStartedUpdate;
@@ -28,9 +35,10 @@ use BushlanovDev\MaxMessengerBot\Models\Updates\ChatTitleChangedUpdate;
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\UserWithPhoto;
use BushlanovDev\MaxMessengerBot\Models\VideoAttachmentDetails;
use BushlanovDev\MaxMessengerBot\Models\VideoUrls;
use LogicException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\UsesClass;
@@ -45,11 +53,11 @@ use PHPUnit\Framework\TestCase;
#[UsesClass(Message::class)]
#[UsesClass(MessageBody::class)]
#[UsesClass(Recipient::class)]
#[UsesClass(Sender::class)]
#[UsesClass(User::class)]
#[UsesClass(UpdateList::class)]
#[UsesClass(BotStartedUpdate::class)]
#[UsesClass(MessageCreatedUpdate::class)]
#[UsesClass(User::class)]
#[UsesClass(UserWithPhoto::class)]
#[UsesClass(UploadEndpoint::class)]
#[UsesClass(Chat::class)]
#[UsesClass(Image::class)]
@@ -61,6 +69,13 @@ use PHPUnit\Framework\TestCase;
#[UsesClass(VideoAttachmentDetails::class)]
#[UsesClass(PhotoAttachmentRequestPayload::class)]
#[UsesClass(VideoUrls::class)]
#[UsesClass(AbstractAttachment::class)]
#[UsesClass(DataAttachment::class)]
#[UsesClass(ShareAttachment::class)]
#[UsesClass(ShareAttachmentRequestPayload::class)]
#[UsesClass(LinkMarkup::class)]
#[UsesClass(AbstractMarkup::class)]
#[UsesClass(StrongMarkup::class)]
final class ModelFactoryTest extends TestCase
{
private ModelFactory $factory;
@@ -205,7 +220,7 @@ final class ModelFactoryTest extends TestCase
$this->assertInstanceOf(Message::class, $message);
$this->assertInstanceOf(MessageBody::class, $message->body);
$this->assertInstanceOf(Recipient::class, $message->recipient);
$this->assertInstanceOf(Sender::class, $message->sender);
$this->assertInstanceOf(User::class, $message->sender);
}
#[Test]
@@ -255,7 +270,7 @@ final class ModelFactoryTest extends TestCase
$this->assertInstanceOf(Chat::class, $chat);
$this->assertInstanceOf(Image::class, $chat->icon);
$this->assertInstanceOf(User::class, $chat->dialogWithUser);
$this->assertInstanceOf(UserWithPhoto::class, $chat->dialogWithUser);
}
#[Test]
@@ -506,4 +521,81 @@ final class ModelFactoryTest extends TestCase
$this->assertInstanceOf(VideoUrls::class, $details->urls);
$this->assertInstanceOf(PhotoAttachmentRequestPayload::class, $details->thumbnail);
}
#[Test]
public function createMessageCorrectlyHydratesPolymorphicAttachments(): void
{
$rawData = [
'timestamp' => time(),
'body' => [
'mid' => 'mid.789.def',
'seq' => 102,
'text' => 'Message with data attachment',
'attachments' => [
['type' => 'data', 'data' => 'payload_from_reply_button'],
[
'type' => 'share',
'payload' => ['url' => 'http://a.com'],
'title' => 'Test Share',
'description' => null,
'image_url' => null,
],
],
'markup' => null,
],
'recipient' => ['chat_type' => 'dialog', 'user_id' => 123],
];
$message = $this->factory->createMessage($rawData);
$this->assertInstanceOf(Message::class, $message);
$this->assertInstanceOf(MessageBody::class, $message->body);
$this->assertIsArray($message->body->attachments);
$this->assertCount(2, $message->body->attachments);
$this->assertInstanceOf(DataAttachment::class, $message->body->attachments[0]);
$this->assertSame('payload_from_reply_button', $message->body->attachments[0]->data);
$this->assertInstanceOf(ShareAttachment::class, $message->body->attachments[1]);
$this->assertSame('Test Share', $message->body->attachments[1]->title);
}
#[Test]
public function createMessageCorrectlyHydratesMarkup(): void
{
// ... (данные теста)
$rawData = [
'timestamp' => time(),
'body' => [
'mid' => 'mid.markup.test',
'seq' => 200,
'text' => 'Hello world! Visit our site.',
'attachments' => null,
'markup' => [
['type' => 'strong', 'from' => 6, 'length' => 5],
['type' => 'link', 'from' => 18, 'length' => 4, 'url' => 'https://dev.max.ru']
]
],
'recipient' => ['chat_type' => 'dialog', 'user_id' => 123],
];
$message = $this->factory->createMessage($rawData);
$markup = $message->body->markup;
$this->assertInstanceOf(StrongMarkup::class, $markup[0]);
$this->assertSame(6, $markup[0]->from);
$this->assertInstanceOf(LinkMarkup::class, $markup[1]);
$this->assertSame('https://dev.max.ru', $markup[1]->url);
}
#[Test]
public function createMarkupElementThrowsExceptionForUnknownType(): void
{
$this->expectException(LogicException::class);
$this->expectExceptionMessage('Unknown or unsupported markup type: brand_new_unsupported_type');
$this->factory->createMarkupElement(['type' => 'brand_new_unsupported_type']);
}
}
@@ -0,0 +1,49 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
use BushlanovDev\MaxMessengerBot\Models\Attachments\AbstractAttachment;
use BushlanovDev\MaxMessengerBot\Models\Attachments\DataAttachment;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;
#[CoversClass(DataAttachment::class)]
#[UsesClass(AbstractAttachment::class)]
final class DataAttachmentTest extends TestCase
{
#[Test]
public function canBeCreatedAndSerialized(): void
{
$attachment = new DataAttachment('some_payload_from_button');
$this->assertSame(AttachmentType::Data, $attachment->type);
$this->assertSame('some_payload_from_button', $attachment->data);
$expectedArray = [
'type' => 'data',
'data' => 'some_payload_from_button',
];
$this->assertEquals($expectedArray, $attachment->toArray());
}
#[Test]
public function canBeCreatedFromArray(): void
{
$data = [
'type' => 'data',
'data' => 'payload123',
];
$attachment = DataAttachment::fromArray($data);
$this->assertInstanceOf(DataAttachment::class, $attachment);
$this->assertSame(AttachmentType::Data, $attachment->type);
$this->assertSame('payload123', $attachment->data);
}
}
@@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Attachments;
use BushlanovDev\MaxMessengerBot\Enums\AttachmentType;
use BushlanovDev\MaxMessengerBot\Models\Attachments\AbstractAttachment;
use BushlanovDev\MaxMessengerBot\Models\Attachments\Payloads\ShareAttachmentRequestPayload;
use BushlanovDev\MaxMessengerBot\Models\Attachments\ShareAttachment;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;
#[CoversClass(ShareAttachment::class)]
#[UsesClass(AbstractAttachment::class)]
#[UsesClass(ShareAttachmentRequestPayload::class)]
final class ShareAttachmentTest extends TestCase
{
#[Test]
public function canBeCreatedFromArray(): void
{
$data = [
'type' => 'share',
'payload' => ['url' => 'https://dev.max.ru'],
'title' => 'Max Bot API',
'description' => 'Documentation for Max Bot API',
'image_url' => 'https://dev.max.ru/image.png',
];
$attachment = ShareAttachment::fromArray($data);
$this->assertInstanceOf(ShareAttachment::class, $attachment);
$this->assertSame(AttachmentType::Share, $attachment->type);
$this->assertSame('Max Bot API', $attachment->title);
$this->assertInstanceOf(ShareAttachmentRequestPayload::class, $attachment->payload);
$this->assertSame('https://dev.max.ru', $attachment->payload->url);
}
}
-3
View File
@@ -29,9 +29,6 @@ final class CallbackTest extends TestCase
'last_activity_time' => 1678886000,
'last_name' => null,
'username' => null,
'description' => null,
'avatar_url' => null,
'full_avatar_url' => null,
],
];
+6 -2
View File
@@ -6,14 +6,14 @@ namespace BushlanovDev\MaxMessengerBot\Tests\Models;
use BushlanovDev\MaxMessengerBot\Models\Chat;
use BushlanovDev\MaxMessengerBot\Models\Image;
use BushlanovDev\MaxMessengerBot\Models\User;
use BushlanovDev\MaxMessengerBot\Models\UserWithPhoto;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
#[CoversClass(Chat::class)]
#[CoversClass(Image::class)]
#[CoversClass(User::class)]
#[CoversClass(UserWithPhoto::class)]
final class ChatTest extends TestCase
{
#[Test]
@@ -42,6 +42,9 @@ final class ChatTest extends TestCase
'username' => 'johndoe',
'is_bot' => false,
'last_activity_time' => 1678886400000,
'description' => 'Description',
'avatar_url' => 'https://example.com/avatar.jpg',
'full_avatar_url' => 'https://example.com/full_avatar.jpg',
],
'messages_count' => 100,
'chat_message_id' => 'mid.123',
@@ -62,6 +65,7 @@ final class ChatTest extends TestCase
$this->assertSame($data['link'], $chat->link);
$this->assertSame($data['description'], $chat->description);
$this->assertSame($data['dialog_with_user']['user_id'], $chat->dialogWithUser->userId);
$this->assertSame($data['dialog_with_user']['full_avatar_url'], $chat->dialogWithUser->fullAvatarUrl);
$this->assertSame($data['messages_count'], $chat->messagesCount);
$this->assertSame($data['chat_message_id'], $chat->chatMessageId);
}
+53
View File
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
use BushlanovDev\MaxMessengerBot\Enums\MessageLinkType;
use BushlanovDev\MaxMessengerBot\Models\LinkedMessage;
use BushlanovDev\MaxMessengerBot\Models\MessageBody;
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(LinkedMessage::class)]
#[UsesClass(MessageBody::class)]
#[UsesClass(User::class)]
final class LinkedMessageTest extends TestCase
{
#[Test]
public function canBeCreatedFromArray(): void
{
$data = [
'type' => 'reply',
'message' => [
'mid' => 'mid.original.123',
'seq' => 10,
'text' => 'This is the original message.',
'attachments' => null,
'markup' => null,
],
'sender' => [
'user_id' => 101,
'first_name' => 'Original',
'last_name' => 'Sender',
'is_bot' => false,
'last_activity_time' => time() - 1000,
],
'chat_id' => 98765,
];
$linkedMessage = LinkedMessage::fromArray($data);
$this->assertInstanceOf(LinkedMessage::class, $linkedMessage);
$this->assertSame(MessageLinkType::Reply, $linkedMessage->type);
$this->assertInstanceOf(MessageBody::class, $linkedMessage->message);
$this->assertSame('mid.original.123', $linkedMessage->message->mid);
$this->assertInstanceOf(User::class, $linkedMessage->sender);
$this->assertSame(101, $linkedMessage->sender->userId);
$this->assertSame(98765, $linkedMessage->chatId);
}
}
+143
View File
@@ -0,0 +1,143 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Tests\Models\Markup;
use BushlanovDev\MaxMessengerBot\Enums\MarkupType;
use BushlanovDev\MaxMessengerBot\Models\Markup\EmphasizedMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\HeadingMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\HighlightedMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\LinkMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\MonospacedMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\StrikethroughMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\StrongMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\UnderlineMarkup;
use BushlanovDev\MaxMessengerBot\Models\Markup\UserMentionMarkup;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
#[CoversClass(LinkMarkup::class)]
#[CoversClass(UserMentionMarkup::class)]
#[CoversClass(StrongMarkup::class)]
#[CoversClass(UnderlineMarkup::class)]
#[CoversClass(StrikethroughMarkup::class)]
#[CoversClass(MonospacedMarkup::class)]
#[CoversClass(EmphasizedMarkup::class)]
#[CoversClass(HeadingMarkup::class)]
#[CoversClass(HighlightedMarkup::class)]
final class MarkupTest extends TestCase
{
#[Test]
public function linkMarkupIsCreatedCorrectly(): void
{
$data = ['type' => 'link', 'from' => 6, 'length' => 10, 'url' => 'https://dev.max.ru'];
$markup = LinkMarkup::fromArray($data);
$this->assertSame(MarkupType::Link, $markup->type);
$this->assertSame('https://dev.max.ru', $markup->url);
$this->assertEquals($data, $markup->toArray());
}
#[Test]
public function userMentionMarkupIsCreatedCorrectly(): void
{
$data = ['type' => 'user_mention', 'from' => 17, 'length' => 8, 'user_link' => '@username', 'user_id' => 12345];
$markup = UserMentionMarkup::fromArray($data);
$this->assertSame(MarkupType::UserMention, $markup->type);
$this->assertSame('@username', $markup->userLink);
$this->assertSame(12345, $markup->userId);
$this->assertEquals($data, $markup->toArray());
}
#[Test]
public function strongMarkupIsCreatesCorrectly(): void
{
$data = ['type' => 'strong', 'from' => 0, 'length' => 5];
$markup = StrongMarkup::fromArray($data);
$this->assertInstanceOf(StrongMarkup::class, $markup);
$this->assertSame(MarkupType::Strong, $markup->type);
$this->assertSame(0, $markup->from);
$this->assertSame(5, $markup->length);
$this->assertEquals($data, $markup->toArray());
}
#[Test]
public function underlineMarkupIsCreatesCorrectly(): void
{
$data = ['type' => 'underline', 'from' => 1, 'length' => 4];
$markup = UnderlineMarkup::fromArray($data);
$this->assertInstanceOf(UnderlineMarkup::class, $markup);
$this->assertSame(MarkupType::Underline, $markup->type);
$this->assertSame(1, $markup->from);
$this->assertSame(4, $markup->length);
$this->assertEquals($data, $markup->toArray());
}
#[Test]
public function strikethroughMarkupIsCreatesCorrectly(): void
{
$data = ['type' => 'strikethrough', 'from' => 1, 'length' => 4];
$markup = StrikethroughMarkup::fromArray($data);
$this->assertInstanceOf(StrikethroughMarkup::class, $markup);
$this->assertSame(MarkupType::Strikethrough, $markup->type);
$this->assertSame(1, $markup->from);
$this->assertSame(4, $markup->length);
$this->assertEquals($data, $markup->toArray());
}
#[Test]
public function monospacedMarkupIsCreatesCorrectly(): void
{
$data = ['type' => 'monospaced', 'from' => 1, 'length' => 4];
$markup = MonospacedMarkup::fromArray($data);
$this->assertInstanceOf(MonospacedMarkup::class, $markup);
$this->assertSame(MarkupType::Monospaced, $markup->type);
$this->assertSame(1, $markup->from);
$this->assertSame(4, $markup->length);
$this->assertEquals($data, $markup->toArray());
}
#[Test]
public function emphasizedMarkupIsCreatesCorrectly(): void
{
$data = ['type' => 'emphasized', 'from' => 1, 'length' => 4];
$markup = EmphasizedMarkup::fromArray($data);
$this->assertInstanceOf(EmphasizedMarkup::class, $markup);
$this->assertSame(MarkupType::Emphasized, $markup->type);
$this->assertSame(1, $markup->from);
$this->assertSame(4, $markup->length);
$this->assertEquals($data, $markup->toArray());
}
#[Test]
public function headingMarkupIsCreatesCorrectly(): void
{
$data = ['type' => 'heading', 'from' => 1, 'length' => 4];
$markup = HeadingMarkup::fromArray($data);
$this->assertInstanceOf(HeadingMarkup::class, $markup);
$this->assertSame(MarkupType::Heading, $markup->type);
$this->assertSame(1, $markup->from);
$this->assertSame(4, $markup->length);
$this->assertEquals($data, $markup->toArray());
}
#[Test]
public function highlightedMarkupIsCreatesCorrectly(): void
{
$data = ['type' => 'highlighted', 'from' => 1, 'length' => 4];
$markup = HighlightedMarkup::fromArray($data);
$this->assertInstanceOf(HighlightedMarkup::class, $markup);
$this->assertSame(MarkupType::Highlighted, $markup->type);
$this->assertSame(1, $markup->from);
$this->assertSame(4, $markup->length);
$this->assertEquals($data, $markup->toArray());
}
}
+4
View File
@@ -19,6 +19,8 @@ final class MessageBodyTest extends TestCase
'mid' => 'mid.456.xyz',
'seq' => 101,
'text' => 'Hello, **world**!',
'attachments' => null,
'markup' => null,
];
$messageBody = MessageBody::fromArray($data);
@@ -41,6 +43,8 @@ final class MessageBodyTest extends TestCase
'mid' => 'mid.456.xyz',
'seq' => 101,
'text' => null,
'attachments' => null,
'markup' => null,
];
$messageBody = MessageBody::fromArray($data);
+22 -3
View File
@@ -4,10 +4,11 @@ declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
use BushlanovDev\MaxMessengerBot\Models\LinkedMessage;
use BushlanovDev\MaxMessengerBot\Models\Message;
use BushlanovDev\MaxMessengerBot\Models\MessageBody;
use BushlanovDev\MaxMessengerBot\Models\Recipient;
use BushlanovDev\MaxMessengerBot\Models\Sender;
use BushlanovDev\MaxMessengerBot\Models\User;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\UsesClass;
@@ -16,7 +17,8 @@ use PHPUnit\Framework\TestCase;
#[CoversClass(Message::class)]
#[UsesClass(MessageBody::class)]
#[UsesClass(Recipient::class)]
#[UsesClass(Sender::class)]
#[UsesClass(User::class)]
#[UsesClass(LinkedMessage::class)]
final class MessageTest extends TestCase
{
#[Test]
@@ -28,6 +30,8 @@ final class MessageTest extends TestCase
'mid' => 'mid.456.xyz',
'seq' => 101,
'text' => 'Hello, **world**!',
'attachments' => null,
'markup' => null,
],
'recipient' => [
'chat_type' => 'dialog',
@@ -43,6 +47,18 @@ final class MessageTest extends TestCase
'last_activity_time' => 1678886400000,
],
'url' => 'https://max.ru/message/123',
'link' => [
'type' => 'reply',
'message' => [
'mid' => 'mid.original.123',
'seq' => 10,
'text' => 'Original message',
'attachments' => null,
'markup' => null,
],
'sender' => null,
'chat_id' => null,
],
];
$message = Message::fromArray($data);
@@ -51,12 +67,15 @@ final class MessageTest extends TestCase
$this->assertSame($data['timestamp'], $message->timestamp);
$this->assertInstanceOf(MessageBody::class, $message->body);
$this->assertInstanceOf(Recipient::class, $message->recipient);
$this->assertInstanceOf(Sender::class, $message->sender);
$this->assertInstanceOf(User::class, $message->sender);
$this->assertSame($data['url'], $message->url);
$array = $message->toArray();
$this->assertIsArray($array);
$this->assertSame($data, $array);
$this->assertInstanceOf(LinkedMessage::class, $message->link);
$this->assertSame('mid.original.123', $message->link->message->mid);
}
}
-70
View File
@@ -1,70 +0,0 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
use BushlanovDev\MaxMessengerBot\Models\Sender;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
#[CoversClass(Sender::class)]
final class SenderTest extends TestCase
{
#[Test]
public function canBeCreatedFromArray(): void
{
$data = [
'user_id' => 123,
'first_name' => 'John',
'last_name' => 'Doe',
'username' => 'johndoe',
'is_bot' => false,
'last_activity_time' => 1678886400000,
];
$sender = Sender::fromArray($data);
$this->assertInstanceOf(Sender::class, $sender);
$this->assertSame($data['user_id'], $sender->userId);
$this->assertSame($data['first_name'], $sender->firstName);
$this->assertSame($data['last_name'], $sender->lastName);
$this->assertSame($data['username'], $sender->username);
$this->assertSame($data['is_bot'], $sender->isBot);
$this->assertSame($data['last_activity_time'], $sender->lastActivityTime);
$array = $sender->toArray();
$this->assertIsArray($array);
$this->assertSame($data, $array);
}
#[Test]
public function canBeCreatedFromArrayWithOptionalDataNull(): void
{
$data = [
'user_id' => 123,
'first_name' => 'John',
'is_bot' => false,
'last_activity_time' => 1678886400000,
];
$sender = Sender::fromArray($data);
$this->assertInstanceOf(Sender::class, $sender);
$this->assertSame($data['user_id'], $sender->userId);
$this->assertSame($data['first_name'], $sender->firstName);
$this->assertNull($sender->lastName);
$this->assertNull($sender->username);
$this->assertSame($data['is_bot'], $sender->isBot);
$this->assertSame($data['last_activity_time'], $sender->lastActivityTime);
$array = $sender->toArray();
$this->assertIsArray($array);
unset($array['last_name']);
unset($array['username']);
$this->assertSame($data, $array);
}
}
@@ -30,9 +30,6 @@ final class BotAddedToChatUpdateTest extends TestCase
'last_activity_time' => 1678000000,
'last_name' => null,
'username' => null,
'description' => null,
'avatar_url' => null,
'full_avatar_url' => null,
],
'is_channel' => false,
];
@@ -30,9 +30,6 @@ final class BotRemovedFromChatUpdateTest extends TestCase
'is_bot' => false,
'last_activity_time' => 1679000000,
'last_name' => null,
'description' => null,
'avatar_url' => null,
'full_avatar_url' => null,
],
'is_channel' => false,
];
@@ -29,7 +29,6 @@ final class BotStartedUpdateTest extends TestCase
'last_name' => 'Doe',
'is_bot' => false,
'last_activity_time' => 1678886400000,
'avatar_url' => 'https://example.com/avatar.jpg',
],
'user_locale' => 'ru-ru',
];
@@ -41,7 +40,6 @@ final class BotStartedUpdateTest extends TestCase
$this->assertSame(123, $update->user->userId);
$this->assertSame('John', $update->user->firstName);
$this->assertSame('Doe', $update->user->lastName);
$this->assertSame('https://example.com/avatar.jpg', $update->user->avatarUrl);
$this->assertSame('ru-ru', $update->userLocale);
}
}
@@ -30,9 +30,6 @@ final class ChatTitleChangedUpdateTest extends TestCase
'last_activity_time' => 1679999999,
'last_name' => null,
'username' => null,
'description' => null,
'avatar_url' => null,
'full_avatar_url' => null,
],
'title' => 'New Awesome Chat Title',
];
@@ -7,7 +7,7 @@ namespace BushlanovDev\MaxMessengerBot\Tests\Models\Updates;
use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
use BushlanovDev\MaxMessengerBot\Models\Chat;
use BushlanovDev\MaxMessengerBot\Models\Image;
use BushlanovDev\MaxMessengerBot\Models\User;
use BushlanovDev\MaxMessengerBot\Models\UserWithPhoto;
use BushlanovDev\MaxMessengerBot\Models\Updates\MessageChatCreatedUpdate;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
@@ -16,7 +16,7 @@ use PHPUnit\Framework\TestCase;
#[CoversClass(MessageChatCreatedUpdate::class)]
#[UsesClass(Chat::class)]
#[UsesClass(User::class)]
#[UsesClass(UserWithPhoto::class)]
#[UsesClass(Image::class)]
final class MessageChatCreatedUpdateTest extends TestCase
{
@@ -8,7 +8,7 @@ use BushlanovDev\MaxMessengerBot\Enums\UpdateType;
use BushlanovDev\MaxMessengerBot\Models\Message;
use BushlanovDev\MaxMessengerBot\Models\MessageBody;
use BushlanovDev\MaxMessengerBot\Models\Recipient;
use BushlanovDev\MaxMessengerBot\Models\Sender;
use BushlanovDev\MaxMessengerBot\Models\User;
use BushlanovDev\MaxMessengerBot\Models\Updates\MessageEditedUpdate;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
@@ -19,7 +19,7 @@ use PHPUnit\Framework\TestCase;
#[UsesClass(Message::class)]
#[UsesClass(MessageBody::class)]
#[UsesClass(Recipient::class)]
#[UsesClass(Sender::class)]
#[UsesClass(User::class)]
final class MessageEditedUpdateTest extends TestCase
{
#[Test]
@@ -30,9 +30,6 @@ final class UserAddedToChatUpdateTest extends TestCase
'is_bot' => false,
'last_activity_time' => 1680000000,
'username' => null,
'description' => null,
'avatar_url' => null,
'full_avatar_url' => null,
],
'inviter_id' => 202,
'is_channel' => false,
@@ -64,9 +61,6 @@ final class UserAddedToChatUpdateTest extends TestCase
'is_bot' => false,
'last_activity_time' => 1680000001,
'username' => null,
'description' => null,
'avatar_url' => null,
'full_avatar_url' => null,
],
'inviter_id' => null,
'is_channel' => true,
@@ -30,9 +30,6 @@ final class UserRemovedFromChatUpdateTest extends TestCase
'is_bot' => false,
'last_activity_time' => 1681000000,
'username' => null,
'description' => null,
'avatar_url' => null,
'full_avatar_url' => null,
],
'admin_id' => 222,
'is_channel' => false,
@@ -64,9 +61,6 @@ final class UserRemovedFromChatUpdateTest extends TestCase
'is_bot' => false,
'last_activity_time' => 1681000001,
'username' => null,
'description' => null,
'avatar_url' => null,
'full_avatar_url' => null,
],
'admin_id' => null,
'is_channel' => true,
+20 -28
View File
@@ -22,25 +22,19 @@ final class UserTest extends TestCase
'username' => 'johndoe',
'is_bot' => false,
'last_activity_time' => 1678886400000,
'description' => 'Description',
'avatar_url' => 'https://example.com/avatar.jpg',
'full_avatar_url' => 'https://example.com/full_avatar.jpg',
];
$user = User::fromArray($data);
$sender = User::fromArray($data);
$this->assertInstanceOf(User::class, $user);
$this->assertSame($data['user_id'], $user->userId);
$this->assertSame($data['first_name'], $user->firstName);
$this->assertSame($data['last_name'], $user->lastName);
$this->assertSame($data['username'], $user->username);
$this->assertSame($data['is_bot'], $user->isBot);
$this->assertSame($data['last_activity_time'], $user->lastActivityTime);
$this->assertSame($data['description'], $user->description);
$this->assertSame($data['avatar_url'], $user->avatarUrl);
$this->assertSame($data['full_avatar_url'], $user->fullAvatarUrl);
$this->assertInstanceOf(User::class, $sender);
$this->assertSame($data['user_id'], $sender->userId);
$this->assertSame($data['first_name'], $sender->firstName);
$this->assertSame($data['last_name'], $sender->lastName);
$this->assertSame($data['username'], $sender->username);
$this->assertSame($data['is_bot'], $sender->isBot);
$this->assertSame($data['last_activity_time'], $sender->lastActivityTime);
$array = $user->toArray();
$array = $sender->toArray();
$this->assertIsArray($array);
$this->assertSame($data, $array);
@@ -56,23 +50,21 @@ final class UserTest extends TestCase
'last_activity_time' => 1678886400000,
];
$user = User::fromArray($data);
$sender = User::fromArray($data);
$this->assertInstanceOf(User::class, $user);
$this->assertSame($data['user_id'], $user->userId);
$this->assertSame($data['first_name'], $user->firstName);
$this->assertNull($user->lastName);
$this->assertNull($user->username);
$this->assertSame($data['is_bot'], $user->isBot);
$this->assertSame($data['last_activity_time'], $user->lastActivityTime);
$this->assertNull($user->description);
$this->assertNull($user->avatarUrl);
$this->assertNull($user->fullAvatarUrl);
$this->assertInstanceOf(User::class, $sender);
$this->assertSame($data['user_id'], $sender->userId);
$this->assertSame($data['first_name'], $sender->firstName);
$this->assertNull($sender->lastName);
$this->assertNull($sender->username);
$this->assertSame($data['is_bot'], $sender->isBot);
$this->assertSame($data['last_activity_time'], $sender->lastActivityTime);
$array = $user->toArray();
$array = $sender->toArray();
$this->assertIsArray($array);
$array = array_filter($array, fn($item) => null !== $item);
unset($array['last_name']);
unset($array['username']);
$this->assertSame($data, $array);
}
}
+78
View File
@@ -0,0 +1,78 @@
<?php
declare(strict_types=1);
namespace BushlanovDev\MaxMessengerBot\Tests\Models;
use BushlanovDev\MaxMessengerBot\Models\UserWithPhoto;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
#[CoversClass(UserWithPhoto::class)]
final class UserWithPhotoTest extends TestCase
{
#[Test]
public function canBeCreatedFromArray(): void
{
$data = [
'user_id' => 123,
'first_name' => 'John',
'last_name' => 'Doe',
'username' => 'johndoe',
'is_bot' => false,
'last_activity_time' => 1678886400000,
'description' => 'Description',
'avatar_url' => 'https://example.com/avatar.jpg',
'full_avatar_url' => 'https://example.com/full_avatar.jpg',
];
$user = UserWithPhoto::fromArray($data);
$this->assertInstanceOf(UserWithPhoto::class, $user);
$this->assertSame($data['user_id'], $user->userId);
$this->assertSame($data['first_name'], $user->firstName);
$this->assertSame($data['last_name'], $user->lastName);
$this->assertSame($data['username'], $user->username);
$this->assertSame($data['is_bot'], $user->isBot);
$this->assertSame($data['last_activity_time'], $user->lastActivityTime);
$this->assertSame($data['description'], $user->description);
$this->assertSame($data['avatar_url'], $user->avatarUrl);
$this->assertSame($data['full_avatar_url'], $user->fullAvatarUrl);
$array = $user->toArray();
$this->assertIsArray($array);
$this->assertSame($data, $array);
}
#[Test]
public function canBeCreatedFromArrayWithOptionalDataNull(): void
{
$data = [
'user_id' => 123,
'first_name' => 'John',
'is_bot' => false,
'last_activity_time' => 1678886400000,
];
$user = UserWithPhoto::fromArray($data);
$this->assertInstanceOf(UserWithPhoto::class, $user);
$this->assertSame($data['user_id'], $user->userId);
$this->assertSame($data['first_name'], $user->firstName);
$this->assertNull($user->lastName);
$this->assertNull($user->username);
$this->assertSame($data['is_bot'], $user->isBot);
$this->assertSame($data['last_activity_time'], $user->lastActivityTime);
$this->assertNull($user->description);
$this->assertNull($user->avatarUrl);
$this->assertNull($user->fullAvatarUrl);
$array = $user->toArray();
$this->assertIsArray($array);
$array = array_filter($array, fn($item) => null !== $item);
$this->assertSame($data, $array);
}
}
+5 -2
View File
@@ -68,7 +68,9 @@ final class WebhookHandlerTest extends TestCase
$messageBody = new MessageBody(
$data['message']['body']['mid'],
$data['message']['body']['seq'],
$data['message']['body']['text']
$data['message']['body']['text'],
null,
null,
);
$recipient = new Recipient(
ChatType::from($data['message']['recipient']['chat_type']),
@@ -80,7 +82,8 @@ final class WebhookHandlerTest extends TestCase
$messageBody,
$recipient,
null,
null
null,
null,
);
return new MessageCreatedUpdate(