mirror of
https://github.com/BushlanovDev/max-bot-api-client-php.git
synced 2026-10-07 04:20:42 +00:00
Merge branch 'master' into sync/api-schema-0.0.33
This commit is contained in:
+11
-2
@@ -458,14 +458,23 @@ readonly class ModelFactory
|
||||
/**
|
||||
* Creates a specific Update model based on the 'update_type' field.
|
||||
*
|
||||
* @param array<string, mixed> $data Raw data for a single update.
|
||||
* @param mixed $data Raw data for a single update. Anything that is not an array
|
||||
* (e.g. a scalar produced by json_decode) is converted to LogicException,
|
||||
* so a webhook or a long-polling loop can skip it instead of crashing.
|
||||
*
|
||||
* @return AbstractUpdate
|
||||
* @throws ReflectionException
|
||||
* @throws LogicException
|
||||
*/
|
||||
public function createUpdate(array $data): AbstractUpdate
|
||||
public function createUpdate(mixed $data): AbstractUpdate
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
$message = sprintf('Failed to parse update: expected JSON object, got %s', get_debug_type($data));
|
||||
$this->logger->warning($message, ['payload' => $data]);
|
||||
|
||||
throw new LogicException($message);
|
||||
}
|
||||
|
||||
try {
|
||||
return match (UpdateType::tryFrom($data['update_type'] ?? '')) {
|
||||
UpdateType::MessageCreated => MessageCreatedUpdate::fromArray($data),
|
||||
|
||||
@@ -966,6 +966,67 @@ final class ModelFactoryTest extends TestCase
|
||||
$this->assertSame(7, $updateList->marker);
|
||||
}
|
||||
|
||||
public static function nonArrayPayloadProvider(): array
|
||||
{
|
||||
return [
|
||||
'string' => ['123'],
|
||||
'integer' => [42],
|
||||
'null' => [null],
|
||||
'float' => [3.14],
|
||||
'boolean' => [true],
|
||||
];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[DataProvider('nonArrayPayloadProvider')]
|
||||
public function createUpdateTurnsNonArrayPayloadIntoLogicException(mixed $payload): void
|
||||
{
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$logger->expects($this->once())
|
||||
->method('warning')
|
||||
->with(
|
||||
'Failed to parse update: expected JSON object, got ' . get_debug_type($payload),
|
||||
['payload' => $payload],
|
||||
);
|
||||
$factory = new ModelFactory($logger);
|
||||
|
||||
try {
|
||||
$factory->createUpdate($payload);
|
||||
$this->fail('LogicException expected');
|
||||
} catch (LogicException $e) {
|
||||
$this->assertNull($e->getPrevious());
|
||||
}
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function createUpdateListSkipsNonArrayElements(): void
|
||||
{
|
||||
$logger = $this->createMock(LoggerInterface::class);
|
||||
$logger->expects($this->exactly(2))->method('warning');
|
||||
$factory = new ModelFactory($logger);
|
||||
|
||||
$updateList = $factory->createUpdateList([
|
||||
'updates' => [
|
||||
'junk',
|
||||
41,
|
||||
[
|
||||
'update_type' => 'message_created',
|
||||
'timestamp' => 3,
|
||||
'message' => [
|
||||
'timestamp' => 3,
|
||||
'body' => ['mid' => 'mid.2', 'seq' => 2],
|
||||
'recipient' => ['chat_type' => 'dialog'],
|
||||
],
|
||||
],
|
||||
],
|
||||
'marker' => 9,
|
||||
]);
|
||||
|
||||
$this->assertCount(1, $updateList->updates);
|
||||
$this->assertInstanceOf(MessageCreatedUpdate::class, $updateList->updates[0]);
|
||||
$this->assertSame(9, $updateList->marker);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function createUpdateListCatchesAndLogsLogicException(): void
|
||||
{
|
||||
|
||||
@@ -249,4 +249,40 @@ final class WebhookHandlerTest extends TestCase
|
||||
|
||||
$this->assertFalse($handlerWasCalled);
|
||||
}
|
||||
|
||||
public static function nonJsonObjectBodyProvider(): array
|
||||
{
|
||||
return [
|
||||
'number' => ['123'],
|
||||
'null' => ['null'],
|
||||
'string' => ['"abc"'],
|
||||
'boolean' => ['true'],
|
||||
];
|
||||
}
|
||||
|
||||
#[Test]
|
||||
#[DataProvider('nonJsonObjectBodyProvider')]
|
||||
public function handleSkipsBodyThatIsNotAJsonObject(string $payload): void
|
||||
{
|
||||
$request = $this->createMockRequest($payload, self::SECRET);
|
||||
|
||||
$this->loggerMock->expects($this->once())
|
||||
->method('warning')
|
||||
->with($this->stringContains('Failed to parse update: expected JSON object'));
|
||||
|
||||
$handlerWasCalled = false;
|
||||
$this->dispatcher->addHandler(UpdateType::MessageCreated, function () use (&$handlerWasCalled) {
|
||||
$handlerWasCalled = true;
|
||||
});
|
||||
|
||||
$handler = new WebhookHandler(
|
||||
$this->dispatcher,
|
||||
new ModelFactory($this->loggerMock),
|
||||
$this->loggerMock,
|
||||
self::SECRET,
|
||||
);
|
||||
$handler->handle($request);
|
||||
|
||||
$this->assertFalse($handlerWasCalled);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user