Deklariert ein Tool über DeclaresRequirements eine ID, die keine Divi-Fähigkeit ist, wird der Aufruf mit divi_incompatible (423) gesperrt, statt ungesperrt zu laufen. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
143 lines
5.1 KiB
PHP
143 lines
5.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Release;
|
|
|
|
use Brain\Monkey\Functions;
|
|
use LIT\MCP\Abilities\Ability;
|
|
use LIT\MCP\Abilities\DeclaresRequirements;
|
|
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
|
use LIT\MCP\Integrations\Divi\Release\FeatureSets;
|
|
use LIT\MCP\Integrations\Divi\Release\RequiresDiviFeatures;
|
|
use LIT\MCP\Tests\Unit\TestCase;
|
|
use Mockery;
|
|
|
|
final class FeatureSetsTest extends TestCase
|
|
{
|
|
/** @var array<int, string> */
|
|
private array $types = [];
|
|
|
|
private bool $mayEdit = true;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
Functions\when('get_post_type')->alias(fn (int $id): string|false => $this->types[$id] ?? false);
|
|
Functions\when('current_user_can')->alias(fn (string $capability): bool => $this->mayEdit);
|
|
}
|
|
|
|
public function testMergeKeepsEveryFeatureOnceInTheOrderOfItsFirstAppearance(): void
|
|
{
|
|
$merged = FeatureSets::merge(
|
|
[DiviFeature::Catalog, DiviFeature::Roles],
|
|
[],
|
|
[DiviFeature::Roles, DiviFeature::PageRead, DiviFeature::Catalog]
|
|
);
|
|
|
|
self::assertSame([DiviFeature::Catalog, DiviFeature::Roles, DiviFeature::PageRead], $merged);
|
|
self::assertSame([], FeatureSets::merge());
|
|
}
|
|
|
|
public function testAPageOrPostAddsNothing(): void
|
|
{
|
|
$this->types = [5 => 'page', 6 => 'post', 7 => 'project'];
|
|
|
|
foreach ([5, 6, 7, '5'] as $id) {
|
|
self::assertSame([], FeatureSets::ofEntry($id, true), (string) $id);
|
|
self::assertSame([], FeatureSets::ofEntry($id, false), (string) $id);
|
|
}
|
|
}
|
|
|
|
public function testAnIdThatNamesNoEntryAddsNothing(): void
|
|
{
|
|
foreach ([null, 0, -3, 'abc', '1.5', [], 404] as $id) {
|
|
self::assertSame([], FeatureSets::ofEntry($id, true), var_export($id, true));
|
|
}
|
|
}
|
|
|
|
public function testALibraryEntryNeedsTheRolesAndWritingAlsoTheLibrary(): void
|
|
{
|
|
$this->types = [7 => 'et_pb_layout'];
|
|
|
|
self::assertSame([DiviFeature::Roles], FeatureSets::ofEntry(7, false));
|
|
self::assertSame(
|
|
[DiviFeature::Roles, DiviFeature::LibraryRead, DiviFeature::LibraryWrite],
|
|
FeatureSets::ofEntry('7', true)
|
|
);
|
|
}
|
|
|
|
public function testEveryThemeBuilderLayoutNeedsTheRolesAndWritingAlsoTheThemeBuilder(): void
|
|
{
|
|
$this->types = [1 => 'et_header_layout', 2 => 'et_body_layout', 3 => 'et_footer_layout'];
|
|
|
|
foreach ([1, 2, 3] as $id) {
|
|
self::assertSame([DiviFeature::Roles], FeatureSets::ofEntry($id, false), (string) $id);
|
|
self::assertSame(
|
|
[DiviFeature::Roles, DiviFeature::ThemeBuilderRead, DiviFeature::ThemeBuilderWrite],
|
|
FeatureSets::ofEntry($id, true),
|
|
(string) $id
|
|
);
|
|
}
|
|
}
|
|
|
|
public function testAnEntryTheCallerMayNotEditAddsNothingSoALockNeverNamesItsKind(): void
|
|
{
|
|
$this->types = [7 => 'et_pb_layout', 9 => 'et_body_layout'];
|
|
$this->mayEdit = false;
|
|
|
|
foreach ([7, 9] as $id) {
|
|
self::assertSame([], FeatureSets::ofEntry($id, true), (string) $id);
|
|
self::assertSame([], FeatureSets::ofEntry($id, false), (string) $id);
|
|
}
|
|
}
|
|
|
|
public function testTemplatesAndThemeBuilderPostsAreNoLayouts(): void
|
|
{
|
|
$this->types = [1 => 'et_template', 2 => 'et_theme_builder'];
|
|
|
|
self::assertSame([], FeatureSets::ofEntry(1, true));
|
|
self::assertSame([], FeatureSets::ofEntry(2, true));
|
|
}
|
|
|
|
public function testDeclaredByReadsTheDiviToolsOwnList(): void
|
|
{
|
|
$tool = Mockery::mock(Ability::class, RequiresDiviFeatures::class);
|
|
$tool->expects('diviFeatures')->with(['a' => 1])->andReturn([DiviFeature::Roles, DiviFeature::Roles]);
|
|
|
|
self::assertSame([DiviFeature::Roles], FeatureSets::declaredBy($tool, ['a' => 1]));
|
|
}
|
|
|
|
public function testDeclaredByTranslatesTheIdsOfACoreTool(): void
|
|
{
|
|
$tool = Mockery::mock(Ability::class, DeclaresRequirements::class);
|
|
$tool->expects('requirements')->with(['divi' => []])->andReturn(['page-write', 'catalog']);
|
|
|
|
self::assertSame(
|
|
[DiviFeature::PageWrite, DiviFeature::Catalog],
|
|
FeatureSets::declaredBy($tool, ['divi' => []])
|
|
);
|
|
}
|
|
|
|
public function testUnknownIdsNamesTheIdsOfACoreToolThatAreNoDiviFeature(): void
|
|
{
|
|
$tool = Mockery::mock(Ability::class, DeclaresRequirements::class);
|
|
$tool->allows('requirements')->with(['divi' => []])->andReturn(['page-write', 'other-integration', 'catalog']);
|
|
|
|
self::assertSame(['other-integration'], FeatureSets::unknownIds($tool, ['divi' => []]));
|
|
}
|
|
|
|
public function testUnknownIdsIsEmptyForDiviToolsAndAnyOtherTool(): void
|
|
{
|
|
$divi = Mockery::mock(Ability::class, RequiresDiviFeatures::class);
|
|
|
|
self::assertSame([], FeatureSets::unknownIds($divi, []));
|
|
self::assertSame([], FeatureSets::unknownIds(Mockery::mock(Ability::class), []));
|
|
}
|
|
|
|
public function testDeclaredByIsEmptyForAnyOtherTool(): void
|
|
{
|
|
self::assertSame([], FeatureSets::declaredBy(Mockery::mock(Ability::class), ['x' => 1]));
|
|
}
|
|
}
|