Files
Xboard/tests/Feature/UserFrontendAccessToggleTest.php
T
yinjianm 7a1cba4553 feat(config): 新增用户前端访问开关
新增 `frontend_enable` 配置并接入后台站点设置,
用于控制用户首页、订阅入口及用户侧 API 是否对外开放。

开关关闭时相关用户入口统一返回空 404,
同时保留节点 API、管理后台与外部回调接口可访问。

补充特性测试覆盖默认开启、关闭隐藏与节点接口白名单场景
2026-04-29 16:31:33 +08:00

91 lines
2.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Http\Middleware\InitializePlugins;
use App\Support\Setting;
use Tests\TestCase;
class UserFrontendAccessToggleTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
$this->withoutMiddleware(InitializePlugins::class);
config()->set('app.key', 'base64:' . base64_encode(str_repeat('a', 32)));
$this->bindSettings();
}
public function test_user_frontend_defaults_to_enabled(): void
{
$response = $this->postJson('/api/v1/passport/auth/login', []);
$this->assertNotSame(404, $response->getStatusCode());
$response->assertStatus(422);
}
public function test_disabled_frontend_hides_web_entry_without_site_title(): void
{
$this->setFrontendEnabled(false);
$response = $this->get('/');
$response->assertStatus(404);
$response->assertContent('');
}
public function test_disabled_frontend_hides_user_routes(): void
{
$this->setFrontendEnabled(false);
$this->postJson('/api/v1/passport/auth/login', [])->assertStatus(404)->assertContent('');
$this->getJson('/api/v1/user/info')->assertStatus(404)->assertContent('');
$this->get('/s/example-token')->assertStatus(404)->assertContent('');
$this->getJson('/api/v1/guest/plan/fetch')->assertStatus(404)->assertContent('');
$this->getJson('/api/v2/client/app/getVersion?token=example-token')->assertStatus(404)->assertContent('');
}
public function test_disabled_frontend_does_not_hide_node_api(): void
{
$this->setFrontendEnabled(false);
$response = $this->getJson('/api/v1/server/UniProxy/config?token=wrong-token&node_id=1&node_type=vmess');
$this->assertNotSame(404, $response->getStatusCode());
$response->assertStatus(422);
}
private function setFrontendEnabled(bool $enabled): void
{
$this->bindSettings([
'frontend_enable' => $enabled ? 1 : 0,
]);
}
private function bindSettings(array $settings = []): void
{
$settings = array_change_key_case(array_merge([
'server_token' => 'server-token',
'subscribe_path' => 's',
], $settings), CASE_LOWER);
$this->app->instance(Setting::class, new class($settings) extends Setting {
public function __construct(private array $settings)
{
}
public function get(string $key, mixed $default = null): mixed
{
return $this->settings[strtolower($key)] ?? $default;
}
public function save(array $settings): bool
{
$this->settings = array_change_key_case($settings, CASE_LOWER) + $this->settings;
return true;
}
});
}
}