<?php

/**
 * 文件功能：后台通用系统参数页权限边界测试
 *
 * 覆盖通用系统参数页对站长专属敏感配置的读写隔离，
 * 防止 SMTP、VIP 支付、微信机器人及 AI 机器人等配置被越权访问。
 */

namespace Tests\Feature\Feature;

use App\Models\Sysparam;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

/**
 * 类功能：验证后台通用系统参数页只允许维护白名单公共配置。
 */
class AdminSystemControllerTest extends TestCase
{
    use RefreshDatabase;

    /**
     * 验证通用系统参数页不会展示站长专属敏感配置。
     */
    public function test_system_page_does_not_show_site_owner_only_sensitive_configs(): void
    {
        $this->seedSystemParams();
        $admin = $this->createSuperAdmin();

        $response = $this->actingAs($admin)->get(route('admin.system.edit'));

        $response->assertOk();
        $response->assertSee('sys_name');
        $response->assertSee('sys_notice');
        $response->assertDontSee('smtp_host');
        $response->assertDontSee('vip_payment_app_secret');
        $response->assertDontSee('wechat_bot_config');
        $response->assertDontSee('chatbot_max_gold');
    }

    /**
     * 验证通用系统参数页更新时只会持久化白名单字段。
     */
    public function test_system_page_update_only_persists_whitelisted_configs(): void
    {
        $this->seedSystemParams();
        $admin = $this->createSuperAdmin();

        $response = $this->actingAs($admin)->put(route('admin.system.update'), [
            'sys_name' => '新版聊天室',
            'sys_notice' => '新的公共公告',
            'smtp_host' => 'attacker.smtp.example',
            'vip_payment_app_secret' => 'tampered-secret',
            'wechat_bot_config' => '{"api":{"bot_key":"stolen"}}',
            'chatbot_max_gold' => '999999',
            'rogue_secret_token' => 'hacked',
        ]);

        $response->assertRedirect(route('admin.system.edit'));
        $response->assertSessionHas('success');

        $this->assertDatabaseHas('sysparam', [
            'alias' => 'sys_name',
            'body' => '新版聊天室',
        ]);
        $this->assertDatabaseHas('sysparam', [
            'alias' => 'sys_notice',
            'body' => '新的公共公告',
        ]);

        // 敏感配置必须保持原值，不能被通用系统页伪造请求覆盖。
        $this->assertDatabaseHas('sysparam', [
            'alias' => 'smtp_host',
            'body' => 'owner.smtp.example',
        ]);
        $this->assertDatabaseHas('sysparam', [
            'alias' => 'vip_payment_app_secret',
            'body' => 'owner-secret',
        ]);
        $this->assertDatabaseHas('sysparam', [
            'alias' => 'wechat_bot_config',
            'body' => '{"api":{"bot_key":"owner-only"}}',
        ]);
        $this->assertDatabaseHas('sysparam', [
            'alias' => 'chatbot_max_gold',
            'body' => '5000',
        ]);
        $this->assertDatabaseMissing('sysparam', [
            'alias' => 'rogue_secret_token',
        ]);
    }

    /**
     * 创建可访问后台通用系统页的超级管理员账号。
     */
    private function createSuperAdmin(): User
    {
        return User::factory()->create([
            'user_level' => 100,
        ]);
    }

    /**
     * 预置通用系统页测试所需的公共参数与敏感参数。
     */
    private function seedSystemParams(): void
    {
        foreach ($this->systemParams() as $alias => $body) {
            Sysparam::updateOrCreate(
                ['alias' => $alias],
                [
                    'body' => $body,
                    'guidetxt' => strtoupper($alias).' 配置说明',
                ]
            );
        }
    }

    /**
     * 返回本轮测试覆盖的系统参数样本。
     *
     * @return array<string, string>
     */
    private function systemParams(): array
    {
        return [
            'sys_name' => '原始聊天室',
            'sys_notice' => '原始公告',
            'smtp_host' => 'owner.smtp.example',
            'vip_payment_app_secret' => 'owner-secret',
            'wechat_bot_config' => '{"api":{"bot_key":"owner-only"}}',
            'chatbot_max_gold' => '5000',
        ];
    }
}
