51336e346a
Daily logs created by root cron were blocking www from appending, which aborted webhook ingest and bot pushes. File channels now use 0664 plus exception-safe stacks, and writes go through SafeLog. Co-authored-by: Cursor <cursoragent@cursor.com>
160 lines
5.2 KiB
PHP
160 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Channel;
|
|
use App\Models\Device;
|
|
use App\Models\User;
|
|
use App\Services\TelegramNotifier;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Http;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use Tests\TestCase;
|
|
|
|
class TelegramNotifierRoutingTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
#[Test]
|
|
public function agent_device_notifies_agent_chat(): void
|
|
{
|
|
config([
|
|
'coruna.telegram.bot_token' => 'system-token',
|
|
'coruna.telegram.owner_chat_id' => '100',
|
|
]);
|
|
|
|
$agent = User::query()->create([
|
|
'username' => 'agent_tg',
|
|
'password' => 'secret12',
|
|
'status' => 1,
|
|
'chat_id' => '200',
|
|
]);
|
|
$channelId = 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee';
|
|
Channel::query()->create([
|
|
'channel_id' => $channelId,
|
|
'user_id' => $agent->id,
|
|
'status' => 1,
|
|
]);
|
|
Device::query()->create([
|
|
'device_id' => 'dev-agent-1',
|
|
'channel_id' => $channelId,
|
|
]);
|
|
|
|
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true], 200)]);
|
|
|
|
app(TelegramNotifier::class)->notifyNewDevice('dev-agent-1', '16.0', '1.2.3.4');
|
|
|
|
Http::assertSent(function ($request) {
|
|
$text = (string) ($request->data()['text'] ?? '');
|
|
|
|
return str_contains($request->url(), '/botsystem-token/')
|
|
&& ($request->data()['chat_id'] ?? null) === '200'
|
|
&& str_contains($text, '渠道 ID')
|
|
&& str_contains($text, 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee');
|
|
});
|
|
Http::assertSent(function ($request) {
|
|
return str_contains($request->url(), '/botsystem-token/')
|
|
&& ($request->data()['chat_id'] ?? null) === '100';
|
|
});
|
|
Http::assertSentCount(2);
|
|
}
|
|
|
|
#[Test]
|
|
public function official_device_notifies_system_bot(): void
|
|
{
|
|
config([
|
|
'coruna.telegram.bot_token' => 'system-token',
|
|
'coruna.telegram.owner_chat_id' => '100',
|
|
]);
|
|
|
|
$channelId = 'ffffffffffffffffffffffffffffffff';
|
|
Channel::query()->create([
|
|
'channel_id' => $channelId,
|
|
'user_id' => Channel::OFFICIAL_USER_ID,
|
|
'status' => 1,
|
|
]);
|
|
Device::query()->create([
|
|
'device_id' => 'dev-official-1',
|
|
'channel_id' => $channelId,
|
|
]);
|
|
|
|
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true], 200)]);
|
|
|
|
app(TelegramNotifier::class)->notifyNewDevice('dev-official-1', '16.0', '1.2.3.4');
|
|
|
|
Http::assertSent(function ($request) {
|
|
$text = (string) ($request->data()['text'] ?? '');
|
|
|
|
return str_contains($request->url(), '/botsystem-token/')
|
|
&& ($request->data()['chat_id'] ?? null) === '100'
|
|
&& str_contains($text, '渠道 ID')
|
|
&& str_contains($text, 'ffffffffffffffffffffffffffffffff');
|
|
});
|
|
Http::assertSentCount(1);
|
|
}
|
|
|
|
#[Test]
|
|
public function agent_without_telegram_falls_back_to_system(): void
|
|
{
|
|
config([
|
|
'coruna.telegram.bot_token' => 'system-token',
|
|
'coruna.telegram.owner_chat_id' => '100',
|
|
]);
|
|
|
|
$agent = User::query()->create([
|
|
'username' => 'agent_empty',
|
|
'password' => 'secret12',
|
|
'status' => 1,
|
|
]);
|
|
$channelId = '12121212121212121212121212121212';
|
|
Channel::query()->create([
|
|
'channel_id' => $channelId,
|
|
'user_id' => $agent->id,
|
|
'status' => 1,
|
|
]);
|
|
Device::query()->create([
|
|
'device_id' => 'dev-fallback',
|
|
'channel_id' => $channelId,
|
|
]);
|
|
|
|
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true], 200)]);
|
|
|
|
app(TelegramNotifier::class)->notifyNewDevice('dev-fallback', '16.0', '1.2.3.4');
|
|
|
|
Http::assertSent(function ($request) {
|
|
$text = (string) ($request->data()['text'] ?? '');
|
|
|
|
return str_contains($request->url(), '/botsystem-token/')
|
|
&& ($request->data()['chat_id'] ?? null) === '100'
|
|
&& str_contains($text, '渠道 ID')
|
|
&& str_contains($text, '12121212121212121212121212121212');
|
|
});
|
|
Http::assertSentCount(1);
|
|
}
|
|
|
|
#[Test]
|
|
public function send_still_works_when_telegram_log_is_unwritable(): void
|
|
{
|
|
config([
|
|
'coruna.telegram.bot_token' => 'system-token',
|
|
'coruna.telegram.owner_chat_id' => '100',
|
|
]);
|
|
|
|
$dir = $this->forceLogChannelUnwritable('telegram');
|
|
Http::fake(['api.telegram.org/*' => Http::response(['ok' => true], 200)]);
|
|
|
|
try {
|
|
$ok = app(TelegramNotifier::class)->send('hello from unwritable log');
|
|
} finally {
|
|
$this->restoreWritableLogDir($dir);
|
|
}
|
|
|
|
$this->assertTrue($ok);
|
|
Http::assertSent(function ($request) {
|
|
return str_contains($request->url(), '/botsystem-token/')
|
|
&& ($request->data()['chat_id'] ?? null) === '100'
|
|
&& ($request->data()['text'] ?? null) === 'hello from unwritable log';
|
|
});
|
|
}
|
|
}
|