feat(compat): Profile, Gates und Pods über den Kompatibilitätskern

Neu: Tier, Profile, Compatibility, CapabilityLocked, CapabilityGate, CompatibilityComponent, ProvidesCompatibility, DiviProfile sowie PodsFeature, PodsCompatibility und PodsIntegration. Das CapabilityGate sperrt gesperrte und unbekannte Fähigkeits-IDs (übernimmt die Sperre unbekannter IDs vom DiviFeatureGate) und delegiert nur Divi ausdrücklich. Pods-Schema, -Lesen, -Schreiben und -Feldrechte laufen über usable(PodsFeature::…); Schreiben verlangt FieldRead und FieldWrite, damit ein Rollback keine Werte verliert. lit-site-status meldet Pods über die CompatibilityComponent.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-11-06 12:26:54 +01:00
co-authored by Claude Opus 5.5
parent b511ef6348
commit c85131603b
38 changed files with 2259 additions and 135 deletions
+64
View File
@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Integrations\Pods;
use LIT\MCP\Compatibility\ProvidesCompatibility;
use LIT\MCP\Guides\InstructionsBuilder;
use LIT\MCP\Integrations\Integration;
use LIT\MCP\Integrations\IntegrationRegistry;
use LIT\MCP\Integrations\Pods\PodsCompatibility;
use LIT\MCP\Integrations\Pods\PodsIntegration;
use LIT\MCP\Tests\Unit\TestCase;
final class PodsIntegrationTest extends TestCase
{
public function testIsAnIntegrationWithoutAbilitiesThatProvidesItsProfile(): void
{
$integration = new PodsIntegration();
self::assertInstanceOf(Integration::class, $integration);
self::assertInstanceOf(ProvidesCompatibility::class, $integration);
self::assertSame('pods', $integration->id());
self::assertSame('Pods', $integration->label());
self::assertSame([], $integration->abilities());
self::assertEquals([PodsCompatibility::profile()], $integration->compatibilities());
}
public function testIsAvailableOnlyWithPods(): void
{
self::assertSame(defined('PODS_VERSION'), (new PodsIntegration())->isAvailable());
}
/** An available integration without abilities is no tool group, but it is an active integration. */
public function testAnAvailableIntegrationWithoutAbilitiesIsNoGroupButIsNamedAsActive(): void
{
$pods = new class implements Integration {
public function id(): string
{
return 'pods';
}
public function label(): string
{
return 'Pods';
}
public function isAvailable(): bool
{
return true;
}
public function abilities(): array
{
return [];
}
};
$registry = new IntegrationRegistry($pods);
self::assertSame([], $registry->grouped());
self::assertSame([], $registry->groupMap());
self::assertStringContainsString('Aktive Integrationen: pods.', (new InstructionsBuilder($registry))->build());
}
}