Files
hado/core/tests/Unit/Channels/TelegramChannelTest.php
2026-09-04 07:18:37 -03:00

92 lines
3.7 KiB
PHP

<?php
namespace Tests\Unit\Channels;
use App\Channels\TelegramChannel;
use App\Enums\AfterDue;
use App\Enums\DueMode;
use App\Enums\EventState;
use App\Enums\Presence;
use App\Models\Delivery;
use App\Models\Event;
use App\Models\Source;
use App\Models\User;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use Tests\TestCase;
class TelegramChannelTest extends TestCase
{
private function driver(): TelegramChannel
{
return new TelegramChannel('test-token', 600);
}
private function event(): Event
{
$event = new Event([
'due_mode' => DueMode::Local, 'due_date' => '2026-08-14', 'due_time' => '24:00:00', 'fire_on' => '2026-08-14',
'after_due' => AfterDue::Expire, 'state' => EventState::Today,
'payload' => ['title' => 'Сегодня ДР — Вася', 'subtitle' => 'исполняется 34', 'done_label' => 'Поздравил'],
]);
$event->id = 17;
$event->setRelation('source', new Source(['name' => 'docs']));
return $event;
}
public function test_presence_is_unknown_unless_recently_seen(): void
{
$user = new User(['login' => 'n', 'tz' => 'UTC']);
$this->assertSame(Presence::Unknown, $this->driver()->presence($user, ['chat_id' => 555]));
$this->driver()->touch(555);
$this->assertSame(Presence::Present, $this->driver()->presence($user, ['chat_id' => 555]));
}
public function test_deliver_sends_message_with_two_buttons_and_stores_message_id(): void
{
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true, 'result' => ['message_id' => 9001]])]);
$outcome = $this->driver()->deliver($this->event(), new User(['login' => 'n', 'tz' => 'UTC']), ['chat_id' => 555], new Delivery(['action_token' => 'tok']));
$this->assertTrue($outcome->ok);
$this->assertSame(['message_id' => 9001], $outcome->meta);
Http::assertSent(function (Request $r) {
$kb = $r['reply_markup']['inline_keyboard'][0];
return str_ends_with($r->url(), '/bottest-token/sendMessage')
&& $r['chat_id'] === 555
&& str_contains($r['text'], 'Сегодня ДР — Вася')
&& str_contains($r['text'], 'исполняется 34')
&& $kb[0] === ['text' => 'Помню', 'callback_data' => 'ack:tok']
&& $kb[1] === ['text' => 'Поздравил', 'callback_data' => 'done:tok'];
});
}
public function test_deliver_fails_on_api_error(): void
{
Http::fake(['api.telegram.org/*' => Http::response(['ok' => false, 'description' => 'chat not found'], 400)]);
$outcome = $this->driver()->deliver($this->event(), new User(['login' => 'n', 'tz' => 'UTC']), ['chat_id' => 555], new Delivery(['action_token' => 'tok']));
$this->assertFalse($outcome->ok);
$this->assertStringContainsString('chat not found', $outcome->error);
}
public function test_on_done_clears_buttons_best_effort(): void
{
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true])]);
$delivery = new Delivery(['action_token' => 'tok', 'meta' => ['message_id' => 9001]]);
$delivery->setRelation('channel', new \App\Models\Channel(['config' => ['chat_id' => 555]]));
$this->driver()->onDone($this->event(), $delivery);
Http::assertSent(fn (Request $r) => str_ends_with($r->url(), '/editMessageReplyMarkup') && $r['message_id'] === 9001 && $r['chat_id'] === 555);
Http::fake(fn () => throw new \RuntimeException('down'));
$this->driver()->onDone($this->event(), $delivery); // не бросает
$this->addToAssertionCount(1);
}
}