diff --git a/.env.testing b/.env.testing new file mode 100644 index 0000000000000000000000000000000000000000..0bf105f10e081da1df165fc1221a96d779f428e5 --- /dev/null +++ b/.env.testing @@ -0,0 +1,19 @@ +WP_ROOT_FOLDER="${APACHE_DOCUMENT_ROOT}" +TEST_SITE_WP_ADMIN_PATH="/wp-admin" +TEST_SITE_DB_NAME="wptest" +TEST_SITE_DB_HOST="mysqltests" +TEST_SITE_DB_USER="mysql" +TEST_SITE_DB_PASSWORD="mysql" +TEST_SITE_TABLE_PREFIX="wp_" +TEST_DB_NAME="wptest" +TEST_DB_HOST="mysqltests" +TEST_DB_USER="mysql" +TEST_DB_PASSWORD="mysql" +TEST_TABLE_PREFIX="wp_" +TEST_SITE_WP_URL="http://${WOOTESTS_IP}" +TEST_SITE_WP_DOMAIN="${WOOTESTS_IP}" +TEST_SITE_ADMIN_EMAIL="grola@seostudio.pl" +TEST_SITE_ADMIN_USERNAME="admin" +TEST_SITE_ADMIN_PASSWORD="admin" +SELENIUM_HOST="chrome" +SELENIUM_PORT=4444 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fdc61bc748829d8a14f73c0903433da358b505d0..0d0d1a3335c7ceffa774e10f2badd4bdbec9ab26 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,4 +5,3 @@ variables: IS_LIBRARY: 1 include: 'https://gitlab.com/wpdesk/gitlab-ci/raw/master/gitlab-ci-1.2.yml' - diff --git a/CHANGELOG.md b/CHANGELOG.md index 81e8b9a5bbbbc321707e1f4177670b14e69ed717..1afd78ceb4bfbfa7388d1640ab1120b7b890132a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,9 @@ -## [3.2.1] - 2023-02-10 +## [3.2.2] - 2023-03-03 +### Added +- security nonce in permanent dismissible notice ajax action +## [3.2.1] - 2023-02-10 ### Changed - - Changed dodgy string with `../../..` for `dirname` with level parameter ## [3.2.0] - 2022-05-27 diff --git a/assets/js/notice.js b/assets/js/notice.js index 2a206977b9c284ca2eaaebbf86fa2f59812a8db2..c5c396fe3cd7bf1da27ce530900dd42154f4a6c4 100644 --- a/assets/js/notice.js +++ b/assets/js/notice.js @@ -1,11 +1,14 @@ jQuery( document ).on( 'click', '.notice-dismiss', function() { - var notice_name = jQuery(this).closest('div.notice').data('notice-name'); - var source = jQuery(this).closest('div.notice').data('source'); + const $notice_div= jQuery(this).closest('div.notice'); + const notice_name = $notice_div.data('notice-name'); + const source = $notice_div.data('source'); + const security = $notice_div.data('security'); if ('' !== notice_name) { jQuery.ajax({ url: ajaxurl, type: 'post', data: { + security: security, action: 'wpdesk_notice_dismiss', notice_name: notice_name, source: source, diff --git a/assets/js/notice.min.js b/assets/js/notice.min.js deleted file mode 100644 index f5d79070ca619f44611617d8b47aa9cfd419634e..0000000000000000000000000000000000000000 --- a/assets/js/notice.min.js +++ /dev/null @@ -1 +0,0 @@ -jQuery(document).on("click",".notice-dismiss",function(){var a=jQuery(this).closest("div.notice").data("notice-name");var b=jQuery(this).closest("div.notice").data("source");if(""!==a){jQuery.ajax({url:ajaxurl,type:"post",data:{action:"wpdesk_notice_dismiss",notice_name:a,source:b},success:function(c){}})}});jQuery(document).on("click",".notice-dismiss-link",function(){jQuery(this).closest("div.notice").data("source",jQuery(this).data("source"));jQuery(this).closest("div.notice").find(".notice-dismiss").click()}); \ No newline at end of file diff --git a/codeception.dist.yml b/codeception.dist.yml new file mode 100644 index 0000000000000000000000000000000000000000..7e75cf592952bce2b87c2ef18bcf1e87603f24bf --- /dev/null +++ b/codeception.dist.yml @@ -0,0 +1,31 @@ +paths: + tests: tests/codeception/tests + output: tests/codeception/tests/_output + data: tests/codeception/tests/_data + support: tests/codeception/tests/_support + envs: tests/codeception/tests/_envs +actor_suffix: Tester +extensions: + enabled: + - Codeception\Extension\RunFailed +# - Codeception\Extension\Recorder: +# module: WPWebDriver +# delete_successful: false # keep screenshots of successful tests + commands: + - Codeception\Command\GenerateWPUnit + - Codeception\Command\GenerateWPRestApi + - Codeception\Command\GenerateWPRestController + - Codeception\Command\GenerateWPRestPostTypeController + - Codeception\Command\GenerateWPAjax + - Codeception\Command\GenerateWPCanonical + - Codeception\Command\GenerateWPXMLRPC + - WPDesk\Codeception\Command\GeneratePluginActivation + - WPDesk\Codeception\Command\GenerateWooCommerce + - tad\Codeception\Command\Steppify +params: + - .env.testing +coverage: + remote: false + include: + - classes + - src diff --git a/composer.json b/composer.json index 944275dd5083028095f701f177d82988bc2e8e20..a7dd46f19aca4270f9d8a3a6cf2b9196db4716a3 100644 --- a/composer.json +++ b/composer.json @@ -13,20 +13,24 @@ ], "config": { "platform": { - "php": "7.0" + "php": "7.0.8" + }, + "allow-plugins": { + "kylekatarnls/update-helper": true, + "wpdesk/wp-codeception": true } }, "require": { - "php": ">=5.5", + "php": ">=7.0.8", "wpdesk/wp-builder": "^1.0|^2.0" }, "require-dev": { - "phpunit/phpunit": "<7", "wp-coding-standards/wpcs": "^0.14.1", "squizlabs/php_codesniffer": "^3.0.2", "mockery/mockery": "*", "10up/wp_mock": "*", - "wimg/php-compatibility": "^8" + "wimg/php-compatibility": "^8", + "wpdesk/wp-codeception": "^2.7" }, "autoload": { "psr-4": {"WPDesk\\Notice\\": "src/WPDesk/Notice/"}, diff --git a/src/WPDesk/Notice/AjaxHandler.php b/src/WPDesk/Notice/AjaxHandler.php index 48e7e0bc39b3fe2dd5e0c7907b30fabc6dc62360..263e84b7ff630f977fdbd356c785ffc01792e152 100644 --- a/src/WPDesk/Notice/AjaxHandler.php +++ b/src/WPDesk/Notice/AjaxHandler.php @@ -12,13 +12,13 @@ use WPDesk\PluginBuilder\Plugin\PluginAccess; * * @package WPDesk\Notice */ -class AjaxHandler implements HookablePluginDependant -{ +class AjaxHandler implements HookablePluginDependant { use PluginAccess; const POST_FIELD_NOTICE_NAME = 'notice_name'; const POST_FIELD_SOURCE = 'source'; + const POST_FIELD_SECURITY = 'security'; const SCRIPTS_VERSION = '4'; const SCRIPT_HANDLE = 'wpdesk_notice'; @@ -33,44 +33,39 @@ class AjaxHandler implements HookablePluginDependant * * @param string|null $assetsURL Assets URL. */ - public function __construct($assetsURL = null) - { + public function __construct( $assetsURL = null ) { $this->assetsURL = $assetsURL; } /** * Hooks. */ - public function hooks() - { - if ($this->assetsURL) { - add_action('admin_enqueue_scripts', [$this, 'enqueueAdminScripts']); + public function hooks() { + if ( $this->assetsURL ) { + add_action( 'admin_enqueue_scripts', [ $this, 'enqueueAdminScripts' ] ); } else { - add_action('admin_head', [$this,'addScriptToAdminHead']); + add_action( 'admin_head', [ $this, 'addScriptToAdminHead' ] ); } - add_action('wp_ajax_wpdesk_notice_dismiss', [$this, 'processAjaxNoticeDismiss']); + add_action( 'wp_ajax_wpdesk_notice_dismiss', [ $this, 'processAjaxNoticeDismiss' ] ); } /** * Enqueue admin scripts. */ - public function enqueueAdminScripts() - { - $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; + public function enqueueAdminScripts() { wp_register_script( self::SCRIPT_HANDLE, - trailingslashit($this->assetsURL) . 'js/notice' . $suffix . '.js', - array( 'jquery' ), + trailingslashit( $this->assetsURL ) . 'js/notice.js', + [ 'jquery' ], self::SCRIPTS_VERSION ); - wp_enqueue_script(self::SCRIPT_HANDLE); + wp_enqueue_script( self::SCRIPT_HANDLE ); } /** * Add Java Script to admin header. */ - public function addScriptToAdminHead() - { + public function addScriptToAdminHead() { include __DIR__ . '/views/admin-head-js.php'; } @@ -79,25 +74,33 @@ class AjaxHandler implements HookablePluginDependant * * Updates corresponded WordPress option and fires wpdesk_notice_dismissed_notice action with notice name. */ - public function processAjaxNoticeDismiss() - { - if (isset($_POST[self::POST_FIELD_NOTICE_NAME])) { - $noticeName = sanitize_text_field($_POST[self::POST_FIELD_NOTICE_NAME]); + public function processAjaxNoticeDismiss() { + if ( isset( $_POST[ self::POST_FIELD_NOTICE_NAME ] ) ) { + $noticeName = sanitize_text_field( $_POST[ self::POST_FIELD_NOTICE_NAME ] ); - if (isset($_POST[self::POST_FIELD_SOURCE])) { - $source = sanitize_text_field($_POST[ self::POST_FIELD_SOURCE ]); + if ( isset( $_POST[ self::POST_FIELD_SOURCE ] ) ) { + $source = sanitize_text_field( $_POST[ self::POST_FIELD_SOURCE ] ); } else { $source = null; } - update_option( - PermanentDismissibleNotice::OPTION_NAME_PREFIX . $noticeName, - PermanentDismissibleNotice::OPTION_VALUE_DISMISSED - ); - do_action('wpdesk_notice_dismissed_notice', $noticeName, $source); + $security = $_POST[ self::POST_FIELD_SECURITY ] ?? ''; + + $option_name = PermanentDismissibleNotice::OPTION_NAME_PREFIX . $noticeName; + + if ( wp_verify_nonce( $security, $option_name ) ) { + update_option( + $option_name, + PermanentDismissibleNotice::OPTION_VALUE_DISMISSED + ); + do_action( 'wpdesk_notice_dismissed_notice', $noticeName, $source ); + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { + wp_send_json_success(); + } + } } - if (defined('DOING_AJAX') && DOING_AJAX) { - die(); + if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) { + wp_send_json_error(); } } diff --git a/src/WPDesk/Notice/PermanentDismissibleNotice.php b/src/WPDesk/Notice/PermanentDismissibleNotice.php index 741b4c4e008da0431fd638a46639d3c1c4ae8700..bc481e9da3916f7e50b11283305f57db2ccfd86f 100644 --- a/src/WPDesk/Notice/PermanentDismissibleNotice.php +++ b/src/WPDesk/Notice/PermanentDismissibleNotice.php @@ -19,6 +19,11 @@ class PermanentDismissibleNotice extends Notice */ private $noticeName; + /** + * @var string + */ + private $noticeSecurity; + /** * @var string */ @@ -47,6 +52,8 @@ class PermanentDismissibleNotice extends Notice $this->noticeDismissOptionName = static::OPTION_NAME_PREFIX . $noticeName; if (self::OPTION_VALUE_DISMISSED === get_option($this->noticeDismissOptionName, '')) { $this->removeAction(); + } else { + $this->noticeSecurity = wp_create_nonce($this->noticeDismissOptionName); } } @@ -68,6 +75,7 @@ class PermanentDismissibleNotice extends Notice { $attributesAsString = parent::getAttributesAsString(); $attributesAsString .= sprintf(' data-notice-name="%1$s"', esc_attr($this->noticeName)); + $attributesAsString .= sprintf(' data-security="%1$s"', esc_attr($this->noticeSecurity)); $attributesAsString .= sprintf(' id="wpdesk-notice-%1$s"', esc_attr($this->noticeName)); return $attributesAsString; } diff --git a/src/WPDesk/Notice/views/admin-head-js.php b/src/WPDesk/Notice/views/admin-head-js.php index 0f716274ae1c25e678bae9bdf4fcabe11cf7b284..5509cb4a519cc87b6e0e30432ea3d82ac03572b3 100644 --- a/src/WPDesk/Notice/views/admin-head-js.php +++ b/src/WPDesk/Notice/views/admin-head-js.php @@ -4,5 +4,5 @@ if ( ! defined( 'ABSPATH' ) ) { } // Exit if accessed directly ?> <script type="text/javascript"> - <?php include dirname(__FILE__, 5) . '/assets/js/notice.min.js'; ?> + <?php include dirname(__FILE__, 5) . '/assets/js/notice.js'; ?> </script> diff --git a/tests/codeception/codeception.yml b/tests/codeception/codeception.yml new file mode 100644 index 0000000000000000000000000000000000000000..18bdc7c088d3bd98e142b834722fa4dc9b6566b9 --- /dev/null +++ b/tests/codeception/codeception.yml @@ -0,0 +1,11 @@ +paths: + tests: tests + output: tests/_output + data: tests/_data + support: tests/_support + envs: tests/_envs +actor_suffix: Tester +extensions: + enabled: + - Codeception\Extension\RunFailed + diff --git a/tests/codeception/tests/_data/.gitkeep b/tests/codeception/tests/_data/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/codeception/tests/_output/.gitignore b/tests/codeception/tests/_output/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d6b7ef32c8478a48c3994dcadc86837f4371184d --- /dev/null +++ b/tests/codeception/tests/_output/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/tests/codeception/tests/acceptance/.gitkeep b/tests/codeception/tests/acceptance/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/codeception/tests/functional/.gitkeep b/tests/codeception/tests/functional/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/codeception/tests/integration.suite.yml b/tests/codeception/tests/integration.suite.yml new file mode 100644 index 0000000000000000000000000000000000000000..25ef607c1f3de3ce2340ad644c5ee1059b6e602d --- /dev/null +++ b/tests/codeception/tests/integration.suite.yml @@ -0,0 +1,37 @@ +# Codeception Test Suite Configuration +# +# Suite for integration tests. + +bootstrap: bootstrap.php + +modules: + enabled: + - WPDb + - WPLoader + config: + WPDb: + dsn: 'mysql:host=%TEST_SITE_DB_HOST%;dbname=%TEST_SITE_DB_NAME%' + user: '%TEST_SITE_DB_USER%' + password: '%TEST_SITE_DB_PASSWORD%' + dump: 'tests/codeception/tests/_data/db.sql' + #import the dump before the tests; this means the test site database will be repopulated before the tests. + populate: false + # re-import the dump between tests; this means the test site database will be repopulated between the tests. + cleanup: false + waitlock: 10 + url: '%TEST_SITE_WP_URL%' + originalUrl: '%TEST_SITE_WP_URL%' + urlReplacement: true #replace the hardcoded dump URL with the one above + tablePrefix: '%TEST_SITE_TABLE_PREFIX%' + WPLoader: + multisite: false + wpRootFolder: '%WP_ROOT_FOLDER%' + dbName: "%TEST_SITE_DB_NAME%" + dbHost: "%TEST_SITE_DB_HOST%" + dbUser: "%TEST_SITE_DB_USER%" + dbPassword: "%TEST_SITE_DB_PASSWORD%" + isolatedInstall: false + loadOnly: false + tablePrefix: "%TEST_SITE_TABLE_PREFIX%" + plugins: [] + activatePlugins: [] diff --git a/tests/codeception/tests/integration/AjaxHandlerTest.php b/tests/codeception/tests/integration/AjaxHandlerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c0f40f9992362437d5efe3657ea9a396eef03657 --- /dev/null +++ b/tests/codeception/tests/integration/AjaxHandlerTest.php @@ -0,0 +1,106 @@ +<?php + +namespace codeception\tests\integration; + +use Codeception\TestCase\WPTestCase; +use \WPDesk\Notice\AjaxHandler; +use \WPDesk\Notice\PermanentDismissibleNotice; + +class AjaxHandlerTest extends WPTestCase { + + const ASSETS_URL = 'http://test.com/test/assetes/'; + const NOTICE_NAME = 'test_notice_name'; + const WP_DEFAULT_PRIORITY = 10; + + public function setUp() { + parent::setUp(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testHooksWithAssetsURL() { + $ajaxHandler = new AjaxHandler( self::ASSETS_URL ); + $ajaxHandler->hooks(); + + $this->assertEquals( + self::WP_DEFAULT_PRIORITY, + has_action( 'admin_enqueue_scripts', [ $ajaxHandler, 'enqueueAdminScripts' ] ) + ); + $this->assertEquals( + self::WP_DEFAULT_PRIORITY, + has_action( 'wp_ajax_wpdesk_notice_dismiss', [ $ajaxHandler, 'processAjaxNoticeDismiss' ] ) + ); + } + + public function testHooksWithoutAssetsURL() { + $ajaxHandler = new AjaxHandler(); + $ajaxHandler->hooks(); + + $this->assertEquals( + self::WP_DEFAULT_PRIORITY, + has_action( 'admin_head', [ $ajaxHandler, 'addScriptToAdminHead' ] ) + ); + $this->assertEquals( + self::WP_DEFAULT_PRIORITY, + has_action( 'wp_ajax_wpdesk_notice_dismiss', [ $ajaxHandler, 'processAjaxNoticeDismiss' ] ) + ); + } + + public function testEnqueueAdminScripts() { + $this->markTestSkipped( 'Must be revisited. get_current_screen not working.' ); + $ajaxHandler = new AjaxHandler( self::ASSETS_URL ); + $ajaxHandler->hooks(); + do_action( 'admin_enqueue_scripts' ); + $registeredScripts = wp_scripts()->registered; + + $this->assertArrayHasKey( 'wpdesk_notice', $registeredScripts, 'Script not registered!' ); + $this->assertEquals( + self::ASSETS_URL . 'js/notice.js', + $registeredScripts['wpdesk_notice']->src, + 'Script src is invalid!' + ); + } + + public function testAddScriptToAdminHead() { + $ajaxHandler = new AjaxHandler(); + $ajaxHandler->hooks(); + + $this->expectOutputString( '<script type="text/javascript">' + . "\n " + . file_get_contents( __DIR__ . '/../../../../assets/js/notice.js' ) + . '</script> +' + ); + + $ajaxHandler->addScriptToAdminHead(); + } + + public function testProcessAjaxNoticeDismiss() { + $_POST[ AjaxHandler::POST_FIELD_NOTICE_NAME ] = self::NOTICE_NAME; + $_POST[ AjaxHandler::POST_FIELD_SECURITY ] = wp_create_nonce( PermanentDismissibleNotice::OPTION_NAME_PREFIX . sanitize_text_field( self::NOTICE_NAME ) ); + + $ajaxHandler = new AjaxHandler( self::ASSETS_URL ); + $ajaxHandler->processAjaxNoticeDismiss(); + + $this->assertEquals( + PermanentDismissibleNotice::OPTION_VALUE_DISMISSED, + get_option( PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME ) + ); + } + + public function testShoulfNotProcessAjaxNoticeDismissWhenInvalidNonce() { + $_POST[ AjaxHandler::POST_FIELD_NOTICE_NAME ] = self::NOTICE_NAME; + $_POST[ AjaxHandler::POST_FIELD_SECURITY ] = wp_create_nonce(); + + $ajaxHandler = new AjaxHandler( self::ASSETS_URL ); + $ajaxHandler->processAjaxNoticeDismiss(); + + $this->assertNotEquals( + PermanentDismissibleNotice::OPTION_VALUE_DISMISSED, + get_option( PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME ) + ); + } + +} diff --git a/tests/codeception/tests/integration/FunctionsTest.php b/tests/codeception/tests/integration/FunctionsTest.php new file mode 100644 index 0000000000000000000000000000000000000000..05117cb1a1dd30d263f0e2cb7c4edd8a7cc8968c --- /dev/null +++ b/tests/codeception/tests/integration/FunctionsTest.php @@ -0,0 +1,119 @@ +<?php + +namespace codeception\tests\integration; + +use Codeception\TestCase\WPTestCase; +use \WPDesk\Notice\Notice; +use \WPDesk\Notice\PermanentDismissibleNotice; + +/** + * Class TestFunctions + */ +class FunctionsTest extends WPTestCase { + + public function setUp() { + parent::setUp(); + } + + public function tearDown() { + parent::tearDown(); + } + + /** + * Test WPDeskWpNotice function. + */ + public function testWPDeskWpNotice() { + $notice = wpdesk_wp_notice( 'test function' ); + + $this->assertInstanceOf( Notice::class, $notice ); + + $this->expectOutputString( '<div class="notice notice-info"><p>test function</p></div>' ); + + $notice->showNotice(); + } + + /** + * Test WPDeskWpNoticeInfo function. + */ + public function testWPDeskWpNoticeInfo() { + $notice = wpdesk_wp_notice_info( 'test function' ); + + $this->assertInstanceOf( Notice::class, $notice ); + + $this->expectOutputString( '<div class="notice notice-info"><p>test function</p></div>' ); + + $notice->showNotice(); + } + + /** + * Test WPDeskWpNoticeError function. + */ + public function testWPDeskWpNoticeError() { + $notice = wpdesk_wp_notice_error( 'test function' ); + + $this->assertInstanceOf( Notice::class, $notice ); + + $this->expectOutputString( '<div class="notice notice-error"><p>test function</p></div>' ); + + $notice->showNotice(); + } + + /** + * Test WPDeskWpNoticeWarning function. + */ + public function testWPDeskWpNoticeWarning() { + $notice = wpdesk_wp_notice_warning( 'test function' ); + + $this->assertInstanceOf( Notice::class, $notice ); + + $this->expectOutputString( '<div class="notice notice-warning"><p>test function</p></div>' ); + + $notice->showNotice(); + } + + /** + * Test WPDeskWpNoticeSuccess function. + */ + public function testWPDeskWpNoticeSuccess() { + $notice = wpdesk_wp_notice_success( 'test function' ); + + $this->assertInstanceOf( Notice::class, $notice ); + + $this->expectOutputString( '<div class="notice notice-success"><p>test function</p></div>' ); + + $notice->showNotice(); + } + + /** + * Test WPDeskPermanentDismissibleWpNotice function. + */ + public function testWPDeskPermanentDismissibleWpNotice() { + $notice_name = 'test-notice'; + + $notice = wpdesk_permanent_dismissible_wp_notice( + 'test function', + $notice_name, + Notice::NOTICE_TYPE_INFO + ); + + $security = wp_create_nonce( PermanentDismissibleNotice::OPTION_NAME_PREFIX . $notice_name ); + + $this->assertInstanceOf( PermanentDismissibleNotice::class, $notice ); + + $this->expectOutputString( + '<div class="notice notice-info is-dismissible" data-notice-name="' . $notice_name . '" data-security="' . $security . '" id="wpdesk-notice-test-notice"><p>test function</p></div>' + ); + + $notice->showNotice(); + } + + /** + * Test WPDeskInitNoticeAjaxHandler function. + */ + public function testWPDeskInitWpNoticeAjaxHandler() { + $ajax_handler = wpdesk_init_wp_notice_ajax_handler(); + + $this->assertInstanceOf( \WPDesk\Notice\AjaxHandler::class, $ajax_handler ); + } + +} diff --git a/tests/codeception/tests/integration/NoticeTest.php b/tests/codeception/tests/integration/NoticeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..feb1c1e7de7407750be54ba6bd3d6c33c3a058f1 --- /dev/null +++ b/tests/codeception/tests/integration/NoticeTest.php @@ -0,0 +1,144 @@ +<?php + +namespace codeception\tests\integration; + +use Codeception\TestCase\WPTestCase; +use \WPDesk\Notice\Notice; + +class NoticeTest extends WPTestCase { + + public function setUp() { + parent::setUp(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testAddAction() { + $notice_priority = 11; + + $notice = new Notice( Notice::NOTICE_TYPE_INFO, 'test', false, $notice_priority ); + + $this->assertEquals( $notice_priority, has_action( 'admin_notices', [ + $notice, + 'showNotice', + ], $notice_priority ) ); + + $this->assertEquals( + Notice::ADMIN_FOOTER_BASE_PRIORITY + intval( $notice_priority ), + has_action( + 'admin_footer', + [ $notice, 'showNotice' ], + Notice::ADMIN_FOOTER_BASE_PRIORITY + intval( $notice_priority ) + ) + ); + } + + public function testShowNotice() { + $notice = new Notice( 'test' ); + + $this->expectOutputString( '<div class="notice notice-info"><p>test</p></div>' ); + + $notice->showNotice(); + + $this->assertFalse( + has_action( 'admin_notices', [ $notice, 'showNotice' ], 10 ) + ); + $this->assertFalse( + has_action( 'admin_footer', [ $notice, 'showNotice' ], 10 ) + ); + } + + public function testShowNoticeError() { + $notice = new Notice( 'test', Notice::NOTICE_TYPE_ERROR ); + + $this->expectOutputString( '<div class="notice notice-error"><p>test</p></div>' ); + + $notice->showNotice(); + } + + public function testShowNoticeWarning() { + $notice = new Notice( 'test', Notice::NOTICE_TYPE_WARNING ); + + $this->expectOutputString( '<div class="notice notice-warning"><p>test</p></div>' ); + + $notice->showNotice(); + } + + public function testShowNoticeSuccess() { + $notice = new Notice( 'test', Notice::NOTICE_TYPE_SUCCESS ); + + $this->expectOutputString( '<div class="notice notice-success"><p>test</p></div>' ); + + $notice->showNotice(); + } + + public function testShowNoticeDismissible() { + $notice = new Notice( 'test', Notice::NOTICE_TYPE_INFO, true ); + + $this->expectOutputString( '<div class="notice notice-info is-dismissible"><p>test</p></div>' ); + + $notice->showNotice(); + } + + public function testNoticeContent() { + $noticeContent = 'test'; + + $notice = new Notice( $noticeContent ); + + $this->assertEquals( $noticeContent, $notice->getNoticeContent() ); + + $noticeContent = 'test 2'; + $notice->setNoticeContent( $noticeContent ); + $this->assertEquals( $noticeContent, $notice->getNoticeContent() ); + } + + public function testNoticeType() { + $notice = new Notice( 'test', Notice::NOTICE_TYPE_INFO ); + + $this->assertEquals( Notice::NOTICE_TYPE_INFO, $notice->getNoticeType() ); + + $notice->setNoticeType( Notice::NOTICE_TYPE_ERROR ); + $this->assertEquals( Notice::NOTICE_TYPE_ERROR, $notice->getNoticeType() ); + } + + public function testDismissible() { + $notice = new Notice( 'test' ); + + $this->assertFalse( $notice->isDismissible() ); + + $notice->setDismissible( true ); + $this->assertTrue( $notice->isDismissible() ); + } + + public function testPriority() { + $notice = new Notice( 'test' ); + + $this->assertEquals( 10, $notice->getPriority() ); + + $notice->setPriority( 20 ); + $this->assertEquals( 20, $notice->getPriority() ); + } + + public function testAddAttribute() { + $notice = new Notice( 'test', Notice::NOTICE_TYPE_WARNING ); + + $notice->addAttribute( 'id', 'test_id' ); + + $this->expectOutputString( '<div class="notice notice-warning" id="test_id"><p>test</p></div>' ); + + $notice->showNotice(); + } + + public function testAddAttributeClass() { + $notice = new Notice( 'test', Notice::NOTICE_TYPE_WARNING ); + + $notice->addAttribute( 'class', 'test-class' ); + + $this->expectOutputString( '<div class="notice notice-warning test-class"><p>test</p></div>' ); + + $notice->showNotice(); + } + +} diff --git a/tests/codeception/tests/integration/PermanentDismissinleNoticeTest.php b/tests/codeception/tests/integration/PermanentDismissinleNoticeTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ec59a580fb96eed3994e1d115342cd966a24f37e --- /dev/null +++ b/tests/codeception/tests/integration/PermanentDismissinleNoticeTest.php @@ -0,0 +1,72 @@ +<?php + +namespace codeception\tests\integration; + +use Codeception\TestCase\WPTestCase; +use \WPDesk\Notice\PermanentDismissibleNotice; + +class PermanentDismissinleNoticeTest extends WPTestCase { + + const NOTICE_NAME = 'test_notice_name'; + + public function setUp() { + parent::setUp(); + } + + public function tearDown() { + parent::tearDown(); + } + + public function testAddAction() { + $notice_priority = 11; + + $notice = new PermanentDismissibleNotice( + 'test', + 'test_name', + PermanentDismissibleNotice::NOTICE_TYPE_INFO, + $notice_priority + ); + + $this->assertEquals( $notice_priority, has_action( 'admin_notices', [ + $notice, + 'showNotice', + ], $notice_priority ) ); + } + + public function testUndoDismiss() { + update_option( + PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME, + PermanentDismissibleNotice::OPTION_VALUE_DISMISSED + ); + + $notice = new PermanentDismissibleNotice( + PermanentDismissibleNotice::NOTICE_TYPE_INFO, + self::NOTICE_NAME + ); + $notice->undoDismiss(); + + $this->assertEquals( + '', + get_option( PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME, '' ) + ); + } + + public function testShowNotice() { + $notice_name = 'test_name'; + + $notice = new PermanentDismissibleNotice( + 'test', + $notice_name, + PermanentDismissibleNotice::NOTICE_TYPE_INFO + ); + + $security = wp_create_nonce( PermanentDismissibleNotice::OPTION_NAME_PREFIX . $notice_name ); + + $this->expectOutputString( + '<div class="notice notice-info is-dismissible" data-notice-name="' . $notice_name . '" data-security="' . $security . '" id="wpdesk-notice-test_name"><p>test</p></div>' + ); + + $notice->showNotice(); + } + +} diff --git a/tests/codeception/tests/integration/bootstrap.php b/tests/codeception/tests/integration/bootstrap.php new file mode 100644 index 0000000000000000000000000000000000000000..2aaab73866ef427723cb84dcbd14b193b646411f --- /dev/null +++ b/tests/codeception/tests/integration/bootstrap.php @@ -0,0 +1,5 @@ +<?php + +ini_set('error_reporting', E_ALL ^ E_DEPRECATED); + + diff --git a/tests/codeception/tests/unit/.gitkeep b/tests/codeception/tests/unit/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/tests/codeception/wpdesk.yml b/tests/codeception/wpdesk.yml new file mode 100644 index 0000000000000000000000000000000000000000..870a58cd2df9c7068dc7ac1101dc3c7d0c639a83 --- /dev/null +++ b/tests/codeception/wpdesk.yml @@ -0,0 +1,8 @@ +plugin-slug: none +plugin-file: none +plugin-title: none +plugins: + repository: + local: + activate: +prepare-database: diff --git a/tests/integration/TestAjaxHandler.php b/tests/integration/TestAjaxHandler.php deleted file mode 100644 index 3007b4bee16624efbcea301ad8b386ef38c77e1a..0000000000000000000000000000000000000000 --- a/tests/integration/TestAjaxHandler.php +++ /dev/null @@ -1,85 +0,0 @@ -<?php - -use \WPDesk\Notice\AjaxHandler; -use \WPDesk\Notice\PermanentDismissibleNotice; - -class TestAjaxHandler extends WP_UnitTestCase -{ - - const ASSETS_URL = 'http://test.com/test/assetes/'; - const NOTICE_NAME = 'test_notice_name'; - const WP_DEFAULT_PRIORITY = 10; - - public function testHooksWithAssetsURL() - { - $ajaxHandler = new AjaxHandler(self::ASSETS_URL); - $ajaxHandler->hooks(); - - $this->assertEquals( - self::WP_DEFAULT_PRIORITY, - has_action('admin_enqueue_scripts', [$ajaxHandler, 'enqueueAdminScripts']) - ); - $this->assertEquals( - self::WP_DEFAULT_PRIORITY, - has_action('wp_ajax_wpdesk_notice_dismiss', [$ajaxHandler, 'processAjaxNoticeDismiss']) - ); - } - - public function testHooksWithoutAssetsURL() - { - $ajaxHandler = new AjaxHandler(); - $ajaxHandler->hooks(); - - $this->assertEquals( - self::WP_DEFAULT_PRIORITY, - has_action('admin_head', [$ajaxHandler, 'addScriptToAdminHead']) - ); - $this->assertEquals( - self::WP_DEFAULT_PRIORITY, - has_action('wp_ajax_wpdesk_notice_dismiss', [$ajaxHandler, 'processAjaxNoticeDismiss']) - ); - } - - public function testEnqueueAdminScripts() - { - $this->markTestSkipped('Must be revisited. get_current_screen not working.'); - $ajaxHandler = new AjaxHandler(self::ASSETS_URL); - $ajaxHandler->hooks(); - do_action('admin_enqueue_scripts'); - $registeredScripts = wp_scripts()->registered; - - $this->assertArrayHasKey('wpdesk_notice', $registeredScripts, 'Script not registered!'); - $this->assertEquals( - self::ASSETS_URL . 'js/notice.js', - $registeredScripts['wpdesk_notice']->src, - 'Script src is invalid!' - ); - } - - public function testAddScriptToAdminHead() - { - $ajaxHandler = new AjaxHandler(); - $ajaxHandler->hooks(); - - $this->expectOutputString('<script type="text/javascript"> - jQuery(document).on("click",".notice-dismiss",function(){var a=jQuery(this).closest("div.notice").data("notice-name");var b=jQuery(this).closest("div.notice").data("source");if(""!==a){jQuery.ajax({url:ajaxurl,type:"post",data:{action:"wpdesk_notice_dismiss",notice_name:a,source:b},success:function(c){}})}});jQuery(document).on("click",".notice-dismiss-link",function(){jQuery(this).closest("div.notice").data("source",jQuery(this).data("source"));jQuery(this).closest("div.notice").find(".notice-dismiss").click()});</script> -' - ); - - $ajaxHandler->addScriptToAdminHead(); - } - - public function testProcessAjaxNoticeDismiss() - { - $_POST[AjaxHandler::POST_FIELD_NOTICE_NAME] = self::NOTICE_NAME; - - $ajaxHandler = new AjaxHandler(self::ASSETS_URL); - $ajaxHandler->processAjaxNoticeDismiss(); - - $this->assertEquals( - PermanentDismissibleNotice::OPTION_VALUE_DISMISSED, - get_option(PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME) - ); - } - -} diff --git a/tests/integration/TestFunctions.php b/tests/integration/TestFunctions.php deleted file mode 100644 index be3177e8c7dc18cfaccb83e5b527134827647dfd..0000000000000000000000000000000000000000 --- a/tests/integration/TestFunctions.php +++ /dev/null @@ -1,121 +0,0 @@ -<?php - -use \WPDesk\Notice\Notice; -use \WPDesk\Notice\PermanentDismissibleNotice; - -/** - * Class TestFunctions - */ -class TestFunctions extends WP_UnitTestCase -{ - - /** - * Test redeclare functions. - */ - public function testRedeclareFunctions() - { - include __DIR__ . '/../../src/WPDesk/notice-functions.php'; - $this->assertTrue(true); - } - - /** - * Test WPDeskWpNotice function. - */ - public function testWPDeskWpNotice() - { - $notice = wpdesk_wp_notice('test function'); - - $this->assertInstanceOf(Notice::class, $notice); - - $this->expectOutputString('<div class="notice notice-info"><p>test function</p></div>'); - - $notice->showNotice(); - } - - /** - * Test WPDeskWpNoticeInfo function. - */ - public function testWPDeskWpNoticeInfo() - { - $notice = wpdesk_wp_notice_info('test function'); - - $this->assertInstanceOf(Notice::class, $notice); - - $this->expectOutputString('<div class="notice notice-info"><p>test function</p></div>'); - - $notice->showNotice(); - } - - /** - * Test WPDeskWpNoticeError function. - */ - public function testWPDeskWpNoticeError() - { - $notice = wpdesk_wp_notice_error('test function'); - - $this->assertInstanceOf(Notice::class, $notice); - - $this->expectOutputString('<div class="notice notice-error"><p>test function</p></div>'); - - $notice->showNotice(); - } - - /** - * Test WPDeskWpNoticeWarning function. - */ - public function testWPDeskWpNoticeWarning() - { - $notice = wpdesk_wp_notice_warning('test function'); - - $this->assertInstanceOf(Notice::class, $notice); - - $this->expectOutputString('<div class="notice notice-warning"><p>test function</p></div>'); - - $notice->showNotice(); - } - - /** - * Test WPDeskWpNoticeSuccess function. - */ - public function testWPDeskWpNoticeSuccess() - { - $notice = wpdesk_wp_notice_success('test function'); - - $this->assertInstanceOf(Notice::class, $notice); - - $this->expectOutputString('<div class="notice notice-success"><p>test function</p></div>'); - - $notice->showNotice(); - } - - /** - * Test WPDeskPermanentDismissibleWpNotice function. - */ - public function testWPDeskPermanentDismissibleWpNotice() - { - $notice = wpdesk_permanent_dismissible_wp_notice( - 'test function', - 'test-notice', - Notice::NOTICE_TYPE_INFO - ); - - $this->assertInstanceOf(PermanentDismissibleNotice::class, $notice); - - $this->expectOutputString( - '<div class="notice notice-info is-dismissible" data-notice-name="test-notice" id="wpdesk-notice-test-notice"><p>test function</p></div>' - ); - - $notice->showNotice(); - } - - /** - * Test WPDeskInitNoticeAjaxHandler function. - */ - public function testWPDeskInitWpNoticeAjaxHandler() - { - $ajax_handler = wpdesk_init_wp_notice_ajax_handler(); - - $this->assertInstanceOf(\WPDesk\Notice\AjaxHandler::class, $ajax_handler); - } - -} diff --git a/tests/integration/TestNotice.php b/tests/integration/TestNotice.php deleted file mode 100644 index d4ec8871869f3c340e2da4bdaf7a35aa31ddb318..0000000000000000000000000000000000000000 --- a/tests/integration/TestNotice.php +++ /dev/null @@ -1,143 +0,0 @@ -<?php - -use \WPDesk\Notice\Notice; - -class TestNotice extends WP_UnitTestCase -{ - - public function testAddAction() - { - $notice_priority = 11; - - $notice = new Notice(Notice::NOTICE_TYPE_INFO, 'test', false, $notice_priority); - - $this->assertEquals($notice_priority, has_action('admin_notices', [$notice, 'showNotice'], $notice_priority)); - - $this->assertEquals( - Notice::ADMIN_FOOTER_BASE_PRIORITY + intval($notice_priority), - has_action( - 'admin_footer', - [$notice, 'showNotice'], - Notice::ADMIN_FOOTER_BASE_PRIORITY + intval($notice_priority) - ) - ); - } - - public function testShowNotice() - { - $notice = new Notice('test'); - - $this->expectOutputString('<div class="notice notice-info"><p>test</p></div>'); - - $notice->showNotice(); - - $this->assertFalse( - has_action('admin_notices', [$notice, 'showNotice'], 10) - ); - $this->assertFalse( - has_action('admin_footer', [$notice, 'showNotice'], 10) - ); - } - - public function testShowNoticeError() - { - $notice = new Notice('test', Notice::NOTICE_TYPE_ERROR); - - $this->expectOutputString('<div class="notice notice-error"><p>test</p></div>'); - - $notice->showNotice(); - } - - public function testShowNoticeWarning() - { - $notice = new Notice('test', Notice::NOTICE_TYPE_WARNING); - - $this->expectOutputString('<div class="notice notice-warning"><p>test</p></div>'); - - $notice->showNotice(); - } - - public function testShowNoticeSuccess() - { - $notice = new Notice('test', Notice::NOTICE_TYPE_SUCCESS); - - $this->expectOutputString('<div class="notice notice-success"><p>test</p></div>'); - - $notice->showNotice(); - } - - public function testShowNoticeDismissible() - { - $notice = new Notice('test', Notice::NOTICE_TYPE_INFO, true); - - $this->expectOutputString('<div class="notice notice-info is-dismissible"><p>test</p></div>'); - - $notice->showNotice(); - } - - public function testNoticeContent() - { - $noticeContent = 'test'; - - $notice = new Notice($noticeContent); - - $this->assertEquals($noticeContent, $notice->getNoticeContent()); - - $noticeContent = 'test 2'; - $notice->setNoticeContent($noticeContent); - $this->assertEquals($noticeContent, $notice->getNoticeContent()); - } - - public function testNoticeType() - { - $notice = new Notice('test', Notice::NOTICE_TYPE_INFO); - - $this->assertEquals(Notice::NOTICE_TYPE_INFO, $notice->getNoticeType()); - - $notice->setNoticeType(Notice::NOTICE_TYPE_ERROR); - $this->assertEquals(Notice::NOTICE_TYPE_ERROR, $notice->getNoticeType()); - } - - public function testDismissible() - { - $notice = new Notice('test'); - - $this->assertFalse($notice->isDismissible()); - - $notice->setDismissible(true); - $this->assertTrue($notice->isDismissible()); - } - - public function testPriority() - { - $notice = new Notice('test'); - - $this->assertEquals(10, $notice->getPriority()); - - $notice->setPriority(20); - $this->assertEquals(20, $notice->getPriority()); - } - - public function testAddAttribute() - { - $notice = new Notice('test', Notice::NOTICE_TYPE_WARNING); - - $notice->addAttribute('id', 'test_id'); - - $this->expectOutputString('<div class="notice notice-warning" id="test_id"><p>test</p></div>'); - - $notice->showNotice(); - } - - public function testAddAttributeClass() - { - $notice = new Notice('test', Notice::NOTICE_TYPE_WARNING); - - $notice->addAttribute('class', 'test-class'); - - $this->expectOutputString('<div class="notice notice-warning test-class"><p>test</p></div>'); - - $notice->showNotice(); - } - -} diff --git a/tests/integration/TestPermanentDismissinleNotice.php b/tests/integration/TestPermanentDismissinleNotice.php deleted file mode 100644 index 839352078ddea011ee5bde7cbd16dd556bcfa77a..0000000000000000000000000000000000000000 --- a/tests/integration/TestPermanentDismissinleNotice.php +++ /dev/null @@ -1,58 +0,0 @@ -<?php - -use \WPDesk\Notice\PermanentDismissibleNotice; - -class TestPermanentDismissinleNotice extends WP_UnitTestCase -{ - - const NOTICE_NAME = 'test_notice_name'; - - public function testAddAction() - { - $notice_priority = 11; - - $notice = new PermanentDismissibleNotice( - 'test', - 'test_name', - PermanentDismissibleNotice::NOTICE_TYPE_INFO, - $notice_priority - ); - - $this->assertEquals($notice_priority, has_action('admin_notices', [$notice, 'showNotice'], $notice_priority)); - } - - public function testUndoDismiss() - { - update_option( - PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME, - PermanentDismissibleNotice::OPTION_VALUE_DISMISSED - ); - - $notice = new PermanentDismissibleNotice( - PermanentDismissibleNotice::NOTICE_TYPE_INFO, - self::NOTICE_NAME - ); - $notice->undoDismiss(); - - $this->assertEquals( - '', - get_option(PermanentDismissibleNotice::OPTION_NAME_PREFIX . self::NOTICE_NAME, '') - ); - } - - public function testShowNotice() - { - $notice = new PermanentDismissibleNotice( - 'test', - 'test_name', - PermanentDismissibleNotice::NOTICE_TYPE_INFO - ); - - $this->expectOutputString( - '<div class="notice notice-info is-dismissible" data-notice-name="test_name" id="wpdesk-notice-test_name"><p>test</p></div>' - ); - - $notice->showNotice(); - } - -}