Files
coruna-lab/tests/Feature/SystemAdminTest.php
T
2026-08-15 23:05:51 +08:00

236 lines
8.1 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Admin;
use App\Models\Setting;
use Illuminate\Foundation\Testing\RefreshDatabase;
use PHPUnit\Framework\Attributes\Test;
use Tests\TestCase;
class SystemAdminTest extends TestCase
{
use RefreshDatabase;
private function superAdmin(): Admin
{
return Admin::query()->create([
'username' => 'root',
'password' => 'secret12',
'is_super' => 1,
]);
}
private function normalAdmin(): Admin
{
return Admin::query()->create([
'username' => 'staff',
'password' => 'secret12',
'is_super' => 0,
]);
}
#[Test]
public function normal_admin_cannot_access_system_routes(): void
{
$staff = $this->normalAdmin();
$this->actingAs($staff, 'admin')
->get(route('admin.system.settings.index'))
->assertForbidden();
$this->actingAs($staff, 'admin')
->get(route('admin.system.admins.index'))
->assertForbidden();
}
#[Test]
public function super_admin_sees_system_menu_normal_does_not(): void
{
$this->actingAs($this->superAdmin(), 'admin')
->get(route('admin.home'))
->assertOk()
->assertSee('系统')
->assertSee('设置')
->assertSee('管理员');
$this->actingAs($this->normalAdmin(), 'admin')
->get(route('admin.home'))
->assertOk()
->assertDontSee('lay-href="'.route('admin.system.settings.index').'"', false);
}
#[Test]
public function super_admin_can_save_settings(): void
{
$super = $this->superAdmin();
\Illuminate\Support\Facades\Http::fake(function ($request) {
if (str_contains($request->url(), 'getMe')) {
return \Illuminate\Support\Facades\Http::response([
'ok' => true,
'result' => ['id' => 1, 'is_bot' => true, 'username' => 'test_bot'],
], 200);
}
return \Illuminate\Support\Facades\Http::response(['ok' => true], 200);
});
$this->actingAs($super, 'admin')
->post(route('admin.system.settings.update'), [
'telegram_bot_token' => 'bot:token',
'telegram_owner_chat_id' => '-1001',
'channels_max_per_agent' => 5,
'channels_domains' => "cdn1.example.com\nhttps://cdn2.example.com/",
'panel_admin_hosts' => "Admin.Example.com\nhttps://ops.example.com:443/",
'panel_agent_hosts' => 'agent.example.com',
])
->assertOk()
->assertJsonPath('code', 0)
->assertJsonPath('data.bot_username', '@test_bot');
$this->assertSame('bot:token', Setting::query()->where('key', 'telegram.bot_token')->value('value'));
$this->assertSame('test_bot', Setting::query()->where('key', 'telegram.bot_username')->value('value'));
$this->assertSame('bot:token', config('coruna.telegram.bot_token'));
$this->assertSame('test_bot', config('coruna.telegram.bot_username'));
$this->assertSame(5, (int) config('coruna.channels.max_per_agent'));
$this->assertSame(['cdn1.example.com', 'cdn2.example.com'], config('coruna.channel_domains'));
$this->assertSame(
'cdn1.example.com,cdn2.example.com',
Setting::query()->where('key', 'channels.domains')->value('value')
);
$this->assertSame(['admin.example.com', 'ops.example.com'], config('coruna.panel.admin_hosts'));
$this->assertSame(['agent.example.com'], config('coruna.panel.agent_hosts'));
$this->assertSame(
'admin.example.com,ops.example.com',
Setting::query()->where('key', 'panel.admin_hosts')->value('value')
);
}
#[Test]
public function super_admin_can_crud_admins(): void
{
$super = $this->superAdmin();
$this->actingAs($super, 'admin')
->post(route('admin.system.admins.store'), [
'username' => 'newstaff',
'password' => 'secret12',
'is_super' => 0,
])
->assertOk()
->assertJsonPath('code', 0);
$staff = Admin::query()->where('username', 'newstaff')->first();
$this->assertNotNull($staff);
$this->assertSame(0, (int) $staff->is_super);
$this->actingAs($super, 'admin')
->putJson(route('admin.system.admins.update', $staff), [
'password' => 'newpass12',
'is_super' => 0,
])
->assertOk()
->assertJsonPath('code', 0);
$this->actingAs($super, 'admin')
->deleteJson(route('admin.system.admins.destroy', $staff))
->assertOk()
->assertJsonPath('code', 0);
$this->assertDatabaseMissing('admins', ['username' => 'newstaff']);
}
#[Test]
public function cannot_delete_last_super_admin(): void
{
$super = $this->superAdmin();
$this->actingAs($super, 'admin')
->deleteJson(route('admin.system.admins.destroy', $super))
->assertStatus(422);
$this->assertDatabaseHas('admins', ['id' => $super->id]);
}
#[Test]
public function super_admin_can_send_telegram_test(): void
{
config([
'coruna.telegram.bot_token' => 'saved-token',
'coruna.telegram.owner_chat_id' => '100',
]);
\Illuminate\Support\Facades\Http::fake([
'api.telegram.org/*' => \Illuminate\Support\Facades\Http::response(['ok' => true], 200),
]);
$this->actingAs($this->superAdmin(), 'admin')
->post(route('admin.system.settings.telegramTest'), [
'chat_id' => '-1009',
'bot_token' => 'form-token',
])
->assertOk()
->assertJsonPath('code', 0);
\Illuminate\Support\Facades\Http::assertSent(function ($request) {
return str_contains($request->url(), '/botform-token/')
&& ($request->data()['chat_id'] ?? null) === '-1009'
&& str_contains((string) ($request->data()['text'] ?? ''), 'Telegram 测试');
});
}
#[Test]
public function telegram_test_reports_telegram_error(): void
{
config(['coruna.telegram.bot_token' => 'saved-token']);
\Illuminate\Support\Facades\Http::fake([
'api.telegram.org/*' => \Illuminate\Support\Facades\Http::response([
'ok' => false,
'description' => 'Bad Request: chat not found',
], 400),
]);
$this->actingAs($this->superAdmin(), 'admin')
->post(route('admin.system.settings.telegramTest'), [
'chat_id' => '999',
])
->assertOk()
->assertJsonPath('code', 1)
->assertJsonPath('msg', 'Bad Request: chat not found');
}
#[Test]
public function normal_admin_cannot_test_official_telegram(): void
{
$this->actingAs($this->normalAdmin(), 'admin')
->post(route('admin.system.settings.telegramTest'), ['chat_id' => '1'])
->assertForbidden();
}
#[Test]
public function settings_page_shows_bot_username_from_getMe(): void
{
config([
'coruna.telegram.bot_token' => 'saved-token',
'coruna.telegram.bot_username' => '',
]);
\Illuminate\Support\Facades\Http::fake(function ($request) {
if (str_contains($request->url(), 'getMe')) {
return \Illuminate\Support\Facades\Http::response([
'ok' => true,
'result' => ['username' => 'ops_bot'],
], 200);
}
return \Illuminate\Support\Facades\Http::response(['ok' => true], 200);
});
$this->actingAs($this->superAdmin(), 'admin')
->get(route('admin.system.settings.index'))
->assertOk()
->assertSee('@ops_bot')
->assertSee('t.me/ops_bot?startgroup=1', false);
$this->assertSame('ops_bot', Setting::query()->where('key', 'telegram.bot_username')->value('value'));
}
}