89 lines
2.9 KiB
PHP
89 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Jobs\SendTelegramMessage;
|
|
use App\Services\TelegramNotifier;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Http;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use RuntimeException;
|
|
use Tests\TestCase;
|
|
|
|
class SendTelegramMessageJobTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
#[Test]
|
|
public function success_does_not_throw(): void
|
|
{
|
|
config(['coruna.telegram.bot_token' => 'bot-token']);
|
|
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true], 200)]);
|
|
|
|
(new SendTelegramMessage('-100', 'hello'))->handle(app(TelegramNotifier::class));
|
|
|
|
Http::assertSentCount(1);
|
|
}
|
|
|
|
#[Test]
|
|
public function timeout_throws_so_the_queue_retries(): void
|
|
{
|
|
config(['coruna.telegram.bot_token' => 'bot-token']);
|
|
Http::fake(function () {
|
|
throw new \Illuminate\Http\Client\ConnectionException(
|
|
'cURL error 28: Failed to connect to api.telegram.org port 443: Connection timed out'
|
|
);
|
|
});
|
|
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('cURL error 28');
|
|
|
|
(new SendTelegramMessage('-100', 'hello'))->handle(app(TelegramNotifier::class));
|
|
}
|
|
|
|
#[Test]
|
|
public function chat_not_found_does_not_throw(): void
|
|
{
|
|
config(['coruna.telegram.bot_token' => 'bot-token']);
|
|
Http::fake([
|
|
'api.telegram.org/*' => Http::response([
|
|
'ok' => false,
|
|
'description' => 'Bad Request: chat not found',
|
|
], 400),
|
|
]);
|
|
|
|
(new SendTelegramMessage('-100', 'hello'))->handle(app(TelegramNotifier::class));
|
|
|
|
Http::assertSentCount(1);
|
|
}
|
|
|
|
#[Test]
|
|
public function backoff_is_10s_then_1m_then_5m(): void
|
|
{
|
|
$this->assertSame([10, 60, 300], (new SendTelegramMessage('-1', 'x'))->backoff());
|
|
$this->assertSame(4, (new SendTelegramMessage('-1', 'x'))->tries);
|
|
}
|
|
|
|
#[Test]
|
|
#[DataProvider('retryableErrors')]
|
|
public function classifies_retryable_errors(string $error, bool $retryable): void
|
|
{
|
|
$this->assertSame($retryable, TelegramNotifier::isRetryableSendError($error));
|
|
}
|
|
|
|
/** @return array<string, array{0: string, 1: bool}> */
|
|
public static function retryableErrors(): array
|
|
{
|
|
return [
|
|
'curl timeout' => ['cURL error 28: Failed to connect to api.telegram.org port 443: Connection timed out', true],
|
|
'too many' => ['Too Many Requests: retry after 12', true],
|
|
'http 502' => ['HTTP 502', true],
|
|
'chat missing' => ['Bad Request: chat not found', false],
|
|
'kicked' => ['Forbidden: bot was kicked from the group chat', false],
|
|
'blocked' => ['Forbidden: bot was blocked by the user', false],
|
|
'no token' => ['未配置 Bot Token', false],
|
|
];
|
|
}
|
|
}
|