Skip to content

Commit

Permalink
Merge branch 'refs/heads/master' into memory-collection
Browse files Browse the repository at this point in the history
# Conflicts:
#	composer.json
#	tests/DialogSerializationTest.php
#	tests/Fakes/FakeBot.php
#	tests/Fakes/FakeHttp.php
  • Loading branch information
alies-dev committed May 14, 2024
2 parents 42fe54d + 18e2cd6 commit c3bcde2
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 13 deletions.
21 changes: 12 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,11 +126,8 @@ final class TelegramWebhookController
}
```


### `Dialog` class API

- `start(\Telegram\Bot\Objects\Update $update)` - Start the dialog from the first step
- `proceed(\Telegram\Bot\Objects\Update $update)` - Proceed the dialog to the next step
- `isEnd()` - Check the end of the dialog
- 🔐 `end()` - End dialog
- 🔐 `jump(string $stepName)` - Jump to the particular step, where `$step` is the `public` method name
Expand All @@ -139,12 +136,18 @@ final class TelegramWebhookController

### `DialogManager` class API

ℹ️ `Dialogs` [Facade](https://laravel.com/docs/master/facades) proxies calls to `DialogManager` class.
`DialogManager` is in charge of:
- storing and recovering Dialog instances between steps/requests
- running Dialog steps (using Dialog public API)
- switching/activating Dialogs

For Laravel apps, the package provides `Dialogs` Facade, that proxies calls to `DialogManager` class.

- `setBot(\Telegram\Bot\Api $bot)` - Use non-default Bot for API calls
- `activate(\KootLabs\TelegramBotDialogs\Dialog $dialog)` - Activate a new Dialog (without running it)
- `proceed(\Telegram\Bot\Objects\Update $update)` - Run the next step handler for the existing Dialog
- `exists(\Telegram\Bot\Objects\Update $update)` - Check for existing Dialog
`DialogManager` public API:
- `activate(\KootLabs\TelegramBotDialogs\Dialog $dialog)` - Activate a new Dialog (without running it). The same user/chat may have few open Dialogs, DialogManager should know which one is active.
- `proceed(\Telegram\Bot\Objects\Update $update)` - Run the next step handler for the active Dialog (if exists)
- `exists(\Telegram\Bot\Objects\Update $update)` - Check for existing Dialog for a given Update (based on chat_id and optional user_id)
- `setBot(\Telegram\Bot\Api $bot)` - Use non-default Bot for Telegram Bot API calls


## ToDo
Expand All @@ -154,7 +157,7 @@ Tasks to do for v1.0:
- [x] Add documentation and examples
- [x] Support for channel bots
- [ ] Improve test coverage
- [ ] Improve developer experience (cleaner API, better error handling)
- [ ] Improve developer experience (cleaner API (similar method in Dialog and DialogManager))
- [ ] Reach message type validation
- [ ] Reach API to validate message types and content
- [ ] Support `\Iterator`s and/or `\Generator`s for Dialog steps
Expand Down
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
],
"homepage": "https://github.com/koot-labs/telegram-bot-dialogs",
"require": {
"php": ">=8.0",
"php": ">=8.0.2",
"illuminate/collections": "^8.0 || ^9.0 || ^10.0 || ^11.0",
"illuminate/support": "^8.0 || ^9.0 || ^10.0 || ^11.0",
"irazasyed/telegram-bot-sdk": "^3.1",
Expand All @@ -20,6 +20,7 @@
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.54",
"phpunit/phpunit": "^10.5 || ^11.0",
"symfony/cache": "^6.0 || ^7.0",
"vimeo/psalm": "^5.24"
},
"minimum-stability": "dev",
Expand Down
7 changes: 6 additions & 1 deletion src/Dialog.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,19 @@ final public function setBot(Api $bot): void
$this->bot = $bot;
}

/** Start Dialog from the begging. */
/**
* @deprecated Will be removed in v1.0.
* Start Dialog from the begging.
*/
final public function start(Update $update): void
{
$this->next = 0;
$this->proceed($update);
}

/**
* @internal Should be called by {@see \KootLabs\TelegramBotDialogs\DialogManager::proceed},
* please do not call this method directly.
* @throws \KootLabs\TelegramBotDialogs\Exceptions\InvalidDialogStep
* @throws \Telegram\Bot\Exceptions\TelegramSDKException
*/
Expand Down
2 changes: 1 addition & 1 deletion src/DialogManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ private function readDialogState(string $key): Dialog
private function generateDialogKeyUserBounded(Update $update): string
{
return implode('-', [
$update->getMessage()->from->id,
$update->getChat()->id,
$update->getMessage()->from->id,
]);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Exceptions/ControlFlow/SwitchToAnotherDialog.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
*/
final class SwitchToAnotherDialog extends \LogicException implements DialogControlFlowException
{
public ?Dialog $nextDialog = null;
public Dialog $nextDialog;

private function __construct(Dialog $nextDialog)
{
Expand Down
84 changes: 84 additions & 0 deletions tests/DialogManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace KootLabs\TelegramBotDialogs\Tests;

use KootLabs\TelegramBotDialogs\DialogManager;
use KootLabs\TelegramBotDialogs\Dialogs\HelloExampleDialog;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Test;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Psr16Cache;
use Telegram\Bot\Api;
use Telegram\Bot\Objects\Update;

#[CoversClass(\KootLabs\TelegramBotDialogs\DialogManager::class)]
final class DialogManagerTest extends TestCase
{
private const RANDOM_CHAT_ID = 42;
private const RANDOM_USER_ID = 110;

private function instantiateDialogManager(): DialogManager
{
return new DialogManager(
new Api('fake-token'),
new Psr16Cache(new ArrayAdapter()), // use array/in-memory store
);
}

#[Test]
public function it_finds_an_activated_dialog(): void
{
$dialogManager = $this->instantiateDialogManager();
$dialog = new HelloExampleDialog(self::RANDOM_CHAT_ID);

$dialogManager->activate($dialog);
$exist = $dialogManager->exists(new Update(['message' => ['chat' => ['id' => self::RANDOM_CHAT_ID]]]));

$this->assertTrue($exist);
}

#[Test]
public function it_finds_a_user_bounded_activated_dialog(): void
{
$dialogManager = $this->instantiateDialogManager();
$dialog = new HelloExampleDialog(self::RANDOM_CHAT_ID, null, self::RANDOM_USER_ID);

$dialogManager->activate($dialog);
$existResult = $dialogManager->exists(new Update(['message' => [
'chat' => ['id' => self::RANDOM_CHAT_ID],
'from' => ['id' => self::RANDOM_USER_ID],
]]));

$this->assertTrue($existResult);
}

#[Test]
public function it_do_not_find_dialog_if_it_is_not_activated(): void
{
$dialogManager = $this->instantiateDialogManager();

$existResult = $dialogManager->exists(new Update(['message' => [
'chat' => ['id' => self::RANDOM_CHAT_ID],
'from' => ['id' => self::RANDOM_USER_ID],
]]));

$this->assertFalse($existResult);
}

#[Test]
public function it_do_not_find_dialog_if_it_ts_not_activated_for_the_current_chat(): void
{
$dialogManager = $this->instantiateDialogManager();
$dialog = new HelloExampleDialog(self::RANDOM_CHAT_ID);
$dialogManager->activate($dialog);

$existResult = $dialogManager->exists(new Update(['message' => [
'chat' => ['id' => 43],
'from' => ['id' => self::RANDOM_USER_ID]],
]));

$this->assertFalse($existResult);
}
}

0 comments on commit c3bcde2

Please sign in to comment.