├── tests ├── _data │ └── .gitkeep ├── functional │ └── .gitkeep ├── _output │ └── .gitignore ├── _support │ ├── _generated │ │ └── .gitignore │ ├── Helper │ │ ├── Unit.php │ │ ├── Wpunit.php │ │ ├── Acceptance.php │ │ └── Functional.php │ ├── UnitTester.php │ ├── WpunitTester.php │ ├── AcceptanceTester.php │ └── FunctionalTester.php ├── acceptance │ ├── MyTestCest.php │ ├── PluginActivatedCest.php │ └── AdminPageCest.php ├── unit.suite.yml ├── wpunit │ ├── PluginTest.php │ ├── BlockPatternsManagerTest.php │ ├── AdminPageTest.php │ └── BlockPatternsListTableTest.php ├── wpunit.suite.yml ├── unit │ ├── PluginTest.php │ ├── AdminPageTest.php │ ├── bootstrap.php │ ├── BlockPatternsManagerTest.php │ └── RemotePatternsTest.php ├── functional.suite.yml └── acceptance.suite.yml ├── .gitignore ├── Readme.md ├── .env.testing ├── codeception.dist.yml ├── package.json ├── inc ├── Plugin.php ├── RemotePatterns.php ├── BlockPatternsManager.php ├── AdminPage.php └── BlockPatternsListTable.php ├── plugin.php └── composer.json /tests/_data/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/functional/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/_output/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /tests/_support/_generated/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor/ 2 | node_modules/ 3 | tmp 4 | .phpunit.result.cache -------------------------------------------------------------------------------- /tests/_support/Helper/Unit.php: -------------------------------------------------------------------------------- 1 | loginAsAdmin(); 16 | $I->amOnPluginsPage(); 17 | $I->seePluginActivated( 'block-patterns-manager' ); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/wpunit/PluginTest.php: -------------------------------------------------------------------------------- 1 | plugin_settings_link([]); 23 | 24 | $this->assertIsArray($links); 25 | $this->assertEquals(count( $links ), 1); 26 | $this->assertIsString($links[0]); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.env.testing: -------------------------------------------------------------------------------- 1 | TEST_SITE_DB_DSN=mysql:host=localhost;dbname=wordpress_test 2 | TEST_SITE_DB_HOST=localhost 3 | TEST_SITE_DB_NAME=wordpress_test 4 | TEST_SITE_DB_USER=werbeagenten 5 | TEST_SITE_DB_PASSWORD=secret 6 | TEST_SITE_TABLE_PREFIX=wp_ 7 | TEST_SITE_ADMIN_USERNAME=admin 8 | TEST_SITE_ADMIN_PASSWORD=admin 9 | TEST_SITE_WP_ADMIN_PATH=/wp-admin 10 | WP_ROOT_FOLDER=/Users/werbeagenten/Sites/wp58rc 11 | TEST_DB_NAME=test 12 | TEST_DB_HOST=localhost 13 | TEST_DB_USER=werbeagenten 14 | TEST_DB_PASSWORD=secret 15 | TEST_TABLE_PREFIX=wp_ 16 | TEST_SITE_WP_URL=https://wp58rc.test 17 | TEST_SITE_WP_DOMAIN=wp58rc.test 18 | TEST_SITE_ADMIN_EMAIL=admin@wp58rc.test 19 | -------------------------------------------------------------------------------- /tests/_support/UnitTester.php: -------------------------------------------------------------------------------- 1 | plugin_settings_link([]); 34 | 35 | $this->assertIsArray($links); 36 | $this->assertEquals(count( $links ), 1); 37 | $this->assertIsString($links[0]); 38 | } 39 | } -------------------------------------------------------------------------------- /tests/wpunit/BlockPatternsManagerTest.php: -------------------------------------------------------------------------------- 1 | register(); 27 | 28 | // global $wp_filter; 29 | // var_dump($wp_filter); 30 | 31 | 32 | // add_action('admin_init', 'test'); 33 | // // $this->assertTrue( has_action('admin_init', 'test' ) ); 34 | 35 | // die(print_r($GLOBALS['wp_filter']['admin_init'][0], true)); 36 | // } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /tests/unit/AdminPageTest.php: -------------------------------------------------------------------------------- 1 | make(BlockPatternsManager::class); 23 | } 24 | 25 | public function testShouldCreateErrorWhenInstantiatedWithoutBlockPatternsManager(): void 26 | { 27 | $this->expectException(Exception::class); 28 | new AdminPage( 'test' ); 29 | } 30 | 31 | public function testShouldReturnMenuSlug(): void 32 | { 33 | $expected_menu_slug = 'block-patterns-manager'; 34 | $received_menu_slug = AdminPage::get_menu_slug(); 35 | 36 | $this->assertEquals( 37 | $expected_menu_slug, 38 | $received_menu_slug 39 | ); 40 | } 41 | } -------------------------------------------------------------------------------- /inc/Plugin.php: -------------------------------------------------------------------------------- 1 | register_admin_hooks(); 14 | } 15 | 16 | public function register_admin_hooks() { 17 | $block_patterns_manager = new BlockPatternsManager(); 18 | $block_patterns_manager->register(); 19 | 20 | $this->admin_page = new AdminPage($block_patterns_manager); 21 | $this->admin_page->register(); 22 | 23 | $remote_patterns = new RemotePatterns( $block_patterns_manager ); 24 | $remote_patterns->register(); 25 | 26 | /** 27 | * Add settings link to plugin page 28 | */ 29 | $plugin = plugin_basename(_get_plugin_directory() . '/plugin.php'); 30 | add_filter("plugin_action_links_$plugin", [$this, 'plugin_settings_link'] ); 31 | } 32 | 33 | /** 34 | * Add a settings link to the plugin page 35 | */ 36 | public function plugin_settings_link( $links ) { 37 | $menu_slug = AdminPage::get_menu_slug(); 38 | 39 | $settings_link = '' . __( 'Settings', 'block-patterns-manager' ) . ''; 40 | $links[] = $settings_link; 41 | 42 | return $links; 43 | } 44 | } -------------------------------------------------------------------------------- /plugin.php: -------------------------------------------------------------------------------- 1 | run(); -------------------------------------------------------------------------------- /tests/functional.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | # 3 | # Suite for functional tests 4 | # Emulate web requests and make WordPress process them 5 | 6 | actor: FunctionalTester 7 | modules: 8 | enabled: 9 | - WPDb 10 | - WPBrowser 11 | # - WPFilesystem 12 | - Asserts 13 | - \Helper\Functional 14 | config: 15 | WPDb: 16 | dsn: '%TEST_SITE_DB_DSN%' 17 | user: '%TEST_SITE_DB_USER%' 18 | password: '%TEST_SITE_DB_PASSWORD%' 19 | dump: 'tests/_data/dump.sql' 20 | populate: true 21 | cleanup: true 22 | waitlock: 10 23 | url: '%TEST_SITE_WP_URL%' 24 | urlReplacement: true 25 | tablePrefix: '%TEST_SITE_TABLE_PREFIX%' 26 | WPBrowser: 27 | url: '%TEST_SITE_WP_URL%' 28 | adminUsername: '%TEST_SITE_ADMIN_USERNAME%' 29 | adminPassword: '%TEST_SITE_ADMIN_PASSWORD%' 30 | adminPath: '%TEST_SITE_WP_ADMIN_PATH%' 31 | headers: 32 | X_TEST_REQUEST: 1 33 | X_WPBROWSER_REQUEST: 1 34 | 35 | WPFilesystem: 36 | wpRootFolder: '%WP_ROOT_FOLDER%' 37 | plugins: '/wp-content/plugins' 38 | mu-plugins: '/wp-content/mu-plugins' 39 | themes: '/wp-content/themes' 40 | uploads: '/wp-content/uploads' -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "derweili/block-patterns-manager", 3 | "authors": [ 4 | { 5 | "name": "derweili", 6 | "email": "jw@derweili.de" 7 | } 8 | ], 9 | "require": { 10 | }, 11 | "autoload": { 12 | "psr-4": { 13 | "Derweili\\BlockPatternsManager\\": "inc/" 14 | } 15 | }, 16 | "require-dev": { 17 | "phpunit/phpunit": "^9", 18 | "lucatume/wp-browser": "^3.0", 19 | "codeception/module-asserts": "^1.0", 20 | "codeception/module-phpbrowser": "^1.0", 21 | "codeception/module-webdriver": "^1.0", 22 | "codeception/module-db": "^1.0", 23 | "codeception/module-filesystem": "^1.0", 24 | "codeception/module-cli": "^1.0", 25 | "codeception/util-universalframework": "^1.0", 26 | "brain/monkey": "^2.6", 27 | "mockery/mockery": "^1.4" 28 | }, 29 | "scripts": { 30 | "test:unit" : "vendor/bin/codecept run unit", 31 | "test:wpunit" : "vendor/bin/codecept run wpunit", 32 | "test:functional" : "vendor/bin/codecept run functional", 33 | "test:acceptance" : "vendor/bin/codecept run acceptance" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /tests/acceptance.suite.yml: -------------------------------------------------------------------------------- 1 | # Codeception Test Suite Configuration 2 | # 3 | # Suite for acceptance tests. 4 | # Perform tests in browser using the WPWebDriver or WPBrowser. 5 | # Use WPDb to set up your initial database fixture. 6 | # If you need both WPWebDriver and WPBrowser tests - create a separate suite. 7 | 8 | actor: AcceptanceTester 9 | modules: 10 | enabled: 11 | - WPDb 12 | - WPBrowser 13 | - \Helper\Acceptance 14 | config: 15 | WPDb: 16 | dsn: '%TEST_SITE_DB_DSN%' 17 | user: '%TEST_SITE_DB_USER%' 18 | password: '%TEST_SITE_DB_PASSWORD%' 19 | dump: 'tests/_data/dump.sql' 20 | #import the dump before the tests; this means the test site database will be repopulated before the tests. 21 | populate: true 22 | # re-import the dump between tests; this means the test site database will be repopulated between the tests. 23 | cleanup: true 24 | waitlock: 10 25 | url: '%TEST_SITE_WP_URL%' 26 | urlReplacement: true #replace the hardcoded dump URL with the one above 27 | tablePrefix: '%TEST_SITE_TABLE_PREFIX%' 28 | WPBrowser: 29 | url: '%TEST_SITE_WP_URL%' 30 | adminUsername: '%TEST_SITE_ADMIN_USERNAME%' 31 | adminPassword: '%TEST_SITE_ADMIN_PASSWORD%' 32 | adminPath: '%TEST_SITE_WP_ADMIN_PATH%' 33 | headers: 34 | X_TEST_REQUEST: 1 35 | X_WPBROWSER_REQUEST: 1 -------------------------------------------------------------------------------- /tests/unit/bootstrap.php: -------------------------------------------------------------------------------- 1 | getMockBuilder(BlockPatternsManager::class) 21 | ->getMock(); 22 | 23 | return $mock; 24 | } 25 | 26 | public function testShouldSaveSettings() { 27 | 28 | $nonce_key = 'save-block-patterns-manager-nonce'; 29 | 30 | // create nonce 31 | $nonce = wp_create_nonce( $nonce_key ); 32 | 33 | $_POST['_wpnonce'] = $nonce; 34 | $_POST['capabilities'] = [ 35 | 'twentytwentyone/large-text' => 'manage_options', 36 | ]; 37 | 38 | $mock = $this->getMockBuilder(BlockPatternsManager::class) 39 | ->getMock(); 40 | 41 | $admin_page_instance = new AdminPage( $mock ); 42 | $has_saved_settings = $admin_page_instance->save_settings(); 43 | 44 | $this->assertTrue( $has_saved_settings ); 45 | } 46 | 47 | public function testShouldNotSaveSettingsIfNonceInvalid() { 48 | // create nonce 49 | $nonce = 'invalidnonce'; 50 | 51 | $_POST['_wpnonce'] = $nonce; 52 | $_POST['capabilities'] = [ 53 | 'twentytwentyone/large-text' => 'manage_options', 54 | ]; 55 | 56 | $mock = $this->getMockBuilder(BlockPatternsManager::class) 57 | ->getMock(); 58 | 59 | $admin_page_instance = new AdminPage( $mock ); 60 | $has_saved_settings = $admin_page_instance->save_settings(); 61 | 62 | $this->assertFalse( $has_saved_settings ); 63 | } 64 | 65 | public function testShouldNotSaveSettingsIfNonceNotPresent() { 66 | $_POST['capabilities'] = [ 67 | 'twentytwentyone/large-text' => 'manage_options', 68 | ]; 69 | 70 | $mock = $this->getMockBuilder(BlockPatternsManager::class) 71 | ->getMock(); 72 | 73 | $admin_page_instance = new AdminPage( $mock ); 74 | $has_saved_settings = $admin_page_instance->save_settings(); 75 | 76 | $this->assertFalse( $has_saved_settings ); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /tests/acceptance/AdminPageCest.php: -------------------------------------------------------------------------------- 1 | loginAsAdmin(); 8 | } 9 | 10 | public function testShouldSaveSettings( AcceptanceTester $I ) { 11 | $I->amOnPluginsPage(); 12 | $I->amOnAdminPage('/tools.php?page=block-patterns-manager'); 13 | 14 | /** 15 | * Save settings first time 16 | */ 17 | $first_test_capability = 'manage_options'; 18 | 19 | $I->submitForm( '#block-patterns-manager-admin-page-form', [ 20 | 'capabilities[block_pattern_directory]' => $first_test_capability, 21 | ]); 22 | 23 | $I->seeMessage('.block-patterns-manager-settings-saved'); 24 | 25 | $returned_setting = $I->grabValueFrom('input[name="capabilities[block_pattern_directory]"]'); 26 | $returned_setting_2 = $I->grabValueFrom('select[name="capabilities[block_pattern_directory]-select"]'); 27 | $I->canSeeInField('input[name="capabilities[block_pattern_directory]"]', $first_test_capability); 28 | $I->canSeeInField('select[name="capabilities[block_pattern_directory]-select"]', $first_test_capability); 29 | 30 | /** 31 | * Save settings second time 32 | */ 33 | $second_test_capability = 'edit_posts'; 34 | 35 | $I->submitForm( '#block-patterns-manager-admin-page-form', [ 36 | 'capabilities[block_pattern_directory]' => $second_test_capability, 37 | ]); 38 | 39 | $I->seeMessage('.block-patterns-manager-settings-saved'); 40 | 41 | $returned_setting = $I->grabValueFrom('input[name="capabilities[block_pattern_directory]"]'); 42 | $I->canSeeInField('input[name="capabilities[block_pattern_directory]"]', $second_test_capability); 43 | $I->canSeeInField('select[name="capabilities[block_pattern_directory]-select"]', $second_test_capability); 44 | 45 | } 46 | 47 | public function testShouldSetSelectToCustom( AcceptanceTester $I ) { 48 | $I->amOnPluginsPage(); 49 | $I->amOnAdminPage('/tools.php?page=block-patterns-manager'); 50 | 51 | /** 52 | * Save settings first time 53 | */ 54 | $first_test_capability = 'my_custom_capability'; 55 | 56 | $I->submitForm( '#block-patterns-manager-admin-page-form', [ 57 | 'capabilities[block_pattern_directory]' => $first_test_capability, 58 | ]); 59 | 60 | $I->seeMessage('.block-patterns-manager-settings-saved'); 61 | 62 | $I->canSeeInField('input[name="capabilities[block_pattern_directory]"]', $first_test_capability); // input should be set to our custom capability 63 | $I->canSeeInField('select[name="capabilities[block_pattern_directory]-select"]', 'custom'); // select should be set to custom 64 | } 65 | } 66 | 67 | 68 | -------------------------------------------------------------------------------- /inc/RemotePatterns.php: -------------------------------------------------------------------------------- 1 | block_patterns_manager = $block_patterns_manager; 37 | } 38 | 39 | /** 40 | * Add the required hooks 41 | * 42 | * Todo: add tests to make sure the hooks are added 43 | */ 44 | public function register() { 45 | // add the filter to the block pattern directory 46 | add_filter('should_load_remote_block_patterns', [ $this, 'should_load_remote_block_patterns' ]); 47 | 48 | /** 49 | * add the block pattern directory as a pattern to BlockPatternsManager patterns list 50 | */ 51 | add_filter('block_pattern_manager_all_patterns', [ $this, 'add_pattern_directory_to_pattern_list' ]); 52 | } 53 | 54 | /** 55 | * Add the block pattern directory as a "fake" pattern to the all patterns list 56 | * This function is added to the block_pattern_manager_all_patterns filter 57 | */ 58 | public function add_pattern_directory_to_pattern_list( $block_patterns ) { 59 | /** 60 | * Add block_pattern_directory to the $block_patterns array 61 | */ 62 | $block_patterns[] = [ 63 | 'name' => 'block_pattern_directory', 64 | 'title' => 'Block Pattern Directory', 65 | 'description' => 'Load external block patterns from the Block Pattern Directory' 66 | ]; 67 | 68 | return $block_patterns; 69 | } 70 | 71 | /** 72 | * Load the current settings for the disable remote patterns capability 73 | */ 74 | public function load_disable_remote_patterns_capability_setting () { 75 | $block_patterns_capabilities = $this->block_patterns_manager->get_settings(); 76 | 77 | if( isset( $block_patterns_capabilities[$this->remote_patterns_key] ) && ! empty( $block_patterns_capabilities[ $this->remote_patterns_key ] ) ) { 78 | return $block_patterns_capabilities[$this->remote_patterns_key]; 79 | } else { 80 | false; 81 | } 82 | } 83 | 84 | /** 85 | * Get the current disable remote patterns capability 86 | * If no capability is stored yet, load it from the BlockPatternsManager settings 87 | */ 88 | public function get_setting() { 89 | if( null === $this->disable_remote_patterns_capability ) { 90 | $this->disable_remote_patterns_capability = $this->load_disable_remote_patterns_capability_setting(); 91 | } 92 | return $this->disable_remote_patterns_capability; 93 | } 94 | 95 | /** 96 | * Disable remote block pattern based on settings 97 | * 98 | * @param bool $should_load_remote_block_patterns 99 | * @return bool 100 | */ 101 | public function should_load_remote_block_patterns( $should_load_remote_block_patterns ) { 102 | 103 | $required_capability = $this->get_setting(); 104 | 105 | 106 | if( $required_capability && ! $this->current_user_can( $this->get_setting() ) ) { 107 | return false; 108 | } 109 | 110 | return $should_load_remote_block_patterns; 111 | } 112 | 113 | /** 114 | * Wrapper function for current_user_can to make it testable/mockable 115 | */ 116 | public function current_user_can( $capability ) { 117 | return current_user_can( $capability ); 118 | } 119 | } -------------------------------------------------------------------------------- /inc/BlockPatternsManager.php: -------------------------------------------------------------------------------- 1 | capabilities_settings = $this->load_settings(); 34 | } 35 | 36 | /** 37 | * Register all required hooks 38 | * 39 | * Loads all currently registered patterns and adds them to the registry. 40 | * Register our settings to the WP settings API. 41 | * Load the unregistered patterns method which disables block patterns if the user is not allowed to use them. 42 | * 43 | * Todo: add tests to check if all those functions are registered correctly 44 | */ 45 | public function register() { 46 | add_action( 'admin_init', array($this, 'load_all_patterns'), 50); 47 | add_action( 'admin_init', [ $this, 'register_settings' ] ); 48 | add_action( 'admin_init', [ $this, 'unregister_block_patterns' ], 500 ); 49 | } 50 | 51 | /** 52 | * Load all currently registered patterns and add them to the registry. 53 | * 54 | * Todo: Create Tests 55 | */ 56 | public function load_all_patterns() { 57 | self::$patterns = WP_Block_Patterns_Registry::get_instance()->get_all_registered(); 58 | } 59 | 60 | /** 61 | * Get all registered which we loaded before. 62 | * 63 | * Implents a filter to add additional (fake) patterns. 64 | * This filter is used by the RemovePattern class to add the block pattern directory to the list of patterns. 65 | */ 66 | public function get_all_patterns() { 67 | return apply_filters( 'block_pattern_manager_all_patterns', self::$patterns ); 68 | } 69 | 70 | /** 71 | * Register the settings to the WP settings API. 72 | */ 73 | public function register_settings() { 74 | register_setting( 'block_patterns_manager_settings', $this->capabilities_settings_key, 'array', __('List of block patterns and their required capabilities', 'block-patterns-manager') ); 75 | } 76 | 77 | /** 78 | * Method to save the settings to the database. 79 | */ 80 | public function save_settings( array $settings ) { 81 | update_option( $this->capabilities_settings_key, $settings ); 82 | $this->capabilities_settings = $settings; 83 | } 84 | 85 | /** 86 | * Get the settings from the database. 87 | */ 88 | private function load_settings() { 89 | return get_option( $this->capabilities_settings_key, [] ); 90 | } 91 | 92 | /** 93 | * Get the settings we loaded before. 94 | * If we did not load them before, load them from the Database. 95 | */ 96 | public function get_settings() { 97 | if( null === $this->capabilities_settings ) { 98 | $this->capabilities_settings = $this->load_settings(); 99 | } 100 | return $this->capabilities_settings; 101 | } 102 | 103 | /** 104 | * Unregister Block Patterns based on capabilities 105 | */ 106 | public function unregister_block_patterns() { 107 | $settings = $this->get_settings(); 108 | 109 | foreach ($settings as $pattern_name => $capability) { 110 | // only unregister if the pattern is registered 111 | if( $this->is_pattern_registered( $pattern_name ) ) { 112 | 113 | // unregister if a capability is selected (not empty) and user has not the capability 114 | if( $capability && ! empty( $capability ) && ! $this->current_user_can( $capability ) ) { 115 | $unregister_result = $this->unregister_block_pattern( $pattern_name ); 116 | } 117 | } 118 | } 119 | } 120 | 121 | /** 122 | * Wrapper function for current_user_can() WordPress Capabilities Check 123 | */ 124 | public function current_user_can( $capability ) { 125 | return current_user_can( $capability ); 126 | } 127 | 128 | /** 129 | * Wrapper function for unregister_block_pattern WordPress function 130 | */ 131 | public function unregister_block_pattern( $pattern_name ) { 132 | return unregister_block_pattern( $pattern_name ); 133 | } 134 | 135 | /** 136 | * Check if a pattern is registered 137 | */ 138 | public function is_pattern_registered( $pattern_name ) { 139 | return WP_Block_Patterns_Registry::get_instance()->is_registered( $pattern_name ); 140 | } 141 | } -------------------------------------------------------------------------------- /tests/unit/BlockPatternsManagerTest.php: -------------------------------------------------------------------------------- 1 | 'my-test-capability', 47 | 'pattern2' => 'my-test-capability2', 48 | 'pattern3' => '', 49 | ]; 50 | 51 | 52 | $manager->save_settings( $demo_settings ); 53 | $returned_settings = $manager->get_settings(); 54 | 55 | $this->assertSame( $demo_settings, $returned_settings ); 56 | } 57 | 58 | public function testShouldUnregisterPatternWhenUserDoesNotHaveCapability() { 59 | $demo_settings = [ 60 | 'pattern1' => 'manage_options', 61 | ]; 62 | 63 | $mock = $this->getMockBuilder(BlockPatternsManager::class) 64 | ->setMethods(['get_settings', 'is_pattern_registered', 'current_user_can', 'unregister_block_pattern']) 65 | ->getMock(); 66 | 67 | $mock->method('get_settings') 68 | ->willReturn( $demo_settings ); 69 | 70 | $mock->expects($this->once()) 71 | ->method('is_pattern_registered') 72 | ->with('pattern1') 73 | ->willReturn(true); 74 | 75 | $mock->expects($this->once()) 76 | ->method('current_user_can') 77 | ->with('manage_options') 78 | ->willReturn(false); 79 | 80 | $mock->expects($this->once()) 81 | ->method('unregister_block_pattern') 82 | ->with('pattern1'); 83 | 84 | $mock->unregister_block_patterns(); 85 | } 86 | 87 | public function testShouldNotUnregisterPatternWhenUserDoesHaveCapability() { 88 | 89 | $demo_settings = [ 90 | 'pattern1' => 'manage_options' 91 | ]; 92 | 93 | $mock = $this->getMockBuilder(BlockPatternsManager::class) 94 | ->setMethods(['get_settings', 'is_pattern_registered', 'current_user_can', 'unregister_block_pattern']) 95 | ->getMock(); 96 | 97 | $mock->method('get_settings') 98 | ->willReturn( $demo_settings ); 99 | 100 | $mock->expects($this->once()) 101 | ->method('is_pattern_registered') 102 | ->with('pattern1') 103 | ->willReturn(true); 104 | 105 | $mock->expects($this->once()) 106 | ->method('current_user_can') 107 | ->with('manage_options') 108 | ->willReturn(true); 109 | 110 | $mock->expects($this->never()) 111 | ->method('unregister_block_pattern'); 112 | 113 | $mock->unregister_block_patterns(); 114 | } 115 | 116 | public function testShouldNotUnregisterPatternWhenCapabilityIsEmpty() { 117 | 118 | $demo_settings = [ 119 | 'pattern1' => '' 120 | ]; 121 | 122 | $mock = $this->getMockBuilder(BlockPatternsManager::class) 123 | ->setMethods(['get_settings', 'is_pattern_registered', 'current_user_can', 'unregister_block_pattern']) 124 | ->getMock(); 125 | 126 | $mock->method('get_settings') 127 | ->willReturn( $demo_settings ); 128 | 129 | $mock->expects($this->once()) 130 | ->method('is_pattern_registered') 131 | ->with('pattern1') 132 | ->willReturn(true); 133 | 134 | $mock->expects($this->never()) 135 | ->method('unregister_block_pattern'); 136 | 137 | $mock->unregister_block_patterns(); 138 | } 139 | 140 | public function testShouldNotUnregisterPatternWhenPatternIsNotRegistered() { 141 | 142 | $demo_settings = [ 143 | 'pattern1' => 'manage_options' 144 | ]; 145 | 146 | $mock = $this->getMockBuilder(BlockPatternsManager::class) 147 | ->setMethods(['get_settings', 'is_pattern_registered', 'current_user_can', 'unregister_block_pattern']) 148 | ->getMock(); 149 | 150 | $mock->method('get_settings') 151 | ->willReturn( $demo_settings ); 152 | 153 | $mock->expects($this->once()) 154 | ->method('is_pattern_registered') 155 | ->with('pattern1') 156 | ->willReturn(false); 157 | 158 | $mock->expects($this->never()) 159 | ->method('unregister_block_pattern'); 160 | 161 | $mock->unregister_block_patterns(); 162 | } 163 | 164 | 165 | /** 166 | * Test if register function actually registers admin_menu and set_screen functions 167 | * 168 | */ 169 | public function testShouldAddCallPatternsFilter() { 170 | 171 | $manager = new BlockPatternsManager(); 172 | $manager->get_all_patterns(); 173 | $this->assertTrue( Filters\applied('block_pattern_manager_all_patterns') > 0 ); 174 | } 175 | } -------------------------------------------------------------------------------- /inc/AdminPage.php: -------------------------------------------------------------------------------- 1 | block_patterns_manager = $block_patterns_manager; 43 | } 44 | 45 | public static function get_menu_slug() { 46 | return self::$menu_slug; 47 | } 48 | 49 | /** 50 | * Todo add test to check if actions and filters are registerd 51 | */ 52 | public function register() { 53 | add_action( 'admin_menu', array($this, 'add_menu_page') ); 54 | add_filter( 'set-screen-option', [ __CLASS__, 'set_screen' ], 10, 3 ); 55 | } 56 | 57 | public static function set_screen( $status, $option, $value ) { 58 | return $value; 59 | } 60 | 61 | /** 62 | * Register the menu page. 63 | * 64 | * Todo: add test to check if menu page is registerd 65 | */ 66 | public function add_menu_page() { 67 | $hook = add_management_page( 68 | __('Block Patterns Manager', 'block-patterns-manager'), 69 | __('Block Patterns Manager', 'block-patterns-manager'), 70 | 'manage_options', 71 | self::get_menu_slug(), 72 | array( $this, 'options_page' ), 73 | 'dashicons-align-wide', 74 | null 75 | ); 76 | 77 | add_action( "load-$hook", [ $this, 'screen_option' ] ); 78 | } 79 | 80 | /** 81 | * Screen options 82 | */ 83 | public function screen_option() { 84 | 85 | $option = 'per_page'; 86 | 87 | $this->block_patterns_list_table = new BlockPatternsListTable( $this->block_patterns_manager ); 88 | $this->save_settings(); 89 | } 90 | 91 | /** 92 | * Render the options page 93 | * 94 | * Todo: Write tests 95 | */ 96 | public function options_page() { 97 | $settings = $this->block_patterns_manager->get_settings(); 98 | 99 | ?> 100 |