ReleaseStore, CheckReportStore, CheckReport, CheckStep und CompatibilityCheck liegen im Kern und arbeiten je Profil (Optionen lit_mcp_<id>_releases|_check_report; Divi behält Namen und Schlüssel divi_version). Divi hängt Katalog-, Format- und Schreibtest über Profile::extraSteps an. Ein roter Prüfbericht für den aktuellen Stand sperrt LockOnFailure-Profile bis zur nächsten grünen Prüfung; Sperrgründe nennen nur Schritt-Labels, Ausnahmen gehen ins Error-Log. Profile bekommt testedVersions, stateKey, extraSteps, manifestCheck und reportVersionKey und wird mit benannten Argumenten gebaut. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
118 lines
4.3 KiB
PHP
118 lines
4.3 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LIT\MCP\Tests\Unit\Integrations\Pods;
|
|
|
|
use LIT\MCP\Compatibility\Call;
|
|
use LIT\MCP\Compatibility\Compatibility;
|
|
use LIT\MCP\Compatibility\Tier;
|
|
use LIT\MCP\Integrations\Divi\Release\DiviProfile;
|
|
use LIT\MCP\Integrations\Pods\PodsCompatibility;
|
|
use LIT\MCP\Integrations\Pods\PodsFeature;
|
|
use LIT\MCP\Tests\Unit\TestCase;
|
|
|
|
final class PodsCompatibilityTest extends TestCase
|
|
{
|
|
/** @return array<string, Call> symbol => call */
|
|
private function calls(): array
|
|
{
|
|
$calls = [];
|
|
foreach (PodsCompatibility::profile()->manifests as $manifest) {
|
|
foreach ($manifest->calls as $call) {
|
|
$calls[$call->symbol] = $call;
|
|
}
|
|
}
|
|
|
|
return $calls;
|
|
}
|
|
|
|
public function testDescribesPodsAsALockOnFailurePlugin(): void
|
|
{
|
|
$profile = PodsCompatibility::profile();
|
|
|
|
self::assertSame('pods', $profile->id);
|
|
self::assertSame('Pods', $profile->label);
|
|
self::assertSame(Tier::LockOnFailure, $profile->tier);
|
|
self::assertSame('2.8', $profile->minVersion);
|
|
self::assertSame(['3.3.9.2'], $profile->testedVersions);
|
|
self::assertSame(PodsFeature::cases(), $profile->capabilities);
|
|
}
|
|
|
|
/** @runInSeparateProcess
|
|
* @preserveGlobalState disabled
|
|
*/
|
|
public function testActiveAndVersionFollowThePodsVersionConstant(): void
|
|
{
|
|
$profile = PodsCompatibility::profile();
|
|
self::assertFalse(($profile->active)());
|
|
self::assertNull(($profile->version)());
|
|
|
|
define('PODS_VERSION', '3.3.9.2');
|
|
|
|
self::assertTrue(($profile->active)());
|
|
self::assertSame('3.3.9.2', ($profile->version)());
|
|
}
|
|
|
|
public function testEveryPodsCallOfTheFieldSourceIsInTheManifest(): void
|
|
{
|
|
$code = '';
|
|
foreach (token_get_all((string) file_get_contents(dirname(__DIR__, 3) . '/../src/Integrations/Pods/PodsFieldSource.php')) as $token) {
|
|
if (is_array($token) && ! in_array($token[0], [T_COMMENT, T_DOC_COMMENT], true)) {
|
|
$code .= $token[1];
|
|
} elseif (is_string($token)) {
|
|
$code .= $token;
|
|
}
|
|
}
|
|
preg_match_all('/\b(pods(?:_[a-z_]+)?)\(/', $code, $found);
|
|
$used = array_values(array_unique(array_diff($found[1], ['pods_permission_denied'])));
|
|
|
|
self::assertContains('pods_api', $used);
|
|
foreach ($used as $function) {
|
|
self::assertArrayHasKey($function, $this->calls(), $function . ' is missing in the manifest');
|
|
}
|
|
foreach (['PodsAPI::load_pod', 'Pods::field', 'Pods::save'] as $method) {
|
|
self::assertArrayHasKey($method, $this->calls());
|
|
}
|
|
}
|
|
|
|
public function testArgumentCountsAreThoseOfTheFieldSource(): void
|
|
{
|
|
$args = array_map(static fn (Call $call): ?int => $call->args, $this->calls());
|
|
|
|
self::assertSame([
|
|
'pods_api' => 0,
|
|
'PodsAPI::load_pod' => 1,
|
|
'pods' => 2,
|
|
'Pods::field' => 1,
|
|
'Pods::save' => 4,
|
|
'pods_has_permissions' => 1,
|
|
'pods_permission' => 1,
|
|
], $args);
|
|
}
|
|
|
|
public function testEveryCapabilityHasACallOrTheConstant(): void
|
|
{
|
|
$manifest = PodsCompatibility::profile()->manifests[0];
|
|
$constantIds = array_map(static fn ($c) => array_map(static fn ($f) => $f->id(), $c->features()), $manifest->constants);
|
|
|
|
self::assertSame(['PODS_VERSION'], array_map(static fn ($c) => $c->name, $manifest->constants));
|
|
self::assertEqualsCanonicalizing(
|
|
array_map(static fn (PodsFeature $f): string => $f->id(), PodsFeature::cases()),
|
|
$constantIds[0]
|
|
);
|
|
foreach (PodsFeature::cases() as $feature) {
|
|
$owners = array_filter($manifest->calls, static fn (Call $call): bool => in_array($feature, $call->features(), true));
|
|
self::assertNotSame([], $owners, $feature->id() . ' has no call');
|
|
}
|
|
}
|
|
|
|
public function testPodsAndDiviProfilesCoexistWithoutIdCollision(): void
|
|
{
|
|
$compatibility = new Compatibility([DiviProfile::profile(), PodsCompatibility::profile()]);
|
|
|
|
self::assertSame(['divi', 'pods'], array_map(static fn ($p) => $p->id, $compatibility->profiles()));
|
|
self::assertSame(PodsFeature::FieldRead, $compatibility->capability('pods-field-read'));
|
|
}
|
|
}
|