You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
wx.sstbc.com/tests/Feature/DisplayDashboardAccessTest.php

129 lines
6.1 KiB

<?php
namespace Tests\Feature;
use App\Models\Admin;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Models\Permission;
use Tests\TestCase;
class DisplayDashboardAccessTest extends TestCase
{
protected function setUp(): void
{
parent::setUp();
config([
'app.key' => 'base64:' . base64_encode(str_repeat('a', 32)),
'database.default' => 'sqlite',
'database.connections.sqlite.database' => ':memory:',
'cache.default' => 'array',
'session.driver' => 'array',
'audit.enabled' => false,
]);
DB::purge('sqlite');
app('migration.repository')->createRepository();
$migrations = [
'2019_12_14_000001_create_personal_access_tokens_table.php',
'2022_03_30_173108_create_permission_tables.php',
'2022_03_30_175453_create_admins_table.php',
'2022_04_06_102925_add_api_prefix_to_permissions.php',
'2022_08_18_105251_create_operate_logs_table.php',
'2024_07_17_135941_create_configs_table.php',
'2026_11_11_000001_add_display_account_to_admins.php',
];
app('migrator')->run(array_map(fn ($file) => database_path('migrations/' . $file), $migrations));
Cache::put('home_v2_data', [
'list' => ['schoolmate_total' => 42, 'internal_count' => 100],
'suzhou' => [],
'country' => [],
'monthCourses' => [[
'title' => '研修班',
'course' => ['teacher_detail' => [['name' => '带班老师', 'mobile' => '123456']]],
]],
'yearConfigs' => [],
'article' => ['internal_article'],
]);
}
public function test_display_login_issues_a_read_only_cookie_and_logout_revokes_it(): void
{
$admin = Admin::create([
'username' => 'tv',
'name' => '电视驾驶舱',
'password' => Hash::make('long-test-password'),
'is_display_account' => true,
]);
$login = $this->withServerVariables(['REMOTE_ADDR' => '127.0.0.1'])
->postJson('/api/admin/auth/login', ['username' => 'tv', 'password' => 'long-test-password']);
$login->assertExactJson(['display_only' => true]);
$cookie = $login->getCookie(Admin::DISPLAY_COOKIE, false);
$this->assertTrue($cookie->isHttpOnly());
$this->assertTrue($cookie->isSecure());
$this->assertSame('strict', $cookie->getSameSite());
$this->assertStringNotContainsString('long-test-password', DB::table('operate_logs')->value('req_parameter'));
$this->withUnencryptedCookie(Admin::DISPLAY_COOKIE, $cookie->getValue())->withCredentials();
$this->postJson('/api/admin/auth/me')->assertExactJson(['display_only' => true]);
$this->getJson('/api/admin/display/dashboard')
->assertJsonPath('list.schoolmate_total', 42)
->assertJsonPath('monthCourses.0.teacher', '带班老师')
->assertJsonMissingPath('list.internal_count')
->assertJsonMissingPath('monthCourses.0.course')
->assertJsonMissingPath('article')
->assertHeader('Cache-Control', 'no-store, private');
$this->getJson('/api/admin/configs/index')->assertJsonPath('errcode', 40001);
$this->getJson('/api/admin/other/courses-home-export')->assertJsonPath('errcode', 40001);
$this->postJson('/api/admin/auth-node/save', [])->assertJsonPath('errcode', 40001);
$this->travel(Admin::DISPLAY_SESSION_MINUTES + 1)->minutes();
$this->getJson('/api/admin/display/dashboard')->assertJsonPath('errcode', 40001);
$this->travelBack();
$this->postJson('/api/admin/auth/logout')->assertCookieExpired(Admin::DISPLAY_COOKIE);
$this->assertSame(0, $admin->tokens()->count());
$this->getJson('/api/admin/display/dashboard')->assertJsonPath('errcode', 40001);
}
public function test_legacy_statistics_require_admin_auth_and_display_rejects_bearer_tokens(): void
{
foreach (['home', 'home-v2', 'courses-home-export'] as $path) {
$this->getJson('/api/admin/other/' . $path)->assertJsonPath('errcode', 40001);
}
$admin = Admin::create(['name' => '后台用户']);
$token = $admin->createToken('token')->plainTextToken;
$this->withToken($token)->getJson('/api/admin/other/home-v2')->assertJsonPath('list.schoolmate_total', 42);
$this->withToken($token)->getJson('/api/admin/display/dashboard')->assertJsonPath('errcode', 40003);
$display = Admin::create(['name' => '大屏用户', 'is_display_account' => true]);
$scopedToken = $display->createToken('dashboard', [Admin::DISPLAY_ABILITY])->plainTextToken;
$this->withToken($scopedToken)->postJson('/api/admin/admin/save', [])->assertJsonPath('errcode', 40003);
$this->withToken($scopedToken)->getJson('/api/admin/display/dashboard')->assertJsonPath('errcode', 40001);
}
public function test_only_user_managers_can_create_display_accounts(): void
{
$manager = Admin::create(['name' => '用户管理员']);
$token = $manager->createToken('token')->plainTextToken;
$payload = [
'name' => '大厅电视',
'username' => 'lobby-tv',
'password' => 'long-test-password',
'is_display_account' => true,
];
$this->withToken($token)->postJson('/api/admin/admin/save', $payload)->assertJsonPath('errcode', 40003);
$permission = Permission::create(['name' => '用户管理', 'guard_name' => 'admin']);
DB::table('permissions')->where('id', $permission->id)->update(['api_prefix' => 'api/admin/admin']);
$manager->givePermissionTo($permission);
$this->withToken($token)->postJson('/api/admin/admin/save', $payload)->assertJsonPath('is_display_account', true);
$display = Admin::where('username', 'lobby-tv')->firstOrFail();
$this->assertTrue($display->isDisplayOnly());
$this->assertTrue(Hash::check($payload['password'], $display->password));
}
}