update test

This commit is contained in:
2026-03-09 13:36:24 +08:00
parent 5e8297d822
commit f95eff3963
4 changed files with 287 additions and 0 deletions
@@ -0,0 +1,272 @@
<?php
declare(strict_types=1);
namespace HyperfTest\Cases\Integration\Auth;
use App\Model\ApiKey;
use App\Model\User;
use HyperfTest\TestCase;
use Qbhy\HyperfAuth\AuthManager;
use function Hyperf\Support\make;
/**
* API Key 认证流程 & CRUD 集成测试
*
* @internal
* @coversNothing
*/
class ApiKeyAuthTest extends TestCase
{
protected function getAuthToken(User $user): string
{
$auth = make(AuthManager::class);
return $auth->guard('jwt')->login($user);
}
protected function authHeaders(User $user): array
{
return ['Authorization' => 'Bearer ' . $this->getAuthToken($user)];
}
protected function createTestUser(array $overrides = []): User
{
$suffix = bin2hex(random_bytes(4));
return User::query()->create(array_merge([
'username' => 'apikey_int_' . $suffix,
'password' => 'Pass_' . $suffix,
'email' => 'apikey_int_' . $suffix . '@example.com',
'status' => 1,
'api_key_enabled' => true,
], $overrides));
}
// ========== API Key CRUD ==========
public function test_generate_api_key_success(): void
{
$user = $this->createTestUser();
$response = $this->post('/api/v1/me/api-keys', [
'name' => 'IntTest Key',
], $this->authHeaders($user));
$response->assertStatus(200);
$response->assertJsonPath('code', 0);
$response->assertJsonStructure([
'data' => ['plain_key', 'api_key' => ['id', 'name', 'key_prefix', 'enabled']],
]);
}
public function test_generate_api_key_without_api_key_enabled_returns_403(): void
{
$user = $this->createTestUser(['api_key_enabled' => false]);
$response = $this->post('/api/v1/me/api-keys', [
'name' => 'Blocked Key',
], $this->authHeaders($user));
$response->assertStatus(403);
$response->assertJsonPath('code', 403);
}
public function test_generate_api_key_missing_name_returns_400(): void
{
$user = $this->createTestUser();
$response = $this->post('/api/v1/me/api-keys', [], $this->authHeaders($user));
$response->assertStatus(400);
$response->assertJsonPath('code', 400);
}
public function test_generate_api_key_without_auth_returns_401(): void
{
$response = $this->post('/api/v1/me/api-keys', [
'name' => 'No Auth Key',
]);
$response->assertStatus(401);
}
public function test_list_api_keys(): void
{
$user = $this->createTestUser();
// 先创建一个 key
$this->post('/api/v1/me/api-keys', [
'name' => 'List Test Key',
], $this->authHeaders($user));
$response = $this->get('/api/v1/me/api-keys', [], $this->authHeaders($user));
$response->assertStatus(200);
$response->assertJsonPath('code', 0);
}
public function test_delete_api_key_success(): void
{
$user = $this->createTestUser();
// 创建一个 key
$create_response = $this->post('/api/v1/me/api-keys', [
'name' => 'Delete Test Key',
], $this->authHeaders($user));
$key_id = $create_response->json('data.api_key.id');
$response = $this->delete('/api/v1/me/api-keys/' . $key_id, [], $this->authHeaders($user));
$response->assertStatus(200);
$response->assertJsonPath('code', 0);
}
public function test_delete_other_users_api_key_returns_404(): void
{
$user_a = $this->createTestUser();
$user_b = $this->createTestUser();
// user_a 创建 key
$create_response = $this->post('/api/v1/me/api-keys', [
'name' => 'UserA Key',
], $this->authHeaders($user_a));
$key_id = $create_response->json('data.api_key.id');
// user_b 尝试删除
$response = $this->delete('/api/v1/me/api-keys/' . $key_id, [], $this->authHeaders($user_b));
$response->assertStatus(404);
$response->assertJsonPath('code', 404);
}
// ========== API Key 认证 ==========
public function test_api_key_auth_access_me_endpoint(): void
{
$user = $this->createTestUser();
// 通过 JWT 创建 API Key
$create_response = $this->post('/api/v1/me/api-keys', [
'name' => 'Auth Test Key',
], $this->authHeaders($user));
$plain_key = $create_response->json('data.plain_key');
// 使用 API Key 访问 /me
$response = $this->get('/api/v1/me', [], [
'X-API-Key' => $plain_key,
]);
$response->assertStatus(200);
$response->assertJsonPath('code', 0);
$response->assertJsonPath('data.id', $user->id);
}
public function test_invalid_api_key_returns_401(): void
{
$response = $this->get('/api/v1/me', [], [
'X-API-Key' => 'invalid_key_that_does_not_exist',
]);
$response->assertStatus(401);
}
public function test_disabled_api_key_returns_401(): void
{
$user = $this->createTestUser();
$create_response = $this->post('/api/v1/me/api-keys', [
'name' => 'Disabled Key',
], $this->authHeaders($user));
$plain_key = $create_response->json('data.plain_key');
$key_id = $create_response->json('data.api_key.id');
// 禁用 key
$api_key = ApiKey::query()->find($key_id);
$api_key->enabled = false;
$api_key->save();
// 使用已禁用的 key
$response = $this->get('/api/v1/me', [], [
'X-API-Key' => $plain_key,
]);
$response->assertStatus(401);
}
public function test_jwt_takes_priority_over_api_key(): void
{
$user_a = $this->createTestUser();
$user_b = $this->createTestUser();
// user_b 创建 API Key
$create_response = $this->post('/api/v1/me/api-keys', [
'name' => 'Priority Test Key',
], $this->authHeaders($user_b));
$plain_key = $create_response->json('data.plain_key');
// 同时携带 JWT (user_a) 和 API Key (user_b),应使用 JWT
$response = $this->get('/api/v1/me', [], [
'Authorization' => 'Bearer ' . $this->getAuthToken($user_a),
'X-API-Key' => $plain_key,
]);
$response->assertStatus(200);
$response->assertJsonPath('data.id', $user_a->id);
}
public function test_api_key_updates_last_used_at(): void
{
$user = $this->createTestUser();
$create_response = $this->post('/api/v1/me/api-keys', [
'name' => 'LastUsed Test Key',
], $this->authHeaders($user));
$plain_key = $create_response->json('data.plain_key');
$key_id = $create_response->json('data.api_key.id');
// 使用 API Key 访问
$this->get('/api/v1/me', [], [
'X-API-Key' => $plain_key,
]);
// 验证 last_used_at 已更新
$api_key = ApiKey::query()->find($key_id);
$this->assertNotNull($api_key->last_used_at);
}
public function test_disabled_user_api_key_returns_403(): void
{
$user = $this->createTestUser();
$create_response = $this->post('/api/v1/me/api-keys', [
'name' => 'Disabled User Key',
], $this->authHeaders($user));
$plain_key = $create_response->json('data.plain_key');
// 禁用用户
$user->status = 0;
$user->save();
// 使用 API Key 访问
$response = $this->get('/api/v1/me', [], [
'X-API-Key' => $plain_key,
]);
$response->assertStatus(403);
}
public function test_no_credentials_returns_401(): void
{
$response = $this->get('/api/v1/me');
$response->assertStatus(401);
}
}