*/ 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 testDeclaredByIgnoresIdsThatAreNoDiviFeature(): void { $tool = Mockery::mock(Ability::class, DeclaresRequirements::class); $tool->allows('requirements')->andReturn(['pods-field-read', 'page-write']); self::assertSame([DiviFeature::PageWrite], FeatureSets::declaredBy($tool, ['divi' => []])); } public function testDeclaredByIsEmptyForAnyOtherTool(): void { self::assertSame([], FeatureSets::declaredBy(Mockery::mock(Ability::class), ['x' => 1])); } }