Silent mode for errors of unsupported event types #15

This commit is contained in:
Alex
2025-12-01 20:11:47 +03:00
parent 03b1f158d9
commit a94dfe0df4
8 changed files with 262 additions and 13 deletions
+1
View File
@@ -118,6 +118,7 @@ use RuntimeException;
#[UsesClass(VideoAttachmentDetails::class)]
#[UsesClass(VideoUrls::class)]
#[UsesClass(UpdateDispatcher::class)]
#[UsesClass(ModelFactory::class)]
final class ApiTest extends TestCase
{
use PHPMock;
+119 -1
View File
@@ -38,6 +38,7 @@ use ReflectionClass;
#[UsesClass(UpdateDispatcher::class)]
#[UsesClass(MaxBotManager::class)]
#[UsesClass(WebhookHandler::class)]
#[UsesClass(ModelFactory::class)]
final class MaxBotServiceProviderTest extends TestCase
{
use PHPMock;
@@ -212,6 +213,105 @@ final class MaxBotServiceProviderTest extends TestCase
$this->assertInstanceOf(NullLogger::class, $actualLogger);
}
#[Test]
public function modelFactoryIsConfiguredWithApplicationLoggerWhenLoggingIsEnabled(): void
{
$this->app['config']->set('maxbot.logging.enabled', true);
$mockLogger = $this->createMock(LoggerInterface::class);
$this->app->instance(LoggerInterface::class, $mockLogger);
/** @var ModelFactory $factory */
$factory = $this->app->make(ModelFactory::class);
$reflection = new ReflectionClass($factory);
$loggerProp = $reflection->getProperty('logger');
$actualLogger = $loggerProp->getValue($factory);
$this->assertSame($mockLogger, $actualLogger);
}
#[Test]
public function modelFactoryIsConfiguredWithNullLoggerWhenLoggingIsDisabled(): void
{
$this->app['config']->set('maxbot.logging.enabled', false);
/** @var ModelFactory $factory */
$factory = $this->app->make(ModelFactory::class);
$reflection = new ReflectionClass($factory);
$loggerProp = $reflection->getProperty('logger');
$actualLogger = $loggerProp->getValue($factory);
$this->assertInstanceOf(NullLogger::class, $actualLogger);
}
#[Test]
public function webhookHandlerIsConfiguredWithApplicationLoggerWhenLoggingIsEnabled(): void
{
$this->app['config']->set('maxbot.logging.enabled', true);
$mockLogger = $this->createMock(LoggerInterface::class);
$this->app->instance(LoggerInterface::class, $mockLogger);
/** @var WebhookHandler $handler */
$handler = $this->app->make(WebhookHandler::class);
$reflection = new ReflectionClass($handler);
$loggerProp = $reflection->getProperty('logger');
$actualLogger = $loggerProp->getValue($handler);
$this->assertSame($mockLogger, $actualLogger);
}
#[Test]
public function webhookHandlerIsConfiguredWithNullLoggerWhenLoggingIsDisabled(): void
{
$this->app['config']->set('maxbot.logging.enabled', false);
/** @var WebhookHandler $handler */
$handler = $this->app->make(WebhookHandler::class);
$reflection = new ReflectionClass($handler);
$loggerProp = $reflection->getProperty('logger');
$actualLogger = $loggerProp->getValue($handler);
$this->assertInstanceOf(NullLogger::class, $actualLogger);
}
#[Test]
public function longPollingHandlerIsConfiguredWithApplicationLoggerWhenLoggingIsEnabled(): void
{
$this->app['config']->set('maxbot.logging.enabled', true);
$mockLogger = $this->createMock(LoggerInterface::class);
$this->app->instance(LoggerInterface::class, $mockLogger);
/** @var LongPollingHandler $handler */
$handler = $this->app->make(LongPollingHandler::class);
$reflection = new ReflectionClass($handler);
$loggerProp = $reflection->getProperty('logger');
$actualLogger = $loggerProp->getValue($handler);
$this->assertSame($mockLogger, $actualLogger);
}
#[Test]
public function longPollingHandlerIsConfiguredWithNullLoggerWhenLoggingIsDisabled(): void
{
$this->app['config']->set('maxbot.logging.enabled', false);
/** @var LongPollingHandler $handler */
$handler = $this->app->make(LongPollingHandler::class);
$reflection = new ReflectionClass($handler);
$loggerProp = $reflection->getProperty('logger');
$actualLogger = $loggerProp->getValue($handler);
$this->assertInstanceOf(NullLogger::class, $actualLogger);
}
#[Test]
public function webhookHandlerIsConfiguredWithSecretFromConfig(): void
{
@@ -240,10 +340,28 @@ final class MaxBotServiceProviderTest extends TestCase
$this->assertSame($this->app->make(ClientApiInterface::class), $clientProp->getValue($api));
$this->assertSame($this->app->make(ModelFactory::class), $factoryProp->getValue($api));
$this->assertSame($this->app->make(LoggerInterface::class), $loggerProp->getValue($api));
$this->assertInstanceOf(NullLogger::class, $loggerProp->getValue($api));
$this->assertSame($this->app->make(UpdateDispatcher::class), $dispatcherProp->getValue($api));
}
#[Test]
public function apiIsConfiguredWithApplicationLoggerWhenLoggingIsEnabled(): void
{
$this->app['config']->set('maxbot.logging.enabled', true);
$mockLogger = $this->createMock(LoggerInterface::class);
$this->app->instance(LoggerInterface::class, $mockLogger);
/** @var Api $api */
$api = $this->app->make(Api::class);
$reflection = new ReflectionClass($api);
$loggerProp = $reflection->getProperty('logger');
$actualLogger = $loggerProp->getValue($api);
$this->assertSame($mockLogger, $actualLogger);
}
/**
* @return array<string, array{0: string}>
*/
+52
View File
@@ -59,6 +59,7 @@ use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;
use Psr\Log\LoggerInterface;
#[CoversClass(ModelFactory::class)]
#[UsesClass(BotInfo::class)]
@@ -818,4 +819,55 @@ final class ModelFactoryTest extends TestCase
$assertionCallback($this, $attachment);
}
#[Test]
public function createUpdateListCatchesAndLogsLogicException(): void
{
$loggerMock = $this->createMock(LoggerInterface::class);
$factory = $this->getMockBuilder(ModelFactory::class)
->setConstructorArgs([$loggerMock])
->onlyMethods(['createUpdate'])
->getMock();
$validUpdateData = [
'update_type' => 'bot_started',
'timestamp' => 2,
'chat_id' => 123,
'user' => [
'user_id' => 123,
'first_name' => 'John',
'is_bot' => false,
'last_activity_time' => 2,
],
'payload' => 'start_payload',
'user_locale' => 'ru-RU',
];
$invalidUpdateData = ['update_type' => 'unknown_type'];
$rawData = [
'updates' => [$validUpdateData, $invalidUpdateData],
'marker' => 123,
];
$exception = new LogicException('Unknown or unsupported update type received: unknown_type');
$factory->expects($this->exactly(2))
->method('createUpdate')
->willReturnCallback(function ($data) use ($validUpdateData, $invalidUpdateData, $exception) {
if ($data === $validUpdateData) {
return BotStartedUpdate::fromArray($data);
}
if ($data === $invalidUpdateData) {
throw $exception;
}
return null;
});
$loggerMock->expects($this->once())
->method('debug')
->with($exception->getMessage(), ['payload' => $invalidUpdateData, 'exception' => $exception]);
$updateList = $factory->createUpdateList($rawData);
$this->assertCount(1, $updateList->updates);
$this->assertInstanceOf(BotStartedUpdate::class, $updateList->updates[0]);
}
}
+39
View File
@@ -185,4 +185,43 @@ final class WebhookHandlerTest extends TestCase
$handler = new WebhookHandler($this->dispatcher, $this->modelFactoryMock, $this->loggerMock, null);
$handler->handle(null);
}
#[Test]
public function handleCatchesAndLogsLogicExceptionFromModelFactory(): void
{
$payload = '{"update_type":"unknown_type","timestamp":123}';
$updateData = json_decode($payload, true);
$exception = new LogicException('Unknown or unsupported update type received: unknown_type');
$request = $this->createMockRequest($payload, self::SECRET);
$this->modelFactoryMock->expects($this->once())
->method('createUpdate')
->with($updateData)
->willThrowException($exception);
$callIndex = 0;
$this->loggerMock->expects($this->exactly(2))
->method('debug')
->willReturnCallback(
function (string $message, array $context = []) use (&$callIndex, $payload, $exception) {
if ($callIndex === 0) {
$this->assertSame('Received webhook payload', $message);
$this->assertArrayHasKey('body', $context);
$this->assertSame($payload, $context['body']);
} elseif ($callIndex === 1) {
$this->assertSame('Unknown or unsupported update type received: unknown_type', $message);
$this->assertArrayHasKey('payload', $context);
$this->assertArrayHasKey('exception', $context);
$this->assertSame($payload, $context['payload']);
$this->assertSame($exception, $context['exception']);
}
$callIndex++;
}
);
$handler = new WebhookHandler($this->dispatcher, $this->modelFactoryMock, $this->loggerMock, self::SECRET);
$handler->handle($request);
}
}