From c5d55a5c0ff9393dda00f2acffaa1487640aaf7e Mon Sep 17 00:00:00 2001 From: Alex Date: Sun, 3 Aug 2025 15:07:05 +0300 Subject: [PATCH] Added DataAttachment & LinkedMessage & Markups --- src/Enums/AttachmentType.php | 1 + src/Enums/MarkupType.php | 18 +++ src/ModelFactory.php | 74 +++++++++ src/Models/AbstractModel.php | 9 +- src/Models/Attachments/AbstractAttachment.php | 18 +++ src/Models/Attachments/DataAttachment.php | 21 +++ src/Models/Attachments/ShareAttachment.php | 23 +++ src/Models/Chat.php | 4 +- src/Models/LinkedMessage.php | 27 ++++ src/Models/Markup/AbstractMarkup.php | 26 ++++ src/Models/Markup/EmphasizedMarkup.php | 24 +++ src/Models/Markup/HeadingMarkup.php | 24 +++ src/Models/Markup/HighlightedMarkup.php | 24 +++ src/Models/Markup/LinkMarkup.php | 26 ++++ src/Models/Markup/MonospacedMarkup.php | 24 +++ src/Models/Markup/StrikethroughMarkup.php | 24 +++ src/Models/Markup/StrongMarkup.php | 24 +++ src/Models/Markup/UnderlineMarkup.php | 24 +++ src/Models/Markup/UserMentionMarkup.php | 28 ++++ src/Models/Message.php | 6 +- src/Models/MessageBody.php | 10 ++ src/Models/User.php | 9 +- src/Models/{Sender.php => UserWithPhoto.php} | 17 ++- tests/ApiTest.php | 6 +- tests/ModelFactoryTest.php | 104 ++++++++++++- .../Models/Attachments/DataAttachmentTest.php | 49 ++++++ .../Attachments/ShareAttachmentTest.php | 40 +++++ tests/Models/CallbackTest.php | 3 - tests/Models/ChatTest.php | 8 +- tests/Models/LinkedMessageTest.php | 53 +++++++ tests/Models/Markup/MarkupTest.php | 143 ++++++++++++++++++ tests/Models/MessageBodyTest.php | 4 + tests/Models/MessageTest.php | 25 ++- tests/Models/SenderTest.php | 70 --------- .../Updates/BotAddedToChatUpdateTest.php | 3 - .../Updates/BotRemovedFromChatUpdateTest.php | 3 - tests/Models/Updates/BotStartedUpdateTest.php | 2 - .../Updates/ChatTitleChangedUpdateTest.php | 3 - .../Updates/MessageChatCreatedUpdateTest.php | 4 +- .../Updates/MessageEditedUpdateTest.php | 4 +- .../Updates/UserAddedToChatUpdateTest.php | 6 - .../Updates/UserRemovedFromChatUpdateTest.php | 6 - tests/Models/UserTest.php | 48 +++--- tests/Models/UserWithPhotoTest.php | 78 ++++++++++ tests/WebhookHandlerTest.php | 7 +- 45 files changed, 990 insertions(+), 164 deletions(-) create mode 100644 src/Enums/MarkupType.php create mode 100644 src/Models/Attachments/AbstractAttachment.php create mode 100644 src/Models/Attachments/DataAttachment.php create mode 100644 src/Models/Attachments/ShareAttachment.php create mode 100644 src/Models/LinkedMessage.php create mode 100644 src/Models/Markup/AbstractMarkup.php create mode 100644 src/Models/Markup/EmphasizedMarkup.php create mode 100644 src/Models/Markup/HeadingMarkup.php create mode 100644 src/Models/Markup/HighlightedMarkup.php create mode 100644 src/Models/Markup/LinkMarkup.php create mode 100644 src/Models/Markup/MonospacedMarkup.php create mode 100644 src/Models/Markup/StrikethroughMarkup.php create mode 100644 src/Models/Markup/StrongMarkup.php create mode 100644 src/Models/Markup/UnderlineMarkup.php create mode 100644 src/Models/Markup/UserMentionMarkup.php rename src/Models/{Sender.php => UserWithPhoto.php} (53%) create mode 100644 tests/Models/Attachments/DataAttachmentTest.php create mode 100644 tests/Models/Attachments/ShareAttachmentTest.php create mode 100644 tests/Models/LinkedMessageTest.php create mode 100644 tests/Models/Markup/MarkupTest.php delete mode 100644 tests/Models/SenderTest.php create mode 100644 tests/Models/UserWithPhotoTest.php diff --git a/src/Enums/AttachmentType.php b/src/Enums/AttachmentType.php index 4ff02c0..4d7d301 100644 --- a/src/Enums/AttachmentType.php +++ b/src/Enums/AttachmentType.php @@ -16,4 +16,5 @@ enum AttachmentType: string case ReplyKeyboard = 'reply_keyboard'; case Location = 'location'; case Share = 'share'; + case Data = 'data'; } diff --git a/src/Enums/MarkupType.php b/src/Enums/MarkupType.php new file mode 100644 index 0000000..828a262 --- /dev/null +++ b/src/Enums/MarkupType.php @@ -0,0 +1,18 @@ + $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 $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') + ), + }; + } } diff --git a/src/Models/AbstractModel.php b/src/Models/AbstractModel.php index 1b51895..18a41b1 100644 --- a/src/Models/AbstractModel.php +++ b/src/Models/AbstractModel.php @@ -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; diff --git a/src/Models/Attachments/AbstractAttachment.php b/src/Models/Attachments/AbstractAttachment.php new file mode 100644 index 0000000..39f1ef7 --- /dev/null +++ b/src/Models/Attachments/AbstractAttachment.php @@ -0,0 +1,18 @@ +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']); + } } diff --git a/tests/Models/Attachments/DataAttachmentTest.php b/tests/Models/Attachments/DataAttachmentTest.php new file mode 100644 index 0000000..f3905de --- /dev/null +++ b/tests/Models/Attachments/DataAttachmentTest.php @@ -0,0 +1,49 @@ +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); + } +} diff --git a/tests/Models/Attachments/ShareAttachmentTest.php b/tests/Models/Attachments/ShareAttachmentTest.php new file mode 100644 index 0000000..1b6b711 --- /dev/null +++ b/tests/Models/Attachments/ShareAttachmentTest.php @@ -0,0 +1,40 @@ + '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); + } +} diff --git a/tests/Models/CallbackTest.php b/tests/Models/CallbackTest.php index cd13619..474967a 100644 --- a/tests/Models/CallbackTest.php +++ b/tests/Models/CallbackTest.php @@ -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, ], ]; diff --git a/tests/Models/ChatTest.php b/tests/Models/ChatTest.php index 82a6a59..269d942 100644 --- a/tests/Models/ChatTest.php +++ b/tests/Models/ChatTest.php @@ -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); } diff --git a/tests/Models/LinkedMessageTest.php b/tests/Models/LinkedMessageTest.php new file mode 100644 index 0000000..96216dc --- /dev/null +++ b/tests/Models/LinkedMessageTest.php @@ -0,0 +1,53 @@ + '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); + } +} diff --git a/tests/Models/Markup/MarkupTest.php b/tests/Models/Markup/MarkupTest.php new file mode 100644 index 0000000..1716957 --- /dev/null +++ b/tests/Models/Markup/MarkupTest.php @@ -0,0 +1,143 @@ + '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()); + } +} diff --git a/tests/Models/MessageBodyTest.php b/tests/Models/MessageBodyTest.php index d38d667..cbae968 100644 --- a/tests/Models/MessageBodyTest.php +++ b/tests/Models/MessageBodyTest.php @@ -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); diff --git a/tests/Models/MessageTest.php b/tests/Models/MessageTest.php index 61bfaa6..ae9949d 100644 --- a/tests/Models/MessageTest.php +++ b/tests/Models/MessageTest.php @@ -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); } } diff --git a/tests/Models/SenderTest.php b/tests/Models/SenderTest.php deleted file mode 100644 index 352aae4..0000000 --- a/tests/Models/SenderTest.php +++ /dev/null @@ -1,70 +0,0 @@ - 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); - } -} diff --git a/tests/Models/Updates/BotAddedToChatUpdateTest.php b/tests/Models/Updates/BotAddedToChatUpdateTest.php index 8e61c7a..dc17131 100644 --- a/tests/Models/Updates/BotAddedToChatUpdateTest.php +++ b/tests/Models/Updates/BotAddedToChatUpdateTest.php @@ -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, ]; diff --git a/tests/Models/Updates/BotRemovedFromChatUpdateTest.php b/tests/Models/Updates/BotRemovedFromChatUpdateTest.php index e3a1ca8..cd4a17f 100644 --- a/tests/Models/Updates/BotRemovedFromChatUpdateTest.php +++ b/tests/Models/Updates/BotRemovedFromChatUpdateTest.php @@ -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, ]; diff --git a/tests/Models/Updates/BotStartedUpdateTest.php b/tests/Models/Updates/BotStartedUpdateTest.php index 979ae99..e359f92 100644 --- a/tests/Models/Updates/BotStartedUpdateTest.php +++ b/tests/Models/Updates/BotStartedUpdateTest.php @@ -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); } } diff --git a/tests/Models/Updates/ChatTitleChangedUpdateTest.php b/tests/Models/Updates/ChatTitleChangedUpdateTest.php index 8d6f09d..f3325e9 100644 --- a/tests/Models/Updates/ChatTitleChangedUpdateTest.php +++ b/tests/Models/Updates/ChatTitleChangedUpdateTest.php @@ -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', ]; diff --git a/tests/Models/Updates/MessageChatCreatedUpdateTest.php b/tests/Models/Updates/MessageChatCreatedUpdateTest.php index 7979558..635770b 100644 --- a/tests/Models/Updates/MessageChatCreatedUpdateTest.php +++ b/tests/Models/Updates/MessageChatCreatedUpdateTest.php @@ -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 { diff --git a/tests/Models/Updates/MessageEditedUpdateTest.php b/tests/Models/Updates/MessageEditedUpdateTest.php index 97ccc8d..acb7947 100644 --- a/tests/Models/Updates/MessageEditedUpdateTest.php +++ b/tests/Models/Updates/MessageEditedUpdateTest.php @@ -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] diff --git a/tests/Models/Updates/UserAddedToChatUpdateTest.php b/tests/Models/Updates/UserAddedToChatUpdateTest.php index 8e3832d..b1c2b98 100644 --- a/tests/Models/Updates/UserAddedToChatUpdateTest.php +++ b/tests/Models/Updates/UserAddedToChatUpdateTest.php @@ -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, diff --git a/tests/Models/Updates/UserRemovedFromChatUpdateTest.php b/tests/Models/Updates/UserRemovedFromChatUpdateTest.php index 985cf3f..3590b7d 100644 --- a/tests/Models/Updates/UserRemovedFromChatUpdateTest.php +++ b/tests/Models/Updates/UserRemovedFromChatUpdateTest.php @@ -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, diff --git a/tests/Models/UserTest.php b/tests/Models/UserTest.php index e62cc8b..7c34a22 100644 --- a/tests/Models/UserTest.php +++ b/tests/Models/UserTest.php @@ -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); } } diff --git a/tests/Models/UserWithPhotoTest.php b/tests/Models/UserWithPhotoTest.php new file mode 100644 index 0000000..ac5f4f8 --- /dev/null +++ b/tests/Models/UserWithPhotoTest.php @@ -0,0 +1,78 @@ + 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); + } +} diff --git a/tests/WebhookHandlerTest.php b/tests/WebhookHandlerTest.php index 99fdc21..05a523d 100644 --- a/tests/WebhookHandlerTest.php +++ b/tests/WebhookHandlerTest.php @@ -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(