feat(cache): WP Super Cache über den Kompatibilitätskern anbinden

SuperCacheFeature, SuperCacheCompatibility (LockOnFailure, getestet 3.1.5, Version aus dem Plugin-Header) und SuperCacheIntegration ohne Tools. Der SuperCacheListener sammelt Änderungen über lit_mcp_changed und leert einmal am Request-Ende: einen Beitrag per wp_cache_post_edit, mehrere Beiträge oder seitenweite Änderungen per wp_cache_clear_cache (Multisite: eigener Blog). Komplett-Purges höchstens alle 30 s, mit genau einem Nachlauf per WP-Cron. Freigabe-Einträge leeren nichts. Uninstaller räumt Optionen, Transient und Cron-Hook ab; Reiter und lit-site-status zeigen das Profil automatisch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-11-06 14:50:35 +01:00
co-authored by Claude Opus 5.5
parent c383b99e7d
commit 05bf890481
16 changed files with 1054 additions and 21 deletions
@@ -0,0 +1,104 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Integrations\SuperCache;
use Brain\Monkey\Functions;
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\SuperCache\SuperCacheCompatibility;
use LIT\MCP\Integrations\SuperCache\SuperCacheFeature;
use LIT\MCP\Tests\Unit\TestCase;
final class SuperCacheCompatibilityTest extends TestCase
{
public function testDescribesSuperCacheAsALockOnFailurePlugin(): void
{
$profile = SuperCacheCompatibility::profile();
self::assertSame('wpsc', $profile->id);
self::assertSame('WP Super Cache', $profile->label);
self::assertSame(Tier::LockOnFailure, $profile->tier);
self::assertSame(['3.1.5'], $profile->testedVersions);
self::assertNull($profile->minVersion);
self::assertSame(SuperCacheFeature::cases(), $profile->capabilities);
}
/** Argument counts are those the listener passes; wp_cache_clear_cache($blog_id = 0) gets the blog. */
public function testTheManifestHoldsTheTwoPurgeFunctionsWithTheirArgumentCounts(): void
{
$manifest = SuperCacheCompatibility::profile()->manifests[0];
$calls = [];
foreach ($manifest->calls as $call) {
$calls[$call->symbol] = [$call->args, $call->features()];
}
self::assertSame([
'wp_cache_post_edit' => [1, [SuperCacheFeature::PurgePost]],
'wp_cache_clear_cache' => [1, [SuperCacheFeature::PurgeAll]],
], $calls);
self::assertContainsOnlyInstancesOf(Call::class, $manifest->calls);
}
/** Both purge functions read $cache_path; wp_cache_post_edit also $blog_cache_dir. */
public function testTheGlobalsTheFunctionsReadAreRequired(): void
{
$manifest = SuperCacheCompatibility::profile()->manifests[0];
self::assertSame(['WPCACHEHOME'], array_map(static fn ($c) => $c->name, $manifest->constants));
$globals = [];
foreach ($manifest->globals as $global) {
$globals[$global->name] = $global->features();
}
self::assertSame(
['cache_path' => SuperCacheFeature::cases(), 'blog_cache_dir' => [SuperCacheFeature::PurgePost]],
$globals
);
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testActiveAndVersionFollowTheCacheHomeConstantAndThePluginHeader(): void
{
$profile = SuperCacheCompatibility::profile();
self::assertFalse(($profile->active)());
self::assertNull(($profile->version)());
define('WPCACHEHOME', '/plugins/wp-super-cache/');
Functions\expect('get_file_data')
->once()
->with('/plugins/wp-super-cache/wp-cache.php', ['Version' => 'Version'])
->andReturn(['Version' => '3.1.5']);
self::assertTrue(($profile->active)());
self::assertSame('3.1.5', ($profile->version)());
}
/**
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testAnUnreadableHeaderIsAnUnknownVersion(): void
{
define('WPCACHEHOME', '/plugins/wp-super-cache/');
Functions\when('get_file_data')->justReturn(['Version' => '']);
self::assertNull((SuperCacheCompatibility::profile()->version)());
}
public function testAllProfilesCoexistWithoutIdCollision(): void
{
$compatibility = new Compatibility(
[DiviProfile::profile(), PodsCompatibility::profile(), SuperCacheCompatibility::profile()]
);
self::assertSame(['divi', 'pods', 'wpsc'], array_map(static fn ($p) => $p->id, $compatibility->profiles()));
self::assertSame(SuperCacheFeature::PurgeAll, $compatibility->capability('wpsc-purge-all'));
}
}