update test

This commit is contained in:
2026-03-09 10:15:43 +08:00
parent a2e8143b6a
commit d5151ce31c
4 changed files with 788 additions and 0 deletions
@@ -0,0 +1,156 @@
<?php
declare(strict_types=1);
namespace HyperfTest\Cases\Unit\Model;
use App\Model\ApiKey;
use App\Model\User;
use PHPUnit\Framework\TestCase;
/**
* @internal
* @coversNothing
*/
class ApiKeyTest extends TestCase
{
protected function runInCoroutine(callable $callback): void
{
$exception = null;
\Swoole\Coroutine\run(static function () use ($callback, &$exception): void {
try {
$callback();
} catch (\Throwable $e) {
$exception = $e;
}
});
if ($exception) {
throw $exception;
}
}
protected function createTestUser(): User
{
$suffix = bin2hex(random_bytes(4));
return User::query()->create([
'username' => 'apikey_test_' . $suffix,
'password' => 'Pass_' . $suffix,
'email' => 'apikey_test_' . $suffix . '@example.com',
'status' => 1,
'api_key_enabled' => true,
]);
}
public function test_generate_returns_plain_key_and_model(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Test Key');
$this->assertArrayHasKey('plain_key', $result);
$this->assertArrayHasKey('api_key', $result);
$this->assertInstanceOf(ApiKey::class, $result['api_key']);
$this->assertSame(64, strlen($result['plain_key']));
});
}
public function test_generate_stores_sha256_hash(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Hash Test');
$expected_hash = hash('sha256', $result['plain_key']);
$this->assertSame($expected_hash, $result['api_key']->key_hash);
});
}
public function test_generate_stores_prefix(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Prefix Test');
$expected_prefix = substr($result['plain_key'], 0, 8);
$this->assertSame($expected_prefix, $result['api_key']->key_prefix);
});
}
public function test_find_by_plain_key_returns_valid_key(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Find Test');
$found = ApiKey::findByPlainKey($result['plain_key']);
$this->assertNotNull($found);
$this->assertSame($result['api_key']->id, $found->id);
});
}
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');
$this->assertNull($found);
});
}
public function test_find_by_plain_key_excludes_disabled_key(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Disabled Test');
$result['api_key']->enabled = false;
$result['api_key']->save();
$found = ApiKey::findByPlainKey($result['plain_key']);
$this->assertNull($found);
});
}
public function test_find_by_plain_key_excludes_expired_key(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Expired Test', \Carbon\Carbon::now()->subDay()->toDateTimeString());
$found = ApiKey::findByPlainKey($result['plain_key']);
$this->assertNull($found);
});
}
public function test_key_hash_is_hidden_in_json(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Hidden Test');
$json = $result['api_key']->toArray();
$this->assertArrayNotHasKey('key_hash', $json);
});
}
public function test_is_valid_returns_true_for_active_key(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Valid Test');
$this->assertTrue($result['api_key']->isValid());
});
}
public function test_is_valid_returns_false_for_disabled_key(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createTestUser();
$result = ApiKey::generate($user->id, 'Disabled Valid');
$result['api_key']->enabled = false;
$this->assertFalse($result['api_key']->isValid());
});
}
}
@@ -0,0 +1,69 @@
<?php
declare(strict_types=1);
namespace HyperfTest\Cases\Unit\Model;
use App\Model\Role;
use PHPUnit\Framework\TestCase;
/**
* @internal
* @coversNothing
*/
class RoleTest extends TestCase
{
protected function runInCoroutine(callable $callback): void
{
$exception = null;
\Swoole\Coroutine\run(static function () use ($callback, &$exception): void {
try {
$callback();
} catch (\Throwable $e) {
$exception = $e;
}
});
if ($exception) {
throw $exception;
}
}
public function test_role_has_correct_fillable(): void
{
$role = new Role();
$this->assertEqualsCanonicalizing(['name', 'label', 'description'], $role->getFillable());
}
public function test_role_table_name(): void
{
$role = new Role();
$this->assertSame('roles', $role->getTable());
}
public function test_administrator_role_exists(): void
{
$this->runInCoroutine(function (): void {
$role = Role::query()->where('name', 'administrator')->first();
$this->assertNotNull($role);
$this->assertSame('超级管理员', $role->label);
});
}
public function test_developer_role_exists(): void
{
$this->runInCoroutine(function (): void {
$role = Role::query()->where('name', 'developer')->first();
$this->assertNotNull($role);
$this->assertSame('开发者', $role->label);
});
}
public function test_accessor_role_exists(): void
{
$this->runInCoroutine(function (): void {
$role = Role::query()->where('name', 'accessor')->first();
$this->assertNotNull($role);
$this->assertSame('数据访问者', $role->label);
});
}
}
@@ -0,0 +1,102 @@
<?php
declare(strict_types=1);
namespace HyperfTest\Cases\Unit\Model;
use App\Model\Role;
use App\Model\User;
use PHPUnit\Framework\TestCase;
/**
* @internal
* @coversNothing
*/
class UserRoleTest extends TestCase
{
protected function runInCoroutine(callable $callback): void
{
$exception = null;
\Swoole\Coroutine\run(static function () use ($callback, &$exception): void {
try {
$callback();
} catch (\Throwable $e) {
$exception = $e;
}
});
if ($exception) {
throw $exception;
}
}
protected function createUserWithRole(string $role_name): User
{
$role = Role::query()->where('name', $role_name)->firstOrFail();
$suffix = bin2hex(random_bytes(4));
return User::query()->create([
'username' => 'role_test_' . $suffix,
'password' => 'Pass_' . $suffix,
'email' => 'role_test_' . $suffix . '@example.com',
'status' => 1,
'role_id' => $role->id,
]);
}
public function test_user_belongs_to_role(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createUserWithRole('administrator');
$this->assertNotNull($user->role);
$this->assertSame('administrator', $user->role->name);
});
}
public function test_is_administrator(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createUserWithRole('administrator');
$this->assertTrue($user->isAdministrator());
$this->assertFalse($user->isDeveloper());
$this->assertFalse($user->isAccessor());
});
}
public function test_is_developer(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createUserWithRole('developer');
$this->assertFalse($user->isAdministrator());
$this->assertTrue($user->isDeveloper());
$this->assertFalse($user->isAccessor());
});
}
public function test_is_accessor(): void
{
$this->runInCoroutine(function (): void {
$user = $this->createUserWithRole('accessor');
$this->assertFalse($user->isAdministrator());
$this->assertFalse($user->isDeveloper());
$this->assertTrue($user->isAccessor());
});
}
public function test_user_without_role(): void
{
$this->runInCoroutine(function (): void {
$suffix = bin2hex(random_bytes(4));
$user = User::query()->create([
'username' => 'no_role_' . $suffix,
'password' => 'Pass_' . $suffix,
'email' => 'no_role_' . $suffix . '@example.com',
'status' => 1,
]);
$this->assertNull($user->role);
$this->assertFalse($user->isAdministrator());
$this->assertFalse($user->isDeveloper());
$this->assertFalse($user->isAccessor());
});
}
}