Files
Gnuboard7/tests/Feature/Extension/ValidatesPermissionStructureTest.php
T
2026-04-01 10:30:52 +09:00

663 lines
20 KiB
PHP

<?php
namespace Tests\Feature\Extension;
use App\Extension\Traits\ValidatesPermissionStructure;
use Tests\TestCase;
class ValidatesPermissionStructureTest extends TestCase
{
private object $traitUser;
protected function setUp(): void
{
parent::setUp();
// Trait을 사용하는 익명 클래스 생성
$this->traitUser = new class
{
use ValidatesPermissionStructure;
/**
* 테스트를 위해 public으로 노출
*/
public function testValidatePermissionStructure(object $extension, string $type = 'module'): void
{
$this->validatePermissionStructure($extension, $type);
}
};
}
/**
* 유효한 권한 구조를 가진 모듈 객체 생성
*/
private function createValidModuleMock(): object
{
return new class
{
public function getIdentifier(): string
{
return 'test-module';
}
public function getPermissions(): array
{
return [
'name' => [
'ko' => '테스트',
'en' => 'Test',
],
'description' => [
'ko' => '테스트 모듈 권한',
'en' => 'Test module permissions',
],
'categories' => [
[
'identifier' => 'items',
'name' => [
'ko' => '항목 관리',
'en' => 'Item Management',
],
'description' => [
'ko' => '항목 관리 권한',
'en' => 'Item management permissions',
],
'permissions' => [
[
'action' => 'view',
'name' => [
'ko' => '항목 조회',
'en' => 'View Items',
],
'description' => [
'ko' => '항목을 조회할 수 있는 권한',
'en' => 'Permission to view items',
],
'roles' => ['admin'],
],
],
],
],
];
}
};
}
/**
* 올바른 계층형 권한 구조 검증 통과 테스트
*/
public function test_valid_hierarchical_permission_structure_passes(): void
{
$module = $this->createValidModuleMock();
// 예외가 발생하지 않아야 함
$this->traitUser->testValidatePermissionStructure($module);
$this->assertTrue(true);
}
/**
* 빈 권한 구조 검증 통과 테스트
*/
public function test_empty_permission_structure_passes(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'empty-module';
}
public function getPermissions(): array
{
return [];
}
};
// 빈 배열은 검증 통과
$this->traitUser->testValidatePermissionStructure($module);
$this->assertTrue(true);
}
/**
* categories 필드 누락 시 예외 발생 테스트
*/
public function test_missing_categories_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
// categories 누락
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/categories/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* categories가 배열이 아닐 때 예외 발생 테스트
*/
public function test_categories_not_array_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => 'not-an-array',
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/categories/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* name 필드 누락 시 예외 발생 테스트
*/
public function test_missing_name_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
// name 누락
'categories' => [],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/name/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* name이 문자열일 때 예외 발생 테스트 (다국어 배열 필수)
*/
public function test_name_as_string_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => 'Not multilingual',
'categories' => [],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/name/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* 카테고리에 identifier 누락 시 예외 발생 테스트
*/
public function test_category_missing_identifier_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
// identifier 누락
'name' => ['ko' => '항목', 'en' => 'Items'],
'permissions' => [],
],
],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/identifier/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* 카테고리에 name 누락 시 예외 발생 테스트
*/
public function test_category_missing_name_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
'identifier' => 'items',
// name 누락
'permissions' => [],
],
],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/name/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* 카테고리에 permissions 누락 시 예외 발생 테스트
*/
public function test_category_missing_permissions_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
'identifier' => 'items',
'name' => ['ko' => '항목', 'en' => 'Items'],
// permissions 누락
],
],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/permissions/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* 개별 권한에 action 누락 시 예외 발생 테스트
*/
public function test_permission_missing_action_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
'identifier' => 'items',
'name' => ['ko' => '항목', 'en' => 'Items'],
'permissions' => [
[
// action 누락
'name' => ['ko' => '조회', 'en' => 'View'],
],
],
],
],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/action/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* 개별 권한에 name 누락 시 예외 발생 테스트
*/
public function test_permission_missing_name_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
'identifier' => 'items',
'name' => ['ko' => '항목', 'en' => 'Items'],
'permissions' => [
[
'action' => 'view',
// name 누락
],
],
],
],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/name/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* 개별 권한의 name이 문자열일 때 예외 발생 테스트
*/
public function test_permission_name_as_string_throws_exception(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
'identifier' => 'items',
'name' => ['ko' => '항목', 'en' => 'Items'],
'permissions' => [
[
'action' => 'view',
'name' => 'Not multilingual', // 문자열
],
],
],
],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/name/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* 여러 카테고리 검증 테스트
*/
public function test_multiple_categories_validation(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'multi-category-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
'identifier' => 'items',
'name' => ['ko' => '항목', 'en' => 'Items'],
'permissions' => [
[
'action' => 'view',
'name' => ['ko' => '조회', 'en' => 'View'],
],
],
],
[
'identifier' => 'reports',
'name' => ['ko' => '보고서', 'en' => 'Reports'],
'permissions' => [
[
'action' => 'read',
'name' => ['ko' => '읽기', 'en' => 'Read'],
],
[
'action' => 'export',
'name' => ['ko' => '내보내기', 'en' => 'Export'],
],
],
],
],
];
}
};
// 예외가 발생하지 않아야 함
$this->traitUser->testValidatePermissionStructure($module);
$this->assertTrue(true);
}
/**
* 두 번째 카테고리에서 오류 발생 시 정확한 인덱스 표시 테스트
*/
public function test_error_message_shows_correct_category_index(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'invalid-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
'identifier' => 'valid',
'name' => ['ko' => '유효', 'en' => 'Valid'],
'permissions' => [],
],
[
// 두 번째 카테고리에 identifier 누락
'name' => ['ko' => '무효', 'en' => 'Invalid'],
'permissions' => [],
],
],
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/\[1\]/');
$this->traitUser->testValidatePermissionStructure($module);
}
/**
* 플러그인 타입으로 검증 테스트
*/
public function test_validation_with_plugin_type(): void
{
$plugin = new class
{
public function getIdentifier(): string
{
return 'invalid-plugin';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
// categories 누락
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/categories/');
$this->traitUser->testValidatePermissionStructure($plugin, 'plugin');
}
/**
* description 필드는 선택적임을 테스트
*/
public function test_description_is_optional(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'no-description-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
// description 없음
'categories' => [
[
'identifier' => 'items',
'name' => ['ko' => '항목', 'en' => 'Items'],
// description 없음
'permissions' => [
[
'action' => 'view',
'name' => ['ko' => '조회', 'en' => 'View'],
// description 없음
],
],
],
],
];
}
};
// description이 없어도 검증 통과
$this->traitUser->testValidatePermissionStructure($module);
$this->assertTrue(true);
}
/**
* roles 필드는 선택적임을 테스트
*/
public function test_roles_is_optional(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'no-roles-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
'categories' => [
[
'identifier' => 'items',
'name' => ['ko' => '항목', 'en' => 'Items'],
'permissions' => [
[
'action' => 'view',
'name' => ['ko' => '조회', 'en' => 'View'],
// roles 없음
],
],
],
],
];
}
};
// roles가 없어도 검증 통과
$this->traitUser->testValidatePermissionStructure($module);
$this->assertTrue(true);
}
/**
* 에러 메시지에 모듈 식별자가 포함되는지 테스트
*/
public function test_error_message_contains_module_identifier(): void
{
$module = new class
{
public function getIdentifier(): string
{
return 'my-test-module';
}
public function getPermissions(): array
{
return [
'name' => ['ko' => '테스트', 'en' => 'Test'],
// categories 누락
];
}
};
$this->expectException(\Exception::class);
$this->expectExceptionMessageMatches('/my-test-module/');
$this->traitUser->testValidatePermissionStructure($module);
}
}