diff --git a/composer.json b/composer.json index b04a148fe..abf796eaf 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ "wp-phpunit/wp-phpunit": "^5.4", "wpackagist-plugin/advanced-custom-fields": "5.8.12", "wpackagist-plugin/easy-digital-downloads": "^2.9.23", + "wpackagist-plugin/jetpack": "^8.7", "wpackagist-plugin/user-switching": "^1.5.5", "wpsh/local": "^0.2.3" }, diff --git a/composer.lock b/composer.lock index 03b357a70..f6f34358b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c025a44ff83e162076363f15803df9da", + "content-hash": "b3a66b40eacb8dece6a3c25e6dda1348", "packages": [ { "name": "composer/installers", - "version": "v1.9.0", + "version": "v1.10.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca" + "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/b93bcf0fa1fccb0b7d176b0967d969691cd74cca", - "reference": "b93bcf0fa1fccb0b7d176b0967d969691cd74cca", + "url": "https://api.github.com/repos/composer/installers/zipball/1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d", + "reference": "1a0357fccad9d1cc1ea0c9a05b8847fbccccb78d", "shasum": "" }, "require": { @@ -28,17 +28,18 @@ "shama/baton": "*" }, "require-dev": { - "composer/composer": "1.6.* || 2.0.*@dev", - "composer/semver": "1.0.* || 2.0.*@dev", - "phpunit/phpunit": "^4.8.36", - "sebastian/comparator": "^1.2.4", + "composer/composer": "1.6.* || ^2.0", + "composer/semver": "^1 || ^3", + "phpstan/phpstan": "^0.12.55", + "phpstan/phpstan-phpunit": "^0.12.16", + "symfony/phpunit-bridge": "^4.2 || ^5", "symfony/process": "^2.3" }, "type": "composer-plugin", "extra": { "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "1.x-dev" } }, "autoload": { @@ -76,6 +77,7 @@ "Porto", "RadPHP", "SMF", + "Starbug", "Thelia", "Whmcs", "WolfCMS", @@ -116,6 +118,7 @@ "phpbb", "piwik", "ppi", + "processwire", "puppet", "pxcms", "reindex", @@ -133,19 +136,23 @@ ], "support": { "issues": "https://github.com/composer/installers/issues", - "source": "https://github.com/composer/installers/tree/v1.9.0" + "source": "https://github.com/composer/installers/tree/v1.10.0" }, "funding": [ { "url": "https://packagist.com", "type": "custom" }, + { + "url": "https://github.com/composer", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/composer/composer", "type": "tidelift" } ], - "time": "2020-04-07T06:57:05+00:00" + "time": "2021-01-14T11:07:16+00:00" } ], "packages-dev": [ @@ -279,16 +286,16 @@ }, { "name": "composer/composer", - "version": "1.10.19", + "version": "1.10.20", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "196601d50c08c3fae389a417a7689367fcf37cef" + "reference": "e55d297525f0ecc805c813a0f63a40114fd670f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/196601d50c08c3fae389a417a7689367fcf37cef", - "reference": "196601d50c08c3fae389a417a7689367fcf37cef", + "url": "https://api.github.com/repos/composer/composer/zipball/e55d297525f0ecc805c813a0f63a40114fd670f6", + "reference": "e55d297525f0ecc805c813a0f63a40114fd670f6", "shasum": "" }, "require": { @@ -358,7 +365,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/1.10.19" + "source": "https://github.com/composer/composer/tree/1.10.20" }, "funding": [ { @@ -374,7 +381,7 @@ "type": "tidelift" } ], - "time": "2020-12-04T08:14:16+00:00" + "time": "2021-01-27T14:41:06+00:00" }, { "name": "composer/semver", @@ -1079,20 +1086,20 @@ }, { "name": "johnpbloch/wordpress", - "version": "5.6.0", + "version": "5.6.1", "source": { "type": "git", "url": "https://github.com/johnpbloch/wordpress.git", - "reference": "3055975734646c8d0b8caf7b5af168ced6ec4309" + "reference": "d7a597988102967cdfc28851b6b897d018613823" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/johnpbloch/wordpress/zipball/3055975734646c8d0b8caf7b5af168ced6ec4309", - "reference": "3055975734646c8d0b8caf7b5af168ced6ec4309", + "url": "https://api.github.com/repos/johnpbloch/wordpress/zipball/d7a597988102967cdfc28851b6b897d018613823", + "reference": "d7a597988102967cdfc28851b6b897d018613823", "shasum": "" }, "require": { - "johnpbloch/wordpress-core": "5.6.0", + "johnpbloch/wordpress-core": "5.6.1", "johnpbloch/wordpress-core-installer": "^1.0 || ^2.0", "php": ">=5.6.20" }, @@ -1121,20 +1128,20 @@ "source": "http://core.trac.wordpress.org/browser", "wiki": "http://codex.wordpress.org/" }, - "time": "2020-12-08T22:34:35+00:00" + "time": "2021-02-03T21:27:41+00:00" }, { "name": "johnpbloch/wordpress-core", - "version": "5.6.0", + "version": "5.6.1", "source": { "type": "git", "url": "https://github.com/johnpbloch/wordpress-core.git", - "reference": "f074617dd69f466302836d1ae5de75c0bd7b6dfd" + "reference": "82592ec73d42cf784da38adb0028a24dbacab1b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/johnpbloch/wordpress-core/zipball/f074617dd69f466302836d1ae5de75c0bd7b6dfd", - "reference": "f074617dd69f466302836d1ae5de75c0bd7b6dfd", + "url": "https://api.github.com/repos/johnpbloch/wordpress-core/zipball/82592ec73d42cf784da38adb0028a24dbacab1b4", + "reference": "82592ec73d42cf784da38adb0028a24dbacab1b4", "shasum": "" }, "require": { @@ -1142,7 +1149,7 @@ "php": ">=5.6.20" }, "provide": { - "wordpress/core-implementation": "5.6.0" + "wordpress/core-implementation": "5.6.1" }, "type": "wordpress-core", "notification-url": "https://packagist.org/downloads/", @@ -1169,7 +1176,7 @@ "source": "https://core.trac.wordpress.org/browser", "wiki": "https://codex.wordpress.org/" }, - "time": "2020-12-08T22:34:23+00:00" + "time": "2021-02-03T21:27:35+00:00" }, { "name": "johnpbloch/wordpress-core-installer", @@ -3145,16 +3152,16 @@ }, { "name": "sirbrillig/phpcs-variable-analysis", - "version": "v2.10.1", + "version": "v2.10.2", "source": { "type": "git", "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", - "reference": "c6716a98fe7bee25d31306e14fb62c3ffa16d70a" + "reference": "0775e0c683badad52c03b11c2cd86a9fdecb937a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/c6716a98fe7bee25d31306e14fb62c3ffa16d70a", - "reference": "c6716a98fe7bee25d31306e14fb62c3ffa16d70a", + "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/0775e0c683badad52c03b11c2cd86a9fdecb937a", + "reference": "0775e0c683badad52c03b11c2cd86a9fdecb937a", "shasum": "" }, "require": { @@ -3194,7 +3201,7 @@ "source": "https://github.com/sirbrillig/phpcs-variable-analysis", "wiki": "https://github.com/sirbrillig/phpcs-variable-analysis/wiki" }, - "time": "2020-12-12T18:28:57+00:00" + "time": "2021-01-08T16:31:05+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -4288,12 +4295,12 @@ "version": "1.9.1", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", + "url": "https://github.com/webmozarts/assert.git", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", "shasum": "" }, @@ -4331,8 +4338,8 @@ "validate" ], "support": { - "issues": "https://github.com/webmozart/assert/issues", - "source": "https://github.com/webmozart/assert/tree/master" + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.9.1" }, "time": "2020-07-08T17:02:28+00:00" }, @@ -6476,16 +6483,16 @@ }, { "name": "wp-phpunit/wp-phpunit", - "version": "5.6.0", + "version": "5.6.1", "source": { "type": "git", "url": "https://github.com/wp-phpunit/wp-phpunit.git", - "reference": "7130a214573cc8c12a0f8fe8a74b18b453bce1e9" + "reference": "f6b3fb65bccc0ff70b3bc7cc241935597dbd5562" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/7130a214573cc8c12a0f8fe8a74b18b453bce1e9", - "reference": "7130a214573cc8c12a0f8fe8a74b18b453bce1e9", + "url": "https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/f6b3fb65bccc0ff70b3bc7cc241935597dbd5562", + "reference": "f6b3fb65bccc0ff70b3bc7cc241935597dbd5562", "shasum": "" }, "type": "library", @@ -6520,7 +6527,7 @@ "issues": "https://github.com/wp-phpunit/issues", "source": "https://github.com/wp-phpunit/wp-phpunit" }, - "time": "2020-12-09T18:06:02+00:00" + "time": "2021-02-04T18:24:14+00:00" }, { "name": "wpackagist-plugin/advanced-custom-fields", @@ -6558,6 +6565,24 @@ "type": "wordpress-plugin", "homepage": "https://wordpress.org/plugins/easy-digital-downloads/" }, + { + "name": "wpackagist-plugin/jetpack", + "version": "8.9.1", + "source": { + "type": "svn", + "url": "https://plugins.svn.wordpress.org/jetpack/", + "reference": "tags/8.9.1" + }, + "dist": { + "type": "zip", + "url": "https://downloads.wordpress.org/plugin/jetpack.8.9.1.zip" + }, + "require": { + "composer/installers": "~1.0" + }, + "type": "wordpress-plugin", + "homepage": "https://wordpress.org/plugins/jetpack/" + }, { "name": "wpackagist-plugin/user-switching", "version": "1.5.6", diff --git a/connectors/class-connector-jetpack.php b/connectors/class-connector-jetpack.php index 34f353748..eaa6a5842 100644 --- a/connectors/class-connector-jetpack.php +++ b/connectors/class-connector-jetpack.php @@ -318,11 +318,16 @@ public function register() { 'label' => esc_html__( 'Tiled Galleries', 'stream' ), 'context' => 'tiled-gallery', ), + // Monitor. + 'monitor_receive_notification' => array( + 'label' => esc_html__( 'Monitor notifications', 'stream' ), + 'context' => 'monitor', + ), ); } /** - * Track Jetpack log entries + * Tracks logs add to Jetpack logging. * Includes: * - Activation/Deactivation of modules * - Registration/Disconnection of blogs @@ -374,11 +379,10 @@ public function callback_jetpack_log_entry( array $entry ) { $action = $method; $meta = compact( 'user_id', 'user_email', 'user_login' ); $message = sprintf( - /* translators: %1$s: a user display name, %2$s: a status, %3$s: the connection either "from" or "to" (e.g. "Jane Doe", "unlinked", "from") */ - __( '%1$s\'s account %2$s %3$s Jetpack', 'stream' ), + /* translators: %1$s: a user display name, %2$s: a status and the connection either "from" or "to" (e.g. "Jane Doe", "unlinked from") */ + __( '%1$s\'s account %2$s Jetpack', 'stream' ), $user->display_name, - ( 'unlink' === $action ) ? esc_html__( 'unlinked', 'stream' ) : esc_html__( 'linked', 'stream' ), - ( 'unlink' === $action ) ? esc_html__( 'from', 'stream' ) : esc_html__( 'to', 'stream' ) + ( 'unlink' === $action ) ? esc_html__( 'unlinked from', 'stream' ) : esc_html__( 'linked to', 'stream' ) ); } elseif ( in_array( $method, array( 'register', 'disconnect', 'subsiteregister', 'subsitedisconnect' ), true ) ) { $context = 'blogs'; diff --git a/local/config/wp-config.php b/local/config/wp-config.php index 4fae56c6a..0fbb56627 100644 --- a/local/config/wp-config.php +++ b/local/config/wp-config.php @@ -23,7 +23,8 @@ $table_prefix = 'wptests_'; -define( 'WP_DEBUG', false ); +define( 'WP_DEBUG', true ); +define( 'JETPACK_DEV_DEBUG', true ); define( 'ABSPATH', __DIR__ . '/' ); diff --git a/phpunit.xml b/phpunit.xml index af2b1c44b..f37a7bf54 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -10,7 +10,7 @@ diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 3c9110625..06b12bd93 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -51,15 +51,20 @@ function() { } ); +/** + * Manually loads Mercator for testing. + */ function xwp_manually_load_mercator() { define( 'MERCATOR_SKIP_CHECKS', true ); require WPMU_PLUGIN_DIR . '/mercator/mercator.php'; } - tests_add_filter( 'muplugins_loaded', 'xwp_manually_load_mercator' ); +/** + * Manually creates EDD's database tables, users, and settings for testing. + */ function xwp_install_edd() { - // Install Easy Digital Downloads + edd_install(); global $current_user, $edd_options; @@ -79,6 +84,9 @@ function( $status = false, $args = array(), $url = '') { ); } +// Run Jetpack in offline mode for testing. +tests_add_filter( 'jetpack_offline_mode', '__return_true' ); + // @see https://core.trac.wordpress.org/browser/trunk/tests/phpunit/includes/bootstrap.php require $_tests_dir . '/includes/bootstrap.php'; diff --git a/tests/tests/connectors/test-class-connector-jetpack.php b/tests/tests/connectors/test-class-connector-jetpack.php new file mode 100644 index 000000000..c42ab9282 --- /dev/null +++ b/tests/tests/connectors/test-class-connector-jetpack.php @@ -0,0 +1,305 @@ +server = $wp_rest_server = new \WP_REST_Server; + do_action( 'rest_api_init' ); + + // Make partial of Connector_Installer class, with mocked "log" function. + $this->mock = $this->getMockBuilder( Connector_Jetpack::class ) + ->setMethods( array( 'log' ) ) + ->getMock(); + + // Register connector. + $this->mock->register(); + } + + public function test_jetpack_installed_and_activated() { + $this->assertTrue( class_exists( 'Jetpack', 'Jetpack is inactive' ) ); + } + + public function test_callback_jetpack_log_entry() { + // Get blog details and create user for later use. + $user_id = self::factory()->user->create( array( 'display_name' => 'testuser' ) ); + $user = new \WP_User( $user_id ); + + // Expected log calls. + $this->mock->expects( $this->exactly( 3 ) ) + ->method( 'log' ) + ->withConsecutive( + array( + 'Comments module activated', + array( 'module_slug' => 'comments'), + null, + 'modules', + 'activated', + ), + array( + 'testuser\'s account linked to Jetpack', + array( + 'user_id' => $user_id, + 'user_email' => $user->user_email, + 'user_login' => $user->user_login, + ), + null, + 'users', + 'authorize', + ), + array( + 'Site connected to Jetpack', + array(), + null, + 'blogs', + 'register' + ) + ); + + // Run Jetpack log function to trigger callback. + \Jetpack::log( 'activate', 'comments' ); + \Jetpack::log( 'authorize', $user_id ); + \Jetpack::log( 'register' ); + + // Check callback test action. + $this->assertFalse( 0 === did_action( $this->action_prefix . 'callback_jetpack_log_entry' ) ); + } + + public function test_callback_sharing_get_services_state() { + // Create sharing service instance and services object for later use. + require_once JETPACK__PLUGIN_DIR. 'modules/sharedaddy/sharing-service.php'; + $sharer = new \Sharing_Service(); + $services = $sharer->get_all_services(); + + // Expected log calls. + $this->mock->expects( $this->exactly( 1 ) ) + ->method( 'log' ) + ->withConsecutive( + array( + $this->equalTo( __( 'Sharing services updated', 'stream' ) ), + $this->equalTo( + array( + 'services' => $services, + 'available' => array_keys( $services ), + 'hidden' => array(), + 'visible' => array(), + 'currently_enabled' => $sharer->get_blog_services(), + ) + ), + $this->equalTo( null ), + $this->equalTo( 'sharedaddy' ), + $this->equalTo( 'updated' ) + ) + ); + + // Update sharing services to trigger callback. + $sharer->set_blog_services( + array( 'facebook' => 'Share_Facebook' ), + array( 'reddit' => 'Share_Reddit' ) + ); + + // Check callback test action. + $this->assertFalse( 0 === did_action( $this->action_prefix . 'callback_sharing_get_services_state' ) ); + } + + public function test_callback_jetpack_module_configuration_load_monitor() { + // Prepare scenario + + // Expected log calls. + $this->mock->expects( $this->once() ) + ->method( 'log' ) + ->with( + $this->equalTo( __( 'Monitor notifications %s', 'stream' ) ), + $this->equalTo( + array( + 'status' => esc_html__( 'activated', 'stream' ), + 'option' => 'receive_jetpack_monitor_notification', + 'old_value' => false, + 'value' => true, + ) + ), + $this->equalTo( null ), + $this->equalTo( 'monitor' ), + $this->equalTo( 'updated' ) + ); + + // Simulate "receive_jetpack_monitor_notification" option change to trigger callback. + $_POST['receive_jetpack_monitor_notification'] = true; + do_action( 'jetpack_module_configuration_load_monitor' ); + + // Check callback test action. + $this->assertFalse( 0 === did_action( $this->action_prefix . 'callback_jetpack_module_configuration_load_monitor' ) ); + } + + public function test_check() { + // Prepare scenario + $admin_id = self::factory()->user->create( array( 'role' => 'administrator' ) ); + wp_set_current_user( $admin_id ); + + // Expected log calls. + $this->mock->expects( $this->exactly( 2 ) ) + ->method( 'log' ) + ->withConsecutive( + array( + $this->equalTo( __( '"%s" setting updated', 'stream' ) ), + $this->equalTo( + array( + 'option_title' => esc_html__( 'Sharing options', 'stream' ), + 'option' => 'sharing-options', + 'old_value' => null, + 'new_value' => array( + 'global' => array( + 'button_style' => 'icon-text', + 'sharing_label' => 'Share this:', + 'open_links' => 'same', + 'show' => array( 'post', 'page' ), + 'custom' => array(), + ), + ), + ) + ), + $this->equalTo( null ), + $this->equalTo( 'sharedaddy' ), + $this->equalTo( 'updated' ), + ), + array( + $this->equalTo( __( '"%s" setting updated', 'stream' ) ), + $this->equalTo( + array( + 'option_title' => esc_html__( 'Sharing options', 'stream' ), + 'option' => 'sharing-options', + 'old_value' => array( + 'global' => array( + 'button_style' => 'icon-text', + 'sharing_label' => 'Share this:', + 'open_links' => 'same', + 'show' => array( 'post', 'page' ), + 'custom' => array(), + ), + ), + 'new_value' => array( + 'global' => array( + 'button_style' => 'icon-text', + 'sharing_label' => 'Share what', + 'open_links' => 'same', + 'show' => array( 'post', 'page' ), + 'custom' => array(), + ), + ), + ) + ), + $this->equalTo( null ), + $this->equalTo( 'sharedaddy' ), + $this->equalTo( 'updated' ), + ) + ); + + // Test Jetpack REST route. + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( $this->namespaced_route, $routes ); + + // Execute REST requests and trigger callbacks. + $request = new \WP_Rest_Request( 'POST', "{$this->namespaced_route}/settings" ); + $request->set_body_params( + array( + 'carousel' => true, + 'carousel_background_color' => 'white', + 'sharedaddy' => true, + 'sharing_label' => 'Share what' + ) + ); + $response = $this->server->dispatch( $request ); + $this->assertEquals( 200, $response->get_status() ); + + // Check callback test action. + $this->assertFalse( 0 === did_action( $this->action_prefix . 'callback_add_option' ) ); + $this->assertFalse( 0 === did_action( $this->action_prefix . 'callback_update_option' ) ); + } + + public function test_track_post_by_email() { + // Prepare scenario + $admin_id = self::factory()->user->create( + array( + 'role' => 'administrator', + 'display_name' => 'TestGuy', + ) + ); + wp_set_current_user( $admin_id ); + + // Expected log calls. + $this->mock->expects( $this->exactly( 3 ) ) + ->method( 'log' ) + ->withConsecutive( + array( + $this->equalTo( __( '%1$s %2$s Post by Email', 'stream' ) ), + $this->equalTo( + array( + 'user_displayname' => 'TestGuy', + 'action' => esc_html__( 'enabled', 'stream' ), + 'status' => true, + ) + ), + $this->equalTo( null ), + $this->equalTo( 'post-by-email' ), + $this->equalTo( 'updated' ), + ), + array( + $this->equalTo( __( '%1$s %2$s Post by Email', 'stream' ) ), + $this->equalTo( + array( + 'user_displayname' => 'TestGuy', + 'action' => esc_html__( 'disabled', 'stream' ), + 'status' => false, + ) + ), + $this->equalTo( null ), + $this->equalTo( 'post-by-email' ), + $this->equalTo( 'updated' ), + ), + array( + $this->equalTo( __( '%1$s %2$s Post by Email', 'stream' ) ), + $this->equalTo( + array( + 'user_displayname' => 'TestGuy', + 'action' => esc_html__( 'regenerated', 'stream' ), + 'status' => null, + ) + ), + $this->equalTo( null ), + $this->equalTo( 'post-by-email' ), + $this->equalTo( 'updated' ), + ) + ); + + // Test Jetpack REST route. + $routes = $this->server->get_routes(); + $this->assertArrayHasKey( $this->namespaced_route, $routes ); + + // Manually trigger callbacks. + do_action( 'wp_ajax_jetpack_post_by_email_enable' ); + do_action( 'wp_ajax_jetpack_post_by_email_disable' ); + do_action( 'wp_ajax_jetpack_post_by_email_regenerate' ); + + // Check callback test action. + $this->assertFalse( 0 === did_action( $this->action_prefix . 'callback_wp_ajax_jetpack_post_by_email_enable' ) ); + $this->assertFalse( 0 === did_action( $this->action_prefix . 'callback_wp_ajax_jetpack_post_by_email_regenerate' ) ); + $this->assertFalse( 0 === did_action( $this->action_prefix . 'callback_wp_ajax_jetpack_post_by_email_disable' ) ); + } +}