diff --git a/composer.json b/composer.json index bab4942..4483fb6 100644 --- a/composer.json +++ b/composer.json @@ -25,8 +25,8 @@ } }, "require-dev": { - "phpunit/phpunit": "^10.3", - "10up/wp_mock": "^0.4.2", + "phpunit/phpunit": "^9.6.13", + "10up/wp_mock": "^1.0.0", "phpcompatibility/phpcompatibility-wp": "*" }, "autoload": { diff --git a/di-config.php b/di-config.php index df43940..d19e685 100644 --- a/di-config.php +++ b/di-config.php @@ -19,6 +19,7 @@ use function DI\create; return [ - 'taxonomy' => create( 'WordPress_Related\Taxonomy\Taxonomy' ), - 'post_type' => create( 'WordPress_Related\Post_Type\Post_Type' ), + 'Admin_Menu' => create( 'WordPress_Related\Admin\Admin_Menu' ), + 'Taxonomy' => create( 'WordPress_Related\Taxonomy\Taxonomy' ), + 'Post_Type' => create( 'WordPress_Related\Post_Type\Post_Type' ), ]; diff --git a/includes/Admin/Admin_Menu.php b/includes/Admin/Admin_Menu.php new file mode 100644 index 0000000..a2c34f5 --- /dev/null +++ b/includes/Admin/Admin_Menu.php @@ -0,0 +1,103 @@ +' . esc_html__( 'WordPress Related', 'wordpress-related' ) . ''; + } + + /** + * Render the Custom Taxonomies page. + * + * @return void + * @throws Exception + */ + public function render_taxonomies_page(): void { + echo '

' . esc_html__( 'Custom Taxonomies', 'wordpress-related' ) . '

'; + } + + /** + * Render the Custom Post Types page. + * + * @return void + * @throws Exception + */ + public function render_post_types_page(): void { + echo '

' . esc_html__( 'Custom Post Types', 'wordpress-related' ) . '

'; + } +} diff --git a/includes/Plugin.php b/includes/Plugin.php index d9c8b8c..0103cd9 100644 --- a/includes/Plugin.php +++ b/includes/Plugin.php @@ -69,7 +69,6 @@ public function init(): void { */ public function register_services(): void { $services = $this->container->getKnownEntryNames(); - foreach ( $services as $service ) { try { $service_instance = $this->container->get( $service ); diff --git a/phpunit.xml.dist b/phpunit.xml.dist index ee3962d..cb698d1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,32 +1,38 @@ - - - - - - - - - - ./tests/unit - - - - - - includes - - - vendor - - + + + + + + + ./includes + + + + ./vendor + + + + + + + + + + + ./tests/unit + + + + + + + + diff --git a/tests/unit/Admin/Admin_Menu_Test.php b/tests/unit/Admin/Admin_Menu_Test.php new file mode 100644 index 0000000..2e03001 --- /dev/null +++ b/tests/unit/Admin/Admin_Menu_Test.php @@ -0,0 +1,139 @@ +register(); + + $this->assertHooksAdded(); // This asserts that the expected hooks were added + } + + /** + * Test register_menu method. + * + * @return void + * @throws Exception + */ + public function test_register_menu(): void { + $admin_menu = new Admin_Menu(); // Instantiating the object before using it + + WP_Mock::userFunction( + 'add_menu_page', + array( + 'times' => 1, + 'args' => array( + __( 'WordPress Related', 'wordpress-related' ), + __( 'WordPress Related', 'wordpress-related' ), + 'manage_options', + 'wordpress-related', + array( $admin_menu, 'render_plugin_page' ), + 'dashicons-coffee', + ), + ) + ); + + WP_Mock::userFunction( + 'add_submenu_page', + array( + 'times' => 2, // Since add_submenu_page is called twice in register_menu + ) + ); + + $admin_menu->register_menu(); + + $this->expectNotToPerformAssertions(); + } + + /** + * Test render_plugin_page method. + * + * @return void + * @throws Exception + */ + public function test_render_plugin_page(): void { + $admin_menu = new Admin_Menu(); + ob_start(); + $admin_menu->render_plugin_page(); + $output = ob_get_clean(); + + $this->assertSame( '

WordPress Related

', $output ); + } + + /** + * Test render_taxonomies_page method. + * + * @return void + * @throws Exception + */ + public function test_render_taxonomies_page(): void { + $admin_menu = new Admin_Menu(); + ob_start(); + $admin_menu->render_taxonomies_page(); + $output = ob_get_clean(); + + $this->assertSame( '

Custom Taxonomies

', $output ); + } + + /** + * Test render_post_types_page method. + * + * @return void + * @throws Exception + */ + public function test_render_post_types_page(): void { + $admin_menu = new Admin_Menu(); + ob_start(); + $admin_menu->render_post_types_page(); + $output = ob_get_clean(); + + $this->assertSame( '

Custom Post Types

', $output ); + } + + /** + * Tear down. + * + * @return void + */ + public function tearDown(): void { + parent::tearDown(); + WP_Mock::tearDown(); + } +} diff --git a/tests/unit/Plugin_Factory_Test.php b/tests/unit/Plugin_Factory_Test.php index b434811..90ae381 100644 --- a/tests/unit/Plugin_Factory_Test.php +++ b/tests/unit/Plugin_Factory_Test.php @@ -4,8 +4,8 @@ namespace WordPress_Related\Tests\Unit; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; -use WordPress_Related\Plugin; use WordPress_Related\Plugin_Factory; use DI\Container; @@ -28,6 +28,7 @@ class Plugin_Factory_Test extends TestCase { * Set up. * * @return void + * @throws Exception * @since 1.0.0 */ public function setUp(): void { diff --git a/tests/unit/Plugin_Test.php b/tests/unit/Plugin_Test.php index 4d4c21c..cd5d2d1 100644 --- a/tests/unit/Plugin_Test.php +++ b/tests/unit/Plugin_Test.php @@ -4,9 +4,12 @@ namespace WordPress_Related\Tests\Unit; -use DI\Container; +use Exception; use PHPUnit\Framework\TestCase; use WordPress_Related\Plugin; +use WP_Mock; +use DI\Container; +use WordPress_Related\Infrastructure\Registerable; /** * Plugin Test. @@ -15,55 +18,168 @@ */ class Plugin_Test extends TestCase { - /** - * Container. - * - * @since 1.0.0 - * @var Container - */ - protected Container $container; - /** * Set up. * * @return void - * @since 1.0.0 */ public function setUp(): void { parent::setUp(); - $this->container = $this->createMock( 'DI\Container' ); + if ( ! defined( 'WORDPRESS_RELATED_FILE' ) ) { + define( 'WORDPRESS_RELATED_FILE', __DIR__ . '/../../wordpress-related.php' ); + } + WP_Mock::setUp(); } /** * Test plugin constructor. * * @return void - * @since 1.0.0 */ public function test_plugin_constructor(): void { - $plugin = new Plugin( $this->container ); - $this->assertInstanceOf( 'WordPress_Related\Plugin', $plugin ); + $container = $this->createMock( Container::class ); + $plugin = new Plugin( $container ); + $this->assertInstanceOf( Plugin::class, $plugin ); } /** * Test plugin init. * * @return void - * @since 1.0.0 */ public function test_plugin_init(): void { - $plugin = new Plugin( $this->container ); + $container = $this->createMock( Container::class ); + $plugin = new Plugin( $container ); $this->assertNull( $plugin->init() ); } + /** + * Test register_hooks method. + * + * @return void + */ + public function test_register_hooks(): void { + $container = $this->createMock( Container::class ); + $plugin = new Plugin( $container ); + + // Mock WordPress functions + WP_Mock::userFunction( + 'register_activation_hook', + array( + 'times' => 1, + 'args' => array( WORDPRESS_RELATED_FILE, array( $plugin, 'on_activation' ) ), + ) + ); + + WP_Mock::userFunction( + 'register_deactivation_hook', + array( + 'times' => 1, + 'args' => array( WORDPRESS_RELATED_FILE, array( $plugin, 'on_deactivation' ) ), + ) + ); + + $plugin->register_hooks(); + + $this->expectNotToPerformAssertions(); + } + + /** + * Test boot method. + * + * @return void + * @throws Exception + */ + public function test_boot(): void { + $container = $this->createMock( Container::class ); + $plugin = new Plugin( $container ); + + // Mock WordPress functions + WP_Mock::userFunction( + 'register_activation_hook', + array( + 'times' => 1, + 'args' => array( WORDPRESS_RELATED_FILE, array( $plugin, 'on_activation' ) ), + ) + ); + + WP_Mock::userFunction( + 'register_deactivation_hook', + array( + 'times' => 1, + 'args' => array( WORDPRESS_RELATED_FILE, array( $plugin, 'on_deactivation' ) ), + ) + ); + + $container->expects( $this->once() ) + ->method( 'getKnownEntryNames' ) + ->willReturn( array() ); + + $plugin->boot(); + } + + /** + * Test register_services method. + * + * @return void + * @throws Exception + */ + public function test_register_services(): void { + $container = $this->createMock( Container::class ); + $plugin = new Plugin( $container ); + + $registerable_mock = $this->createMock( Registerable::class ); + $registerable_mock->expects( $this->once() ) + ->method( 'register' ); + + $container->expects( $this->once() ) + ->method( 'getKnownEntryNames' ) + ->willReturn( array( 'registerableService' ) ); + + $container->expects( $this->once() ) + ->method( 'get' ) + ->with( 'registerableService' ) + ->willReturn( $registerable_mock ); + + $plugin->register_services(); + } + + /** + * Test on_deactivation method. + * + * @return void + */ + public function test_on_deactivation(): void { + $container = $this->createMock( Container::class ); + $plugin = new Plugin( $container ); + + // Mock WordPress functions + WP_Mock::userFunction( + 'wp_cache_flush', + array( + 'times' => 1, + ) + ); + + WP_Mock::userFunction( + 'wp_rewrite_flush', + array( + 'times' => 1, + ) + ); + + $plugin->on_deactivation(); + + $this->expectNotToPerformAssertions(); + } + /** * Tear down. * * @return void - * @since 1.0.0 */ public function tearDown(): void { + WP_Mock::tearDown(); parent::tearDown(); - unset( $this->container ); } }