feat: max-bot-test initial — full surface coverage
Some checks failed
Deploy Max Bot Test / deploy (push) Failing after 3s
Some checks failed
Deploy Max Bot Test / deploy (push) Failing after 3s
- Slim 4 PSR-15 webhook, PHP-DI 7, Symfony Console 8 - 13 update handlers, 30+ command scenarios, all 7 button types - Composer pulls pkirillw/max-bot-api-php from GitHub vcs - Multi-stage Dockerfile (php-fpm 8.4-alpine) + nginx - docker-compose.yml targets server (npm_default external) - docker-compose.override.yml for local dev (gitignored) - .gitea/workflows/deploy.yml mirrors ghost-blog-bot pattern Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
85
tests/Integration/WebhookSecretTest.php
Normal file
85
tests/Integration/WebhookSecretTest.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Tests\Integration;
|
||||
|
||||
use Nyholm\Psr7\Factory\Psr17Factory;
|
||||
use Nyholm\Psr7\ServerRequest;
|
||||
use Pkirillw\MaxBotApi\Webhook\WebhookHandler;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class WebhookSecretTest extends TestCase
|
||||
{
|
||||
private const SECRET = 'topsecret';
|
||||
|
||||
public function testRejectsMissingSecretWith401(): void
|
||||
{
|
||||
$handler = $this->makeHandler();
|
||||
$request = new ServerRequest('POST', '/webhook', [], $this->messageCreatedBody());
|
||||
$response = $handler->handle($request);
|
||||
self::assertSame(401, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function testRejectsWrongSecretWith401(): void
|
||||
{
|
||||
$handler = $this->makeHandler();
|
||||
$request = (new ServerRequest('POST', '/webhook', [], $this->messageCreatedBody()))
|
||||
->withHeader('X-Max-Bot-Api-Secret', 'wrong');
|
||||
$response = $handler->handle($request);
|
||||
self::assertSame(401, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function testAcceptsValidSecretAndInvokesUserlandHandler(): void
|
||||
{
|
||||
$handler = $this->makeHandler();
|
||||
$received = null;
|
||||
$handler->setHandler(static function (object $update) use (&$received): void {
|
||||
$received = $update;
|
||||
});
|
||||
|
||||
$request = (new ServerRequest('POST', '/webhook', [], $this->messageCreatedBody()))
|
||||
->withHeader('X-Max-Bot-Api-Secret', self::SECRET);
|
||||
$response = $handler->handle($request);
|
||||
|
||||
self::assertSame(200, $response->getStatusCode());
|
||||
self::assertNotNull($received);
|
||||
self::assertSame('message_created', $received->getUpdateType()->value);
|
||||
}
|
||||
|
||||
public function testReturns400OnEmptyBody(): void
|
||||
{
|
||||
$handler = $this->makeHandler();
|
||||
$request = (new ServerRequest('POST', '/webhook'))
|
||||
->withHeader('X-Max-Bot-Api-Secret', self::SECRET);
|
||||
$response = $handler->handle($request);
|
||||
self::assertSame(400, $response->getStatusCode());
|
||||
}
|
||||
|
||||
public function testReturns405OnGet(): void
|
||||
{
|
||||
$handler = $this->makeHandler();
|
||||
$request = (new ServerRequest('GET', '/webhook'))
|
||||
->withHeader('X-Max-Bot-Api-Secret', self::SECRET);
|
||||
$response = $handler->handle($request);
|
||||
self::assertSame(405, $response->getStatusCode());
|
||||
}
|
||||
|
||||
private function makeHandler(): WebhookHandler
|
||||
{
|
||||
return new WebhookHandler(new Psr17Factory(), secret: self::SECRET, keepRawUpdates: true);
|
||||
}
|
||||
|
||||
private function messageCreatedBody(): string
|
||||
{
|
||||
return json_encode([
|
||||
'update_type' => 'message_created',
|
||||
'timestamp' => 1_700_000_000_000,
|
||||
'message' => [
|
||||
'body' => ['mid' => 'mid-1', 'seq' => 1, 'text' => '/help'],
|
||||
'recipient' => ['chat_id' => 100, 'chat_type' => 'dialog'],
|
||||
'sender' => ['user_id' => 200, 'name' => 'Tester'],
|
||||
],
|
||||
], JSON_THROW_ON_ERROR);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user