feat(cache): Verhaltensprobe und Smoke für WP Super Cache

SuperCacheProbe prüft beim Prüfen, ob wp_cache_post_edit die Cache-Datei einer Testseite entfernt; während der Probe ist nur der Einzelseiten-Purge erlaubt, der Pfad kommt aus home und es werden nur feste Dateinamen gelöscht. ProbeStep bündelt die Schrittlogik von Pods und WP Super Cache; ThrowawayPost hält Marker und Titel zentral und räumt auch private Probe-Seiten auf (WP Super Cache wie Pods beim Laden des Reiters). super-cache-smoke.sh prüft gegen das echte Plugin; lib.sh sperrt parallele Smoke-Läufe per flock, wp-config.php wird atomar wiederhergestellt. Doku: Host-Abhängigkeit des Einzel-Purges, WP-Cron für den Nachlauf, Komplett-Purge durch Divi beim Prüfen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jan-Niclas Loosen
2026-11-06 17:25:37 +01:00
co-authored by Claude Opus 5.5
parent 05bf890481
commit 661d3945fd
22 changed files with 1432 additions and 49 deletions
@@ -0,0 +1,80 @@
<?php
declare(strict_types=1);
namespace LIT\MCP\Tests\Unit\Compatibility;
use Closure;
use LIT\MCP\Compatibility\ProbeStep;
use LIT\MCP\Tests\Unit\TestCase;
use RuntimeException;
final class ProbeStepTest extends TestCase
{
/** @param Closure(): (list<string>|null) $probe */
private function step(Closure $probe): Closure
{
return ProbeStep::extra('probe', 'Prüfung', 'Prüfung (nichts zu prüfen)', $probe);
}
public function testASkippedStepWithARedManifestThatNeverRunsTheProbe(): void
{
$ran = false;
$steps = $this->step(static function () use (&$ran): array {
$ran = true;
return [];
})(false);
self::assertCount(1, $steps);
self::assertSame('probe', $steps[0]->key);
self::assertTrue($steps[0]->skipped);
self::assertFalse($steps[0]->green());
self::assertSame('Prüfung', $steps[0]->label());
self::assertFalse($ran);
}
/** Nothing to probe is no red step: a skipped or red one would lock the plugin on a site that has nothing yet. */
public function testNullIsAGreenStepWithTheHintLabel(): void
{
$steps = $this->step(static fn (): ?array => null)(true);
self::assertCount(1, $steps);
self::assertTrue($steps[0]->green());
self::assertSame('Prüfung (nichts zu prüfen)', $steps[0]->label());
}
public function testGreenKeepsTheNormalLabel(): void
{
$steps = $this->step(static fn (): array => [])(true);
self::assertTrue($steps[0]->green());
self::assertSame('Prüfung', $steps[0]->label());
}
public function testProblemsArePassedThrough(): void
{
$steps = $this->step(static fn (): array => ['rot', 'gelb'])(true);
self::assertSame(['rot', 'gelb'], $steps[0]->problems);
self::assertFalse($steps[0]->skipped);
self::assertSame('Prüfung', $steps[0]->label());
}
public function testAThrowingProbeIsOneFixedProblem(): void
{
$log = (string) tempnam(sys_get_temp_dir(), 'lit-mcp-log');
$previous = ini_set('error_log', $log);
try {
$steps = $this->step(static function (): never {
throw new RuntimeException('innen');
})(true);
} finally {
ini_set('error_log', (string) $previous);
unlink($log);
}
self::assertSame(['Prüfschritt abgebrochen (Details im PHP-Error-Log).'], $steps[0]->problems);
self::assertSame('Prüfung', $steps[0]->label());
}
}
+17 -1
View File
@@ -222,7 +222,7 @@ final class ThrowawayPostTest extends TestCase
$this->throwaway()->removeOrphans(['post', 'lit_person']);
self::assertSame(['post', 'lit_person'], $query['post_type']);
self::assertSame('draft', $query['post_status']);
self::assertSame(['draft', 'private'], $query['post_status']);
self::assertSame('_marker', $query['meta_key']);
$this->throwaway()->removeOrphans('page');
@@ -244,4 +244,20 @@ final class ThrowawayPostTest extends TestCase
self::assertSame([], $this->throwaway()->removeOrphans('page'));
}
/** A probe killed while its page was private (WP Super Cache) leaves a private page, not a draft. */
public function testShortStatusListCoversAProbeKilledWhilePrivate(): void
{
$query = null;
$this->fakeQuery([self::draft(5, 900)], $query);
self::assertSame([5], $this->throwaway()->removeOrphans('page'));
self::assertContains('private', $query['post_status']);
}
public function testTheSharedMarkerAndTitlePrefixOfTheProbes(): void
{
self::assertSame('_lit_mcp_check_entry', ThrowawayPost::MARKER);
self::assertSame('[LIT MCP Prüfung]', ThrowawayPost::TITLE);
}
}