Skip to content

Commit

Permalink
Feature / Telegram getUpdates handling
Browse files Browse the repository at this point in the history
  • Loading branch information
glavvra4 committed Dec 17, 2023
1 parent e159073 commit 51004a6
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 0 deletions.
62 changes: 62 additions & 0 deletions src/Command/Telegram/GetUpdatesCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?php

declare(strict_types=1);

namespace App\Command\Telegram;

use App\Contracts\HttpClient\Telegram\BotApi;
use App\Event\Telegram\UpdateEvent;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Throwable;

class GetUpdatesCommand extends Command
{
public function __construct(
private readonly EventDispatcherInterface $eventDispatcher,
private readonly BotApi $telegram,
string $name = 'telegram:handle-updates'
)
{
parent::__construct($name);
}

protected function configure()
{
$this->setDescription('Handles a Telegram updates via long polling');
$this->setAliases([
'tg:handle-updates'
]);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$io = new SymfonyStyle($input, $output);
$io->title("Starting a telegram update handling");

$lastUpdateId = -1;
while (true) {
try {
$updates = $this->telegram->getUpdates(
offset: $lastUpdateId + 1,
timeout: 30
);

$io->text(sprintf('Handled %d updates', count($updates)));

foreach ($updates as $update) {
$lastUpdateId = $update->id->getValue();
$this->eventDispatcher->dispatch(new UpdateEvent($update), UpdateEvent::NAME);
}
} catch (Throwable $e) {
$io->error($e->getMessage());
break;
}
}

return Command::FAILURE;
}
}
27 changes: 27 additions & 0 deletions src/Event/Telegram/UpdateEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

declare(strict_types=1);

namespace App\Event\Telegram;

use Core\Telegram\Update\Entity\Update;
use Symfony\Contracts\EventDispatcher\Event;

class UpdateEvent extends Event
{
public const NAME = 'telegram.update';

public function __construct(
protected Update $update
)
{
}

/**
* @return Update
*/
public function getUpdate(): Update
{
return $this->update;
}
}
50 changes: 50 additions & 0 deletions tests-src/Command/Telegram/GetUpdatesCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace App\Tests\Command\Telegram;

use App\Command\Telegram\GetMeCommand;
use App\Command\Telegram\GetUpdatesCommand;
use App\Contracts\HttpClient\Telegram\BotApi;
use App\Event\Telegram\UpdateEvent;
use Core\Telegram\Update\Entity\Update;
use Core\Telegram\Update\Entity\Updates;
use JsonException;
use PHPUnit\Framework\MockObject\Rule\InvokedCount;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Tester\CommandTester;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;

class GetUpdatesCommandTest extends TestCase
{
public function testSuccess(): void
{
$botApi = self::createMock(BotApi::class);
$eventDispatcher = $this->createMock(EventDispatcherInterface::class);
$command = new GetUpdatesCommand($eventDispatcher, $botApi);
$commandTester = new CommandTester($command);

$botApi
->method('getUpdates')
->willReturn(
new Updates([
new Update(
new Update\Id(10)
)
])
);

$eventDispatcher
->method('dispatch')
->willThrowException(new JsonException());

$commandTester->execute([]);

self::assertEquals(
Command::FAILURE,
$commandTester->execute([])
);
}
}
26 changes: 26 additions & 0 deletions tests-src/Event/Telegram/UpdateEventTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

declare(strict_types=1);

namespace App\Tests\Event\Telegram;

use App\Event\Telegram\UpdateEvent;
use Core\Telegram\Update\Entity\Update;
use PHPUnit\Framework\TestCase;

class UpdateEventTest extends TestCase
{
public function testGetUpdate()
{
$event = new UpdateEvent(
new Update(
new Update\Id(10)
)
);

$this->assertEquals(
10,
$event->getUpdate()->id->getValue()
);
}
}

0 comments on commit 51004a6

Please sign in to comment.