markTestSkipped('Daum postcode plugin settings.json not found'); } $this->assertTrue($plugin->hasSettings()); } /** * 설정 레이아웃 파일이 없으면 false 반환 */ public function test_hasSettings_returns_false_when_layout_not_exists(): void { $plugin = new class extends AbstractPlugin { public function getName(): string|array { return 'Test Plugin'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Test Description'; } public function getSettingsLayout(): ?string { return null; } }; $this->assertFalse($plugin->hasSettings()); } // ======================================================================== // getSettingsLayout() 테스트 // ======================================================================== /** * 기본 설정 레이아웃 경로 반환 테스트 (실제 플러그인) */ public function test_getSettingsLayout_returns_path_when_file_exists(): void { $layoutPath = base_path('plugins/sirsoft-daum_postcode/resources/layouts/settings.json'); if (! file_exists($layoutPath)) { $this->markTestSkipped('Daum postcode plugin settings.json not found'); } // 실제 Daum postcode 플러그인이 존재하면 테스트 $pluginPath = base_path('plugins/sirsoft-daum_postcode'); if (! is_dir($pluginPath)) { $this->markTestSkipped('Daum postcode plugin directory not found'); } // Mock plugin that returns the actual path $plugin = new class($pluginPath) extends AbstractPlugin { private string $testPluginPath; public function __construct(string $pluginPath) { $this->testPluginPath = $pluginPath; } public function getName(): string|array { return 'Test Plugin'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Test Description'; } protected function getPluginPath(): string { return $this->testPluginPath; } }; $result = $plugin->getSettingsLayout(); $this->assertNotNull($result); $this->assertStringEndsWith('settings.json', $result); $this->assertTrue(file_exists($result)); } /** * 설정 레이아웃 파일이 없으면 null 반환 */ public function test_getSettingsLayout_returns_null_when_file_not_exists(): void { $plugin = new class extends AbstractPlugin { public function getName(): string|array { return 'Test Plugin'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Test Description'; } protected function getPluginPath(): string { return '/nonexistent/path'; } }; $result = $plugin->getSettingsLayout(); $this->assertNull($result); } /** * 커스텀 레이아웃 경로 오버라이드 테스트 */ public function test_getSettingsLayout_can_be_overridden(): void { $customPath = '/custom/path/to/settings.json'; $plugin = new class($customPath) extends AbstractPlugin { private string $customLayoutPath; public function __construct(string $customLayoutPath) { $this->customLayoutPath = $customLayoutPath; } public function getName(): string|array { return 'Test Plugin'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Test Description'; } public function getSettingsLayout(): ?string { return $this->customLayoutPath; } }; $result = $plugin->getSettingsLayout(); $this->assertEquals($customPath, $result); } // ======================================================================== // getSettingsSchema() 테스트 // ======================================================================== /** * 기본 설정 스키마는 빈 배열 반환 */ public function test_getSettingsSchema_returns_empty_array_by_default(): void { $plugin = new class extends AbstractPlugin { public function getName(): string|array { return 'Test Plugin'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Test Description'; } }; $result = $plugin->getSettingsSchema(); $this->assertIsArray($result); $this->assertEmpty($result); } /** * 커스텀 설정 스키마 오버라이드 테스트 */ public function test_getSettingsSchema_can_be_overridden(): void { $plugin = new class extends AbstractPlugin { public function getName(): string|array { return 'Test Plugin'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Test Description'; } public function getSettingsSchema(): array { return [ 'api_key' => [ 'type' => 'string', 'label' => ['ko' => 'API 키', 'en' => 'API Key'], 'sensitive' => true, 'required' => true, ], 'timeout' => [ 'type' => 'integer', 'label' => ['ko' => '타임아웃', 'en' => 'Timeout'], 'default' => 30, ], 'enabled' => [ 'type' => 'boolean', 'label' => ['ko' => '활성화', 'en' => 'Enabled'], 'default' => true, ], 'mode' => [ 'type' => 'enum', 'options' => ['popup', 'layer'], 'label' => ['ko' => '모드', 'en' => 'Mode'], 'default' => 'layer', ], ]; } }; $result = $plugin->getSettingsSchema(); $this->assertIsArray($result); $this->assertCount(4, $result); // api_key 필드 검증 $this->assertArrayHasKey('api_key', $result); $this->assertEquals('string', $result['api_key']['type']); $this->assertTrue($result['api_key']['sensitive']); $this->assertTrue($result['api_key']['required']); // timeout 필드 검증 $this->assertArrayHasKey('timeout', $result); $this->assertEquals('integer', $result['timeout']['type']); $this->assertEquals(30, $result['timeout']['default']); // enabled 필드 검증 $this->assertArrayHasKey('enabled', $result); $this->assertEquals('boolean', $result['enabled']['type']); // mode 필드 검증 (enum) $this->assertArrayHasKey('mode', $result); $this->assertEquals('enum', $result['mode']['type']); $this->assertEquals(['popup', 'layer'], $result['mode']['options']); } /** * Daum 우편번호 플러그인의 실제 설정 스키마 테스트 */ public function test_daum_postcode_plugin_settings_schema(): void { // _bundled 디렉토리 우선 사용 (테스트 환경에서는 _bundled 기준으로 실행) $pluginFile = base_path('plugins/_bundled/sirsoft-daum_postcode/plugin.php'); if (! file_exists($pluginFile)) { $this->markTestSkipped('Daum postcode plugin not found in _bundled'); } // 이미 bootstrap에서 로드되었을 수 있으므로 class_exists 가드 사용 if (! class_exists('Plugins\\Sirsoft\\DaumPostcode\\Plugin', false)) { require_once $pluginFile; } $pluginClass = 'Plugins\\Sirsoft\\DaumPostcode\\PostcodePlugin'; if (! class_exists($pluginClass)) { $this->markTestSkipped('PostcodePlugin class not found'); } $plugin = new $pluginClass; $schema = $plugin->getSettingsSchema(); $this->assertIsArray($schema); // Daum 우편번호 플러그인의 설정 스키마 필드 확인 $this->assertArrayHasKey('display_mode', $schema); $this->assertEquals('enum', $schema['display_mode']['type']); $this->assertEquals(['popup', 'layer'], $schema['display_mode']['options']); $this->assertArrayHasKey('popup_width', $schema); $this->assertEquals('integer', $schema['popup_width']['type']); $this->assertArrayHasKey('popup_height', $schema); $this->assertEquals('integer', $schema['popup_height']['type']); $this->assertArrayHasKey('theme_color', $schema); $this->assertEquals('string', $schema['theme_color']['type']); } // ======================================================================== // 통합 테스트 // ======================================================================== /** * hasSettings()와 getSettingsLayout() 연동 테스트 */ public function test_hasSettings_uses_getSettingsLayout(): void { // getSettingsLayout이 값을 반환하면 hasSettings가 true $pluginWithLayout = new class extends AbstractPlugin { public function getName(): string|array { return 'Plugin With Layout'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Description'; } public function getSettingsLayout(): ?string { return '/some/path/settings.json'; } }; $this->assertTrue($pluginWithLayout->hasSettings()); // getSettingsLayout이 null을 반환하면 hasSettings가 false $pluginWithoutLayout = new class extends AbstractPlugin { public function getName(): string|array { return 'Plugin Without Layout'; } public function getVersion(): string { return '1.0.0'; } public function getDescription(): string|array { return 'Description'; } public function getSettingsLayout(): ?string { return null; } }; $this->assertFalse($pluginWithoutLayout->hasSettings()); } }