Skip to content

Commit

Permalink
Added ReactionType data type, fixed typing
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-helldar committed Oct 3, 2024
1 parent 5e3cd22 commit a21eada
Show file tree
Hide file tree
Showing 9 changed files with 163 additions and 21 deletions.
17 changes: 17 additions & 0 deletions docs/12.features/9.dto.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ contains incoming data (a message or a callback query)

- `->id()` incoming _update_id_
- `->message()` (optional) an instance of [`Message`](#message)
- `->messageReaction()` (optional) an instance of [`Reaction`](#reaction)
- `->callbackQuery()` (optional) an instance of [`CallbackQuery`](#callback-query)

## `Chat`
Expand Down Expand Up @@ -57,6 +58,22 @@ contains incoming data (a message or a callback query)
- `->message()` (optional) an instance of the [`Message`](#message) that triggered the callback query
- `->data()` an `Illuminate\Support\Collection` that holds the key/value pairs of the callback query data

## `Reaction`

- `->id()` incoming _message_id_
- `->chat()` an instance of [`Chat`](#chat) holding data about the chat to which the message belongs to
- `->actorChat()` (optional) an instance of [`Chat`](#chat) holding data about the chat to which the chat on behalf of which the reaction was changed, if the user is anonymous
- `->from()` (optional) an instance of [`User`](#user) holding data about the message's sender
- `->oldReaction()` a collection of [`ReactionType`](#reactiontype) holding data about the contained reaction type resolutions
- `->newReaction()` a collection of [`ReactionType`](#reactiontype) holding data about the contained reaction type resolutions
- `->date()` a `CarbonInterface` holding the message sent

## `ReactionType`

- `->type()` type of the reaction
- `->emoji()` reaction emoji
- `->customEmojiId()` (optional) custom emoji identifier


## `User`

Expand Down
30 changes: 18 additions & 12 deletions src/DTO/Reaction.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Carbon\CarbonInterface;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;

/**
* @implements Arrayable<string, string|int|bool|array<string, mixed>>
Expand All @@ -21,19 +22,21 @@ class Reaction implements Arrayable
private ?User $from = null;

/**
* @var array<array<string, string>>
* @var Collection<array-key, ReactionType>
*/
private array $oldReaction = [];
private Collection $oldReaction;

/**
* @var array<array<string, string>>
* @var Collection<array-key, ReactionType>
*/
private array $newReaction = [];
private Collection $newReaction;

private CarbonInterface $date;

private function __construct()
{
$this->oldReaction = Collection::empty();
$this->newReaction = Collection::empty();
}

/**
Expand Down Expand Up @@ -68,8 +71,11 @@ public static function fromArray(array $data): Reaction

$reaction->date = Carbon::createFromTimestamp($data['date']);

$reaction->oldReaction = $data['old_reaction'];
$reaction->newReaction = $data['new_reaction'];
/* @phpstan-ignore-next-line */
$reaction->oldReaction = collect($data['old_reaction'] ?? [])->map(fn (array $reactionData) => ReactionType::fromArray($reactionData));

/* @phpstan-ignore-next-line */
$reaction->newReaction = collect($data['new_reaction'] ?? [])->map(fn (array $reactionData) => ReactionType::fromArray($reactionData));

return $reaction;
}
Expand All @@ -95,17 +101,17 @@ public function from(): ?User
}

/**
* @return array<array<string, string>>
* @return Collection<array-key, ReactionType>
*/
public function oldReaction(): array
public function oldReaction(): Collection
{
return $this->oldReaction;
}

/**
* @return array<array<string, string>>
* @return Collection<array-key, ReactionType>
*/
public function newReaction(): array
public function newReaction(): Collection
{
return $this->newReaction;
}
Expand All @@ -122,8 +128,8 @@ public function toArray(): array
'chat' => $this->chat->toArray(),
'actor_chat' => $this->actorChat?->toArray(),
'from' => $this->from?->toArray(),
'old_reaction' => $this->oldReaction,
'new_reaction' => $this->newReaction,
'old_reaction' => $this->oldReaction->toArray(),
'new_reaction' => $this->newReaction->toArray(),
'date' => $this->date->toISOString(),
], fn ($value) => $value !== null);
}
Expand Down
67 changes: 67 additions & 0 deletions src/DTO/ReactionType.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace DefStudio\Telegraph\DTO;

use Illuminate\Contracts\Support\Arrayable;

/**
* @implements Arrayable<string, string|null>
*/
class ReactionType implements Arrayable
{
public const TYPE_EMOJI = 'emoji';
public const TYPE_CUSTOM_EMOJI = 'custom_emoji';
public const TYPE_PAID_EMOJI = 'paid';

private string $type;
private string $emoji;
private ?string $customEmojiId = null;

private function __construct()
{
}

/**
* @param array{
* type: string,
* emoji: string,
* custom_emoji_id?: string
* } $data
*/
public static function fromArray(array $data): ReactionType
{
$reaction = new self();

$reaction->type = $data['type'];
$reaction->emoji = $data['emoji'];
$reaction->customEmojiId = $data['custom_emoji_id'] ?? null;

return $reaction;
}

public function type(): string
{
return $this->type;
}

public function emoji(): string
{
return $this->emoji;
}

public function customEmojiId(): ?string
{
return $this->customEmojiId;
}

public function toArray(): array
{
return array_filter([
'type' => $this->type,
'emoji' => $this->emoji,
'custom_emoji_id' => $this->customEmojiId,
], fn ($value) => $value !== null);
}
}
13 changes: 13 additions & 0 deletions src/DTO/TelegramUpdate.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class TelegramUpdate implements Arrayable
{
private int $id;
private ?Message $message = null;
private ?Reaction $messageReaction = null;
private ?CallbackQuery $callbackQuery = null;
private ?ChatMemberUpdate $botChatStatusChange = null;
private ?InlineQuery $inlineQuery = null;
Expand All @@ -28,6 +29,7 @@ private function __construct()
* update_id:int,
* message?:array<string, mixed>,
* edited_message?:array<string, mixed>,
* message_reaction?:array<string, mixed>,
* channel_post?:array<string, mixed>,
* callback_query?:array<string, mixed>,
* my_chat_member?:array<string, mixed>,
Expand All @@ -50,6 +52,11 @@ public static function fromArray(array $data): TelegramUpdate
$update->message = Message::fromArray($data['edited_message']);
}

if (isset($data['message_reaction'])) {
/* @phpstan-ignore-next-line */
$update->messageReaction = Reaction::fromArray($data['message_reaction']);
}

if (isset($data['channel_post'])) {
/* @phpstan-ignore-next-line */
$update->message = Message::fromArray($data['channel_post']);
Expand Down Expand Up @@ -83,6 +90,11 @@ public function message(): ?Message
return $this->message;
}

public function messageReaction(): ?Reaction
{
return $this->messageReaction;
}

public function callbackQuery(): ?CallbackQuery
{
return $this->callbackQuery;
Expand All @@ -103,6 +115,7 @@ public function toArray(): array
return array_filter([
'id' => $this->id,
'message' => $this->message?->toArray(),
'message_reaction' => $this->messageReaction?->toArray(),
'callback_query' => $this->callbackQuery?->toArray(),
'bot_chat_status_change' => $this->botChatStatusChange?->toArray(),
'inline_query' => $this->inlineQuery?->toArray(),
Expand Down
6 changes: 3 additions & 3 deletions src/Handlers/WebhookHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,12 +219,12 @@ protected function handleChatMessage(Stringable $text): void
}

/**
* @param array<array<string, string>> $newReactions
* @param array<array<string, string>> $oldReactions
* @param Collection<array-key, Reaction> $newReactions
* @param Collection<array-key, Reaction> $oldReactions
*
* @return void
*/
protected function handleChatReaction(array $newReactions, array $oldReactions): void
protected function handleChatReaction(Collection $newReactions, Collection $oldReactions): void
{
// .. do nothing
}
Expand Down
9 changes: 6 additions & 3 deletions tests/Support/TestWebhookHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use DefStudio\Telegraph\Keyboard\Button;
use DefStudio\Telegraph\Keyboard\Keyboard;
use Exception;
use Illuminate\Support\Collection;
use Illuminate\Support\Stringable;

class TestWebhookHandler extends WebhookHandler
Expand Down Expand Up @@ -141,11 +142,13 @@ protected function handleChatMemberLeft(User $member): void
$this->chat->html("{$member->firstName()} just left")->send();
}

protected function handleChatReaction(array $newReactions, array $oldReactions): void
protected function handleChatReaction(Collection $newReactions, Collection $oldReactions): void
{
$this->chat->html(implode(':', [
'New reaction is ' . $newReactions[0]['emoji'],
'Old reaction is ' . $oldReactions[0]['emoji'],
/* @phpstan-ignore-next-line */
'New reaction is ' . $newReactions->first()->emoji(),
/* @phpstan-ignore-next-line */
'Old reaction is ' . $oldReactions->first()->emoji(),
]))->send();
}
}
4 changes: 2 additions & 2 deletions tests/Unit/DTO/ReactionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@
],
]);

expect($dto->oldReaction())->toBe([
expect($dto->oldReaction()->toArray())->toBe([
[
'type' => 'emoji',
'emoji' => '🔥',
Expand Down Expand Up @@ -251,7 +251,7 @@
],
]);

expect($dto->newReaction())->toBe([
expect($dto->newReaction()->toArray())->toBe([
[
'type' => 'emoji',
'emoji' => '👍',
Expand Down
33 changes: 33 additions & 0 deletions tests/Unit/DTO/TelegramUpdateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,39 @@
'date' => now()->timestamp,
'text' => 'f',
],
'message_reaction' => [
'message_id' => 2,
'date' => now()->timestamp,
'chat' => [
'id' => 3,
'type' => 'a',
'title' => 'b',
],
'actor_chat' => [
'id' => 3,
'type' => 'a',
'title' => 'b',
],
'user' => [
'id' => 1,
'is_bot' => true,
'first_name' => 'a',
'last_name' => 'b',
'username' => 'c',
],
'new_reaction' => [
[
'type' => 'emoji',
'emoji' => '👍',
],
],
'old_reaction' => [
[
'type' => 'emoji',
'emoji' => '🔥',
],
],
],
'channel_post' => [
'message_id' => 4,
'date' => now()->timestamp,
Expand Down
5 changes: 4 additions & 1 deletion tests/Unit/Handlers/WebhookHandlerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,10 @@
],
]), $bot);

Facade::assertSent("New reaction is 👍:Old reaction is 🔥");
Facade::assertSent(implode(':', [
'New reaction is 👍',
'Old reaction is 🔥',
]));
});

it('does not crash on errors', function () {
Expand Down

0 comments on commit a21eada

Please sign in to comment.