- plugin.json 新增 usage 字段(多行文本),后台插件卡片折叠展示;四个内置插件补齐使用说明 - PageCacheMiddleware 记录命中/未命中计数(按日滚动),仪表盘新增「页面缓存」统计卡(条目数 + 命中率),用于判断前台缓存效果、是否需额外加速 - 文档与测试同步
118 lines
3.9 KiB
PHP
118 lines
3.9 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace Tests\Feature;
|
||
|
||
use App\Blog\Support\PluginManager;
|
||
use Illuminate\Foundation\Testing\RefreshDatabase;
|
||
use RuntimeException;
|
||
use Tests\TestCase;
|
||
|
||
class PluginDependencyTest extends TestCase
|
||
{
|
||
use RefreshDatabase;
|
||
|
||
private function manager(): PluginManager
|
||
{
|
||
return app(PluginManager::class);
|
||
}
|
||
|
||
public function test_enable_plugin_with_disabled_dependency_throws(): void
|
||
{
|
||
$manager = $this->manager();
|
||
|
||
// 先停用无依赖者的 membership,再停用 payment(此时无启用的依赖者)
|
||
$manager->disable('neatstudio.membership');
|
||
$manager->disable('neatstudio.payment');
|
||
|
||
try {
|
||
$manager->enable('neatstudio.membership');
|
||
$this->fail('依赖未启用时应抛出异常');
|
||
} catch (RuntimeException $e) {
|
||
$this->assertStringContainsString('neatstudio.payment', $e->getMessage());
|
||
}
|
||
|
||
$this->assertFalse($manager->isEnabled('neatstudio.membership'));
|
||
}
|
||
|
||
public function test_disable_plugin_with_enabled_dependent_throws(): void
|
||
{
|
||
$manager = $this->manager();
|
||
|
||
// 默认状态下 payment 已启用且 membership 依赖它
|
||
try {
|
||
$manager->disable('neatstudio.payment');
|
||
$this->fail('存在已启用的依赖者时应抛出异常');
|
||
} catch (RuntimeException $e) {
|
||
$this->assertStringContainsString('neatstudio.membership', $e->getMessage());
|
||
}
|
||
|
||
$this->assertTrue($manager->isEnabled('neatstudio.payment'));
|
||
}
|
||
|
||
public function test_disable_plugin_without_dependents_works(): void
|
||
{
|
||
$manager = $this->manager();
|
||
|
||
$manager->disable('neatstudio.membership');
|
||
$this->assertFalse($manager->isEnabled('neatstudio.membership'));
|
||
|
||
// 依赖(payment)仍启用,可重新启用
|
||
$manager->enable('neatstudio.membership');
|
||
$this->assertTrue($manager->isEnabled('neatstudio.membership'));
|
||
}
|
||
|
||
public function test_all_reports_dependency_status(): void
|
||
{
|
||
$manager = $this->manager();
|
||
|
||
$plugins = $manager->all();
|
||
$member = $plugins['neatstudio.membership'];
|
||
|
||
$this->assertSame(['neatstudio.payment'], $member['requires']);
|
||
$this->assertTrue($member['dependencies'][0]['ok']);
|
||
$this->assertEmpty($member['dependency_errors']);
|
||
$this->assertNotEmpty($member['usage']);
|
||
|
||
// 停用依赖后,依赖状态应变为失败
|
||
$manager->disable('neatstudio.membership');
|
||
$manager->disable('neatstudio.payment');
|
||
|
||
$plugins = $manager->all();
|
||
$this->assertFalse($plugins['neatstudio.membership']['dependencies'][0]['ok']);
|
||
$this->assertSame(['neatstudio.payment'], $plugins['neatstudio.membership']['dependency_errors']);
|
||
}
|
||
|
||
public function test_uninstall_plugin_with_enabled_dependent_throws(): void
|
||
{
|
||
$manager = $this->manager();
|
||
|
||
try {
|
||
$manager->uninstall('neatstudio.payment');
|
||
$this->fail('存在已启用的依赖者时应抛出异常');
|
||
} catch (RuntimeException $e) {
|
||
$this->assertStringContainsString('neatstudio.membership', $e->getMessage());
|
||
}
|
||
|
||
// 卸载失败,记录仍在
|
||
$this->assertTrue($manager->isEnabled('neatstudio.payment'));
|
||
}
|
||
|
||
public function test_dependency_problems_for_missing_plugin(): void
|
||
{
|
||
$manager = $this->manager();
|
||
|
||
// 默认依赖完好
|
||
$this->assertSame([], $manager->dependencyProblems('neatstudio.membership'));
|
||
|
||
// 停用依赖后出现问题(先停用无依赖者的 membership)
|
||
$manager->disable('neatstudio.membership');
|
||
$manager->disable('neatstudio.payment');
|
||
$this->assertNotEmpty($manager->dependencyProblems('neatstudio.membership'));
|
||
|
||
// 不存在的插件没有依赖问题(空 requires)
|
||
$this->assertSame([], $manager->dependencyProblems('neatstudio.does-not-exist'));
|
||
}
|
||
}
|