Add unit tests and abstract bot method execution framework

This commit is contained in:
netkas 2024-09-30 02:34:07 -04:00
parent 69f7ff6a5a
commit 7aa6be4e9a
3 changed files with 170 additions and 0 deletions

View file

@ -0,0 +1,122 @@
<?php
namespace TgBotLib\Abstracts;
use CURLFile;
use CurlHandle;
use TgBotLib\Bot;
use TgBotLib\Exceptions\TelegramException;
use TgBotLib\Interfaces\ObjectTypeInterface;
abstract class Method
{
/**
* Executes a bot command with the given parameters.
*
* @param Bot $bot The bot instance on which the command is to be executed.
* @param array $parameters The parameters required for the bot command.
* @return ObjectTypeInterface|ObjectTypeInterface[]|mixed The result of the bot command.
* @throws TelegramException if the response from the bot command is not valid.
*/
public abstract static function execute(Bot $bot, array $parameters=[]): mixed;
/**
* Builds a cURL handle for making a POST request to a bot's endpoint.
*
* @param Bot $bot The bot object containing the endpoint information.
* @param string $method
* @param array|null $parameters An array of parameters to be sent in the POST request.
* @return CurlHandle The configured cURL handle ready for execution.
*/
protected static function buildPost(Bot $bot, string $method, ?array $parameters=null): CurlHandle
{
$curl = curl_init(sprintf('%s/bot%s/%s', $bot->getEndpoint(), $bot->getToken(), $method));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
if($parameters === null)
{
curl_setopt($curl, CURLOPT_POST, false);
}
else
{
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($parameters));
}
return $curl;
}
/**
* Builds a cURL handle for uploading a file to the Telegram API.
*
* @param Bot $bot The bot instance used to get the endpoint.
* @param string $file_param The parameter name for the file to be uploaded.
* @param string $file_path The file path of the file to be uploaded.
* @param array $parameters Additional parameters to be included in the request.
* @return CurlHandle The cURL handle configured for the file upload.
*/
protected static function buildUpload(Bot $bot, string $method, string $file_param, string $file_path, array $parameters): CurlHandle
{
$curl = curl_init(sprintf('%s/%s?%s', $bot->getEndpoint(), $method, http_build_query($parameters)));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: multipart/form-data']);
curl_setopt($curl, CURLOPT_POSTFIELDS, [
$file_param => new CURLFile($file_path)
]);
return $curl;
}
protected static function buildMultiUpload(Bot $bot, string $method, array $files, array $parameters): CurlHandle
{
$curl = curl_init(sprintf('%s/%s?%s', $bot->getEndpoint(), $method, http_build_query($parameters)));
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: multipart/form-data']);
$post_fields = [];
foreach($files as $file_param => $file_path)
{
$post_fields[$file_param] = new CURLFile($file_path);
}
curl_setopt($curl, CURLOPT_POSTFIELDS, $post_fields);
return $curl;
}
/**
* Executes a cURL request and processes the response.
*
* @param CurlHandle $curl The cURL handle to be executed.
* @return array The decoded response from the cURL request.
* @throws TelegramException if the response is not a valid array,
* or if the 'ok' field is not set or is false.
*/
protected static function executeCurl(CurlHandle $curl): array
{
$response = curl_exec($curl);
curl_close($curl);
$result = json_decode($response, true);
if(!is_array($result))
{
throw new TelegramException('Invalid response from Telegram API');
}
if(!isset($result['ok']))
{
throw new TelegramException('Invalid response from Telegram API');
}
if($result['ok'] === false)
{
throw new TelegramException($result['description'], (int)$result['error_code']);
}
return $result['result'];
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace TgBotLib\Enums;
use TgBotLib\Bot;
use TgBotLib\Methods\GetMe;
enum Methods : string
{
case GET_ME = 'getMe';
public function execute(Bot $bot, array $parameters=[]): mixed
{
return match($this)
{
self::GET_ME => GetMe::execute($bot, $parameters),
};
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace TgBotLib\Methods;
use PHPUnit\Framework\TestCase;
use TgBotLib\Bot;
use TgBotLib\Objects\Telegram\User;
class GetMeTest extends TestCase
{
private $bot;
protected function setUp(): void
{
$this->bot = new Bot(BOT_TOKEN);
}
/**
* This test checks if the `execute` method of the `getMe` class correctly calls `fromArray` method of User class
* and `executeCurl` method of the `getMe` class (itself), with correctly built parameters.
*
* Method `execute` should return User object constructed from the array returned by `executeCurl`.
*/
public function testExecute()
{
$user = getMe::execute($this->bot);
$this->assertInstanceOf(User::class, $user);
}
}