app = new Application(dirname(__DIR__, 2));
$this->app->instance('config', new Repository(['app' => ['locale' => 'zh', 'timezone' => 'Asia/Shanghai']]));
Facade::setFacadeApplication($this->app);
$db = new Manager($this->app); $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_']);
$db->setEventDispatcher(new Dispatcher($this->app)); $db->setAsGlobal(); $db->bootEloquent();
$this->app->instance('db', $db->getDatabaseManager()); $this->app->bind('db.schema', fn () => $db->schema());
$translator = new Translator(new ArrayLoader(), 'zh'); $this->app->instance('translator', $translator);
$this->app->instance('validator', new Factory($translator, $this->app));
$this->app->instance('log', new \Psr\Log\NullLogger());
$this->app->instance(\Illuminate\Contracts\Routing\ResponseFactory::class, new \Tests\Support\JsonResponseFactory());
$request = Request::create('/admin/agent/pageConfig'); $request->user = (object)['id' => 1, 'username' => 'admin']; $this->app->instance('request', $request);
DB::statement('CREATE TABLE bot_operation_audits (id INTEGER PRIMARY KEY AUTOINCREMENT,resource_type TEXT,resource_id INTEGER,action TEXT,changes TEXT,operator_id INTEGER,operator_name TEXT,created_at TEXT)');
$this->migration()->up();
$this->service = new AgentPageConfigurationService();
}
protected function tearDown(): void { DB::disconnect(); Facade::clearResolvedInstances(); parent::tearDown(); }
private function migration() { return require dirname(__DIR__, 2) . '/database/migrations/2026_10_30_180000_create_agent_page_settings.php'; }
private function emptyConfig(): array { return ['commission_plan_html' => '', 'contact_tg_url' => '', 'agent_backend_url' => '']; }
private function payload(): array
{
return ['commission_plan_html' => '
佣金方案 / Tiếng Việt
',
'contact_tg_url' => ' https://t.me/customer_service ', 'agent_backend_url' => 'https://agent.example.com/login?from=member#start'];
}
public function test_defaults_and_migration_can_be_rolled_back_and_reapplied(): void
{
$this->assertSame($this->emptyConfig(), $this->service->get());
$this->migration()->down(); $this->migration()->up();
$this->assertSame($this->emptyConfig(), $this->service->get());
}
public function test_rich_table_and_two_urls_save_together_and_only_public_fields_are_returned(): void
{
$this->app['request']->merge($this->payload());
$response = (new AgentPageConfiguration())->save($this->service);
$result = $response->getData(true); $this->assertSame(0, $result['code']);
$data = $result['data'];
$this->assertSame(array_keys($this->emptyConfig()), array_keys($data));
$this->assertSame('https://t.me/customer_service', $data['contact_tg_url']);
$this->assertSame($this->payload()['agent_backend_url'], $data['agent_backend_url']);
foreach (['', '', '', '', 'colspan="2"', 'rowspan="2"', 'width: 100%', 'text-align: center', 'color: #f00', '佣金方案', 'Tiếng Việt', '30%', '40%'] as $text) $this->assertStringContainsString($text, $data['commission_plan_html']);
$this->assertSame($data, $this->service->get());
$this->assertStringContainsString('no-store', $response->headers->get('Cache-Control'));
$this->assertSame(1, DB::table('agent_page_settings')->count());
$this->assertSame(1, DB::table('operation_audits')->count());
$this->assertSame($data, $this->service->save($data));
$this->assertSame(1, DB::table('operation_audits')->count());
$this->assertSame($this->emptyConfig(), $this->service->save($this->emptyConfig()));
}
public function test_active_markup_and_unsafe_styles_are_removed_without_flattening_tables(): void
{
$input = $this->emptyConfig();
$input['commission_plan_html'] = '中文
错误链接TG';
$html = $this->service->save($input)['commission_plan_html'];
foreach (['