update backend p20.1 p20.2
This commit is contained in:
@@ -47,7 +47,7 @@ class ApiKeyTest extends TestCase
|
||||
]);
|
||||
}
|
||||
|
||||
public function test_generate_returns_plain_key_and_model(): void
|
||||
public function test_generate_returns_plain_key_with_user_id_prefix(): void
|
||||
{
|
||||
$this->runInCoroutine(function (): void {
|
||||
$user = $this->createTestUser();
|
||||
@@ -56,28 +56,38 @@ class ApiKeyTest extends TestCase
|
||||
$this->assertArrayHasKey('plain_key', $result);
|
||||
$this->assertArrayHasKey('api_key', $result);
|
||||
$this->assertInstanceOf(ApiKey::class, $result['api_key']);
|
||||
$this->assertSame(64, strlen($result['plain_key']));
|
||||
|
||||
// 格式为 {user_id}#{64hex}
|
||||
$this->assertStringContainsString('#', $result['plain_key']);
|
||||
[$prefix, $token] = explode('#', $result['plain_key'], 2);
|
||||
$this->assertSame((string) $user->id, $prefix);
|
||||
$this->assertSame(64, strlen($token));
|
||||
$this->assertMatchesRegularExpression('/^[0-9a-f]{64}$/', $token);
|
||||
});
|
||||
}
|
||||
|
||||
public function test_generate_stores_sha256_hash(): void
|
||||
public function test_generate_stores_token_only_hash(): void
|
||||
{
|
||||
$this->runInCoroutine(function (): void {
|
||||
$user = $this->createTestUser();
|
||||
$result = ApiKey::generate($user->id, 'Hash Test');
|
||||
|
||||
$expected_hash = hash('sha256', $result['plain_key']);
|
||||
// key_hash 是 token 部分的 SHA-256,不含 user_id 前缀
|
||||
$token = explode('#', $result['plain_key'], 2)[1];
|
||||
$expected_hash = hash('sha256', $token);
|
||||
$this->assertSame($expected_hash, $result['api_key']->key_hash);
|
||||
});
|
||||
}
|
||||
|
||||
public function test_generate_stores_prefix(): void
|
||||
public function test_generate_key_prefix_from_token_part(): void
|
||||
{
|
||||
$this->runInCoroutine(function (): void {
|
||||
$user = $this->createTestUser();
|
||||
$result = ApiKey::generate($user->id, 'Prefix Test');
|
||||
|
||||
$expected_prefix = substr($result['plain_key'], 0, 8);
|
||||
// key_prefix 取 token 前 8 位(不是 plain_key 前 8 位)
|
||||
$token = explode('#', $result['plain_key'], 2)[1];
|
||||
$expected_prefix = substr($token, 0, 8);
|
||||
$this->assertSame($expected_prefix, $result['api_key']->key_prefix);
|
||||
});
|
||||
}
|
||||
@@ -94,10 +104,33 @@ class ApiKeyTest extends TestCase
|
||||
});
|
||||
}
|
||||
|
||||
public function test_find_by_plain_key_new_format(): void
|
||||
{
|
||||
$this->runInCoroutine(function (): void {
|
||||
$user = $this->createTestUser();
|
||||
$result = ApiKey::generate($user->id, 'New Format Test');
|
||||
|
||||
// 新格式 {user_id}#{token} 能正确查找
|
||||
$found = ApiKey::findByPlainKey($result['plain_key']);
|
||||
$this->assertNotNull($found);
|
||||
$this->assertSame($result['api_key']->id, $found->id);
|
||||
$this->assertSame($user->id, $found->user_id);
|
||||
});
|
||||
}
|
||||
|
||||
public function test_find_by_plain_key_rejects_old_format(): void
|
||||
{
|
||||
$this->runInCoroutine(function (): void {
|
||||
// 旧格式(纯 hex,不含 #)直接返回 null
|
||||
$found = ApiKey::findByPlainKey(bin2hex(random_bytes(32)));
|
||||
$this->assertNull($found);
|
||||
});
|
||||
}
|
||||
|
||||
public function test_find_by_plain_key_returns_null_for_invalid_key(): void
|
||||
{
|
||||
$this->runInCoroutine(function (): void {
|
||||
$found = ApiKey::findByPlainKey('invalid_key_that_does_not_exist');
|
||||
$found = ApiKey::findByPlainKey('999#invalid_token_that_does_not_exist');
|
||||
$this->assertNull($found);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user