refactor: ReleaseGate::invalidate() als einzige Stelle zum Zurücksetzen des Freigabe-Zustands; CompatibilityMatrix::locked() und ReleaseGate::lockOf() ersetzen die drei Kopien der Sperrprüfung
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
7f9a087b8b
commit
63389f35a8
@@ -8,6 +8,7 @@ use LIT\MCP\Integrations\Divi\Release\CompatibilityMatrix;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\Divi\Release\FeatureStatus;
|
||||
use LIT\MCP\Integrations\Divi\Release\ReleaseState;
|
||||
use LIT\MCP\Tests\Support\ReleaseMatrices;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
final class CompatibilityMatrixTest extends TestCase
|
||||
@@ -84,6 +85,29 @@ final class CompatibilityMatrixTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testLockedNamesEveryUnusableFeatureOnceInTheGivenOrder(): void
|
||||
{
|
||||
$matrix = ReleaseMatrices::matrix(
|
||||
[DiviFeature::LibraryWrite, DiviFeature::ThemeBuilderWrite, DiviFeature::Catalog],
|
||||
ReleaseState::Incompatible
|
||||
);
|
||||
|
||||
$locked = $matrix->locked([
|
||||
DiviFeature::PageWrite,
|
||||
DiviFeature::ThemeBuilderWrite,
|
||||
DiviFeature::LibraryWrite,
|
||||
DiviFeature::ThemeBuilderWrite,
|
||||
]);
|
||||
|
||||
self::assertSame(
|
||||
[DiviFeature::ThemeBuilderWrite, DiviFeature::LibraryWrite],
|
||||
array_map(static fn (FeatureStatus $status): DiviFeature => $status->feature, $locked)
|
||||
);
|
||||
self::assertSame(ReleaseState::Incompatible, $locked[0]->state);
|
||||
self::assertSame([], $matrix->locked([DiviFeature::PageWrite, DiviFeature::PageRead]));
|
||||
self::assertSame([], $matrix->locked([]));
|
||||
}
|
||||
|
||||
public function testToArrayListsEveryFeatureInCaseOrder(): void
|
||||
{
|
||||
$rows = self::matrix(['tb-write' => [ReleaseState::Incompatible, ['b']]])->toArray();
|
||||
|
||||
@@ -317,19 +317,6 @@ final class DiviFeatureGateTest extends TestCase
|
||||
);
|
||||
}
|
||||
|
||||
public function testLockForIsNullForUsableFeaturesAndNamesTheUnusableOnesOtherwise(): void
|
||||
{
|
||||
self::assertNull(DiviFeatureGate::lockFor([]));
|
||||
self::assertNull(DiviFeatureGate::lockFor([DiviFeature::PageWrite]));
|
||||
|
||||
DiviFeatureFixtures::lock(DiviFeature::Catalog);
|
||||
$lock = DiviFeatureGate::lockFor([DiviFeature::PageWrite, DiviFeature::Catalog, DiviFeature::Catalog]);
|
||||
|
||||
self::assertNotNull($lock);
|
||||
self::assertSame([DiviFeature::Catalog], $lock->features);
|
||||
self::assertSame('5.3.0', $lock->status->version);
|
||||
}
|
||||
|
||||
/**
|
||||
* The real tools of the three Divi groups: locking one capability refuses exactly the tools that declare it
|
||||
* (reading and writing alike) and no other.
|
||||
|
||||
@@ -4,12 +4,15 @@ declare(strict_types=1);
|
||||
|
||||
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Release;
|
||||
|
||||
use Brain\Monkey\Functions;
|
||||
use LIT\MCP\Abilities\WriteFailed;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||||
use LIT\MCP\Integrations\Divi\Release\DiviLocked;
|
||||
use LIT\MCP\Integrations\Divi\Release\ReleaseGate;
|
||||
use LIT\MCP\Integrations\Divi\Release\ReleaseResolver;
|
||||
use LIT\MCP\Integrations\Divi\Release\ReleaseState;
|
||||
use LIT\MCP\Integrations\Divi\Release\ReleaseStatus;
|
||||
use LIT\MCP\Tests\Support\DiviFeatureFixtures;
|
||||
use LIT\MCP\Tests\Support\ReleaseMatrices;
|
||||
use LIT\MCP\Tests\Unit\TestCase;
|
||||
use RuntimeException;
|
||||
@@ -27,12 +30,17 @@ final class ReleaseGateTest extends TestCase
|
||||
ReleaseGate::assertFeatures(DiviFeature::cases(), 7);
|
||||
}
|
||||
|
||||
public function testFeatureReadsTheMatrixOfThisRequest(): void
|
||||
public function testLockOfIsNullForUsableFeaturesAndNamesTheUnusableOnesOtherwise(): void
|
||||
{
|
||||
ReleaseGate::useResolver(static fn (): ReleaseStatus => ReleaseMatrices::status([DiviFeature::Catalog]));
|
||||
self::assertNull(ReleaseGate::lockOf([]));
|
||||
self::assertNull(ReleaseGate::lockOf([DiviFeature::PageWrite]));
|
||||
|
||||
self::assertSame(ReleaseState::Untested, ReleaseGate::feature(DiviFeature::Catalog)->state);
|
||||
self::assertTrue(ReleaseGate::feature(DiviFeature::PageRead)->usable());
|
||||
DiviFeatureFixtures::lock(DiviFeature::Catalog);
|
||||
$lock = ReleaseGate::lockOf([DiviFeature::PageWrite, DiviFeature::Catalog, DiviFeature::Catalog]);
|
||||
|
||||
self::assertNotNull($lock);
|
||||
self::assertSame([DiviFeature::Catalog], $lock->features);
|
||||
self::assertSame('5.3.0', $lock->status->version);
|
||||
}
|
||||
|
||||
public function testAssertFeatureRefusesOnlyALockedFeature(): void
|
||||
@@ -149,6 +157,33 @@ final class ReleaseGateTest extends TestCase
|
||||
self::assertSame(2, $calls);
|
||||
}
|
||||
|
||||
public function testInvalidateForgetsTheStatusAndClearsTheMirrorCacheOnlyWhenAsked(): void
|
||||
{
|
||||
$calls = 0;
|
||||
$deleted = [];
|
||||
ReleaseGate::useResolver(static function () use (&$calls): ReleaseStatus {
|
||||
++$calls;
|
||||
|
||||
return ReleaseMatrices::released('5.2.1');
|
||||
});
|
||||
Functions\when('delete_transient')->alias(static function (string $key) use (&$deleted): bool {
|
||||
$deleted[] = $key;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
ReleaseGate::status();
|
||||
ReleaseGate::invalidate();
|
||||
ReleaseGate::status();
|
||||
self::assertSame(2, $calls);
|
||||
self::assertSame([], $deleted, 'a release or withdrawal leaves the mirror results alone');
|
||||
|
||||
ReleaseGate::invalidate(mirrors: true);
|
||||
ReleaseGate::status();
|
||||
self::assertSame(3, $calls);
|
||||
self::assertSame([ReleaseResolver::CACHE], $deleted);
|
||||
}
|
||||
|
||||
public function testAFailingResolverLocksWrites(): void
|
||||
{
|
||||
ReleaseGate::useResolver(static function (): never {
|
||||
|
||||
Reference in New Issue
Block a user