Files
lotteryLaravel/tests/Feature/AdminAuthLoginTest.php

140 lines
4.5 KiB
PHP

<?php
use App\Models\AdminUser;
use App\Lottery\ErrorCode;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Cache;
use Illuminate\Foundation\Testing\RefreshDatabase;
uses(RefreshDatabase::class);
test('admin ping requires authentication', function () {
$this->getJson('/api/v1/admin/ping')->assertUnauthorized()
->assertJsonPath('code', ErrorCode::AdminUnauthenticated->value);
});
test('admin auth me returns current admin profile', function () {
$admin = AdminUser::query()->create([
'username' => 'admin_me',
'name' => '管理员本人',
'email' => null,
'password' => 'secret-strong',
'status' => 0,
]);
$roleId = DB::table('admin_roles')->insertGetId([
'code' => 'super_admin',
'slug' => 'super_admin',
'name' => '超级管理员',
'description' => null,
'status' => 1,
'is_system' => true,
'sort_order' => 0,
'created_at' => now(),
'updated_at' => now(),
]);
$siteId = DB::table('admin_sites')->insertGetId([
'code' => 'default',
'name' => '默认站点',
'is_default' => true,
'status' => 1,
'created_at' => now(),
'updated_at' => now(),
]);
DB::table('admin_user_site_roles')->insert([
'admin_user_id' => $admin->id,
'site_id' => $siteId,
'role_id' => $roleId,
'granted_at' => now(),
]);
$token = $admin->createToken('admin-api', ['*'], now()->addDay())->plainTextToken;
$this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/v1/admin/auth/me')
->assertOk()
->assertJsonPath('code', ErrorCode::Success->value)
->assertJsonPath('data.admin.username', 'admin_me')
->assertJsonPath('data.admin.navigation.0.segment', 'dashboard');
});
test('admin login returns bearer token when captcha passes validation', function () {
AdminUser::query()->create([
'username' => 'tester',
'name' => '测试昵称',
'email' => null,
'password' => 'secret-strong',
'status' => 0,
]);
$captchaKey = (string) Str::uuid();
Cache::put(
'admin_captcha:'.$captchaKey,
hash_hmac('sha256', 'xwz2', (string) config('app.key')),
now()->addSeconds(120),
);
$resp = $this->postJson('/api/v1/admin/auth/login', [
'account' => 'Tester',
'password' => 'secret-strong',
'captcha_key' => $captchaKey,
'captcha_code' => 'xwz2',
]);
$resp->assertOk()
->assertJsonPath('code', ErrorCode::Success->value)
->assertJsonPath('data.admin.username', 'tester')
->assertJsonPath('data.admin.nickname', '测试昵称')
->assertJsonPath('data.admin.navigation.0.segment', 'dashboard')
->assertJsonPath('data.admin.navigation.0.href', '/admin')
->assertJsonPath('data.admin.navigation.1.segment', 'settings')
->assertJsonStructure(['data' => ['token', 'token_type', 'admin' => ['id', 'username', 'nickname', 'email', 'permissions', 'navigation']]]);
$token = $resp->json('data.token');
expect($token)->not->toBeNull();
$this->withHeader('Authorization', 'Bearer '.$token)
->getJson('/api/v1/admin/ping')
->assertOk()
->assertJsonPath('data.scope', 'admin');
});
test('admin captcha exposes key and image base64', function () {
$resp = $this->getJson('/api/v1/admin/auth/captcha');
$resp->assertOk()
->assertJsonPath('code', ErrorCode::Success->value);
$data = $resp->json('data');
expect($data)->toBeArray()
->and(Str::isUuid((string) $data['captcha_key']))->toBeTrue()
->and((string) $data['image_base64'])->not->toBe('');
});
test('login rejects wrong password with masked message', function () {
AdminUser::query()->create([
'username' => 'bad_tester',
'name' => 'X',
'email' => null,
'password' => 'right-only',
'status' => 0,
]);
$captchaKey = (string) Str::uuid();
Cache::put(
'admin_captcha:'.$captchaKey,
hash_hmac('sha256', 'aaaa', (string) config('app.key')),
now()->addSeconds(120),
);
$this->postJson('/api/v1/admin/auth/login', [
'account' => 'bad_tester',
'password' => 'wrong-password',
'captcha_key' => $captchaKey,
'captcha_code' => 'aaaa',
])->assertUnauthorized()
->assertJsonPath('code', ErrorCode::AdminCredentialsInvalid->value);
});