diff --git a/inc/Engine/Optimization/RUCSS/Admin/Subscriber.php b/inc/Engine/Optimization/RUCSS/Admin/Subscriber.php index 561268c933..7f69019fc1 100644 --- a/inc/Engine/Optimization/RUCSS/Admin/Subscriber.php +++ b/inc/Engine/Optimization/RUCSS/Admin/Subscriber.php @@ -69,7 +69,6 @@ public static function get_subscribed_events() : array { 'rocket_input_sanitize' => [ 'sanitize_options', 14, 2 ], 'update_option_' . $slug => [ [ 'clean_used_css_and_cache', 9, 2 ], - [ 'clean_used_css_with_cdn', 9, 2 ], [ 'maybe_set_processing_transient', 50, 2 ], ], 'switch_theme' => 'truncate_used_css', @@ -326,40 +325,6 @@ public function clean_used_css_and_cache( $old_value, $value ) { $this->set_notice_transient(); } - /** - * Truncate UsedCSS DB Table when CDN option is changed. - * - * @since 3.11 - * - * @param array $old_value An array of submitted values for the settings. - * @param array $value An array of previous values for the settings. - * - * @return void - */ - public function clean_used_css_with_cdn( $old_value, $value ) { - if ( ! isset( $value['cdn'], $old_value['cdn'] ) ) { - return; - } - - if ( empty( $value['remove_unused_css'] ) ) { - return; - } - - if ( - $value['cdn'] === $old_value['cdn'] - && - $value['cdn_cnames'] === $old_value['cdn_cnames'] - && - $value['cdn_zone'] === $old_value['cdn_zone'] - ) { - return; - } - - $this->delete_used_css_rows(); - - $this->set_notice_transient(); - } - /** * Truncate used_css table when clicking on the dashboard button. * diff --git a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php index 3b8369d5b3..19dcc4988f 100644 --- a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php +++ b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php @@ -391,7 +391,16 @@ private function add_used_css_to_html( string $html, UsedCSS_Row $used_css ): st * @return string */ private function get_used_css_markup( UsedCSS_Row $used_css ): string { - $css = str_replace( '\\', '\\\\', $used_css->css );// Guard the backslashes before passing the content to preg_replace. + /** + * Filters Used CSS content before saving into DB. + * + * @since 3.9.0.2 + * + * @param string $usedcss Used CSS. + */ + $css = apply_filters( 'rocket_usedcss_content', $used_css->css ); + + $css = str_replace( '\\', '\\\\', $css );// Guard the backslashes before passing the content to preg_replace. $used_css_contents = $this->handle_charsets( $css, false ); return sprintf( '', @@ -517,15 +526,6 @@ public function check_job_status( int $id ) { $css = $this->apply_font_display_swap( $job_details['contents']['shakedCSS'] ); - /** - * Filters Used CSS content before saving into DB. - * - * @since 3.9.0.2 - * - * @param string $usedcss Used CSS. - */ - $css = apply_filters( 'rocket_usedcss_content', $css ); - $this->used_css_query->make_status_completed( $id, $css ); do_action( 'rocket_rucss_complete_job_status', $row_details->url, $job_details ); diff --git a/tests/Fixtures/WP.php b/tests/Fixtures/WP.php new file mode 100644 index 0000000000..c3a087b05c --- /dev/null +++ b/tests/Fixtures/WP.php @@ -0,0 +1,6 @@ + 'http://example.org/home', - 'css' => 'h1{color:red;}', - 'unprocessedcss' => json_encode( [] ), - 'retries' => 3, - 'is_mobile' => false, - ], - [ - 'url' => 'http://example.org/home', - 'css' => 'h1{color:red;}', - 'unprocessedcss' => json_encode( [] ), - 'retries' => 3, - 'is_mobile' => true, - ], -]; - -return [ - - // Test data. - 'test_data' => [ - 'shouldNotTruncateUnusedCSSDueToMissingSettings' => [ - 'input' => [ - 'items' => $items, - 'settings' => [], - 'old_settings' => [], - ], - 'expected' => [ - 'truncated' => false, - ], - ], - 'shouldNotTruncateUnusedCSSDueToSettings' => [ - 'input' => [ - 'items' => $items, - 'settings' => [ - 'remove_unused_css' => 0, - 'cdn' => 0, - ], - 'old_settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 1, - ], - ], - 'expected' => [ - 'truncated' => false, - ], - ], - 'shouldTruncateUnusedCSSWhenCDNChanges' => [ - 'input' => [ - 'items' => $items, - 'settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 0, - ], - 'old_settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 1, - ], - ], - 'expected' => [ - 'truncated' => true, - 'not_completed_count' => 0, - ], - ], - 'shouldTruncateUnusedCSSWhenCNamesChanges' => [ - 'input' => [ - 'items' => $items, - 'settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 1, - 'cdn_cnames' => [ - 'cdn.example.org' - ], - ], - 'old_settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 1, - 'cdn_cnames' => [ - 'cdn2.example.org' - ], - ], - ], - 'expected' => [ - 'truncated' => true, - 'not_completed_count' => 0, - ], - ], - - 'shouldTruncateUnusedCSSWhenZonesChanges' => [ - 'input' => [ - 'items' => $items, - 'settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 1, - 'cdn_cnames' => [ - 'cdn.example.org' - ], - 'cdn_zone' => [ - 'all' - ], - ], - 'old_settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 1, - 'cdn_cnames' => [ - 'cdn.example.org' - ], - 'cdn_zone' => [ - 'css' - ], - ], - ], - 'expected' => [ - 'truncated' => true, - 'not_completed_count' => 0, - ], - ], - - 'shouldDeleteCompletedUnusedCSS' => [ - 'input' => [ - 'items' => $items, - 'settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 0, - ], - 'old_settings' => [ - 'remove_unused_css' => 1, - 'cdn' => 1, - ], - ], - 'expected' => [ - 'truncated' => true, - 'not_completed_count' => 10, - ], - ], - ], -]; diff --git a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtred.php b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtred.php new file mode 100644 index 0000000000..a9806464fb --- /dev/null +++ b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtred.php @@ -0,0 +1,8 @@ + + + Test + + + + + diff --git a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php new file mode 100644 index 0000000000..cf021c015c --- /dev/null +++ b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php @@ -0,0 +1,10 @@ + + + Test + + + + + + + diff --git a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php new file mode 100644 index 0000000000..b5b25a780e --- /dev/null +++ b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php @@ -0,0 +1,138 @@ + [ + 'config' => [ + 'home_url' => 'http://example.com', + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + 'is_allowed' => false, + ], + 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + + ], + 'expectFetchCssWithQueueAndReturnSameWhenEmptyUsedCss' => [ + 'config' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + 'is_allowed' => true, + 'home_url' => 'http://example.com', + 'is_mobile' => [ + 'has_mobile_cache' => false, + 'is_caching_mobile_files' => false, + 'is_mobile' => false, + ], + 'get_existing_used_css' => [ + 'used_css' => null + ], + 'create_new_job' => [ + 'safelist' => [], + 'config' => [ + 'treeshake' => 1, + 'rucss_safelist' => [], + 'is_mobile' => false, + 'is_home' => true, + ], + 'is_success_response' => true, + 'response' => [ + 'code' => 200, + 'contents' => [ + 'jobId' => 'id', + 'queueName' => 'name', + ] + ] + ] + ], + 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + ], + 'expectFetchCssWithJobAndReturnSameWhenEmptyUsedCssAndQueueFailed' => [ + 'config' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + 'is_allowed' => true, + 'home_url' => 'http://example.com', + 'is_mobile' => [ + 'has_mobile_cache' => true, + 'is_caching_mobile_files' => true, + 'is_mobile' => true, + ], + 'get_existing_used_css' => [ + 'used_css' => null + ], + 'create_new_job' => [ + 'safelist' => [], + 'config' => [ + 'treeshake' => 1, + 'rucss_safelist' => [], + 'is_mobile' => true, + 'is_home' => true, + ], + 'response' => [ + 'code' => 400, + 'message' => 'message', + ] + ] + ], + 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + ], + 'expectedSameHTMlWhenNoEmptyUsedCSSAndWrongStatus' => [ + 'config' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + 'is_allowed' => true, + 'home_url' => 'http://example.com', + 'is_mobile' => [ + 'has_mobile_cache' => true, + 'is_caching_mobile_files' => true, + 'is_mobile' => true, + ], + 'get_existing_used_css' => [ + 'used_css' => (object) [ + 'status' => 'failed', + 'id' => 'id', + 'css' => '', + ] + ], + ], + 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + ], + 'expectedSameHTMlWhenNoEmptyUsedCSSAndEmptyCSS' => [ + 'config' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + 'is_allowed' => true, + 'home_url' => 'http://example.com', + 'is_mobile' => [ + 'has_mobile_cache' => true, + 'is_caching_mobile_files' => true, + 'is_mobile' => true, + ], + 'get_existing_used_css' => [ + 'used_css' => (object) [ + 'status' => 'completed', + 'css' => '', + 'id' => 'id', + ] + ], + ], + 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + ], + 'expectedFilteredHTMlWhenNoEmptyUsedCSS' => [ + 'config' => [ + 'is_allowed' => true, + 'home_url' => 'http://example.com', + 'is_mobile' => [ + 'has_mobile_cache' => true, + 'is_caching_mobile_files' => true, + 'is_mobile' => true, + ], + 'get_existing_used_css' => [ + 'used_css' => (object) [ + 'status' => 'completed', + 'css' => 'h1{color:red;}', + 'id' => 'id', + ] + ], + 'apply_used_css' => [ + 'test' + ], + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), + ], + 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtred.php'), + ] +]; diff --git a/tests/Integration/inc/Engine/Optimization/RUCSS/Admin/Subscriber/cleanUsedCssWithCDN.php b/tests/Integration/inc/Engine/Optimization/RUCSS/Admin/Subscriber/cleanUsedCssWithCDN.php deleted file mode 100644 index 8c38a0daf1..0000000000 --- a/tests/Integration/inc/Engine/Optimization/RUCSS/Admin/Subscriber/cleanUsedCssWithCDN.php +++ /dev/null @@ -1,58 +0,0 @@ -get( 'rucss_used_css_query' ); - - $this->input = $input; - - foreach ( $input['items'] as $item ) { - $rucss_usedcss_query->add_item( $item ); - } - $result = $rucss_usedcss_query->query(); - - $this->assertCount( count( $input['items'] ), $result ); - - do_action( 'update_option_wp_rocket_settings', $input['settings'], $input['old_settings'] ); - - $rucss_usedcss_query = $container->get( 'rucss_used_css_query' ); - $resultAfterTruncate = $rucss_usedcss_query->query(); - - if ( $expected['truncated'] ) { - $this->assertCount( 0, $resultAfterTruncate ); - } else { - $this->assertCount( count( $input['items'] ), $result ); - } - } -} diff --git a/tests/Unit/bootstrap.php b/tests/Unit/bootstrap.php index f0a3a009ba..14983c3bd1 100644 --- a/tests/Unit/bootstrap.php +++ b/tests/Unit/bootstrap.php @@ -34,6 +34,7 @@ function load_original_files_before_mocking() { $fixtures = [ '/WP_Error.php', + '/WP.php', '/WP_Theme.php', '/WPDieException.php', ]; diff --git a/tests/Unit/inc/Engine/Optimization/RUCSS/Admin/Subscriber/cleanUsedCssWithCDN.php b/tests/Unit/inc/Engine/Optimization/RUCSS/Admin/Subscriber/cleanUsedCssWithCDN.php deleted file mode 100644 index 9cf7cdf559..0000000000 --- a/tests/Unit/inc/Engine/Optimization/RUCSS/Admin/Subscriber/cleanUsedCssWithCDN.php +++ /dev/null @@ -1,75 +0,0 @@ -settings = Mockery::mock( Settings::class ); - $this->database = Mockery::mock( Database::class ); - $this->usedCSS = Mockery::mock( UsedCSS::class ); - $this->subscriber = new Subscriber( $this->settings, $this->database, $this->usedCSS, Mockery::mock( Queue::class ) ); - } - - /** - * @dataProvider configTestData - */ - public function testShouldDoExpected( $input, $expected ) { - if ( $expected['truncated'] ) { - $this->usedCSS->shouldReceive( 'get_not_completed_count' )->once()->andReturn( $expected['not_completed_count'] ); - - if ( $expected['not_completed_count'] > 0 ) { - $this->usedCSS->shouldReceive( 'remove_all_completed_rows' )->once(); - } else { - $this->database->shouldReceive( 'truncate_used_css_table' )->once(); - } - - Functions\expect( 'set_transient' ) - ->once() - ->with( - 'rocket_rucss_processing', - Mockery::type( 'int' ), - 90 - ); - - Functions\expect( 'rocket_renew_box' ) - ->once() - ->with( 'rucss_success_notice' ); - } else { - $this->database - ->shouldReceive( 'truncate_used_css_table' ) - ->never(); - - Functions\expect( 'set_transient' ) - ->never(); - } - - $this->subscriber->clean_used_css_with_cdn( $input['old_settings'], $input['settings'] ); - } -} diff --git a/tests/Unit/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php b/tests/Unit/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php new file mode 100644 index 0000000000..7056d8b82c --- /dev/null +++ b/tests/Unit/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php @@ -0,0 +1,155 @@ +options = Mockery::mock(Options_Data::class); + // fix a bug from mockery with __isset function + error_reporting(E_ALL ^ E_WARNING); + $this->usedCssQuery = Mockery::mock(UsedCSS_Query::class); + $this->resourcesQuery = Mockery::mock(ResourcesQuery::class); + $this->api = Mockery::mock(APIClient::class); + $this->queue = Mockery::mock(QueueInterface::class); + $this->usedCss = Mockery::mock(UsedCSS::class . '[is_allowed,update_last_accessed]', [$this->options, $this->usedCssQuery, + $this->resourcesQuery, + $this->api, + $this->queue]); + } + + protected function tearDown(): void + { + error_reporting(E_ALL); + parent::tearDown(); + } + + /** + * @dataProvider configTestData + */ + public function testShouldReturnAsExpected($config, $expected) { + Logger::disable_debug(); + $wp = new WP(); + $GLOBALS['wp'] = $wp; + + Functions\expect( 'home_url' ) + ->with() + ->zeroOrMoreTimes() + ->andReturn( $config['home_url'] ); + + $this->usedCss->expects()->is_allowed()->andReturn($config['is_allowed']); + + $this->configureIsMobile($config); + + $this->configureGetExistingUsedCss($config); + + $this->configureCreateNewJob($config); + + $this->configValidUsedCss($config); + + $this->configApplyUsedCss($config); + + $this->assertEquals($this->format_the_html($expected), $this->format_the_html($this->usedCss->treeshake($config['html']))); + } + + protected function configureIsMobile($config) { + if(! key_exists('is_mobile', $config)) { + return; + } + + $this->options->expects()->get('cache_mobile', 0)->andReturn($config['is_mobile']['has_mobile_cache']); + + if(! $config['is_mobile']['has_mobile_cache']) { + return; + } + + $this->options->expects()->get('do_caching_mobile_files', 0)->andReturn($config['is_mobile']['is_caching_mobile_files']); + + if(! $config['is_mobile']['is_caching_mobile_files']) { + return; + } + + Functions\expect( 'wp_is_mobile' ) + ->with() + ->once() + ->andReturn( $config['is_mobile']['is_mobile'] ); + } + + protected function configureGetExistingUsedCss($config) { + + if(! key_exists('get_existing_used_css', $config)) { + return; + } + + Functions\expect( 'add_query_arg' ) + ->with( [], $config['home_url'] ) + ->once() + ->andReturn( $config['home_url'] ); + + if($config['get_existing_used_css']['used_css']) { + $usedCssRow = Mockery::mock(UsedCSS_Row::class); + $usedCssRow->status = $config['get_existing_used_css']['used_css']->status; + $usedCssRow->css = $config['get_existing_used_css']['used_css']->css; + $usedCssRow->id = $config['get_existing_used_css']['used_css']->id; + } else { + $usedCssRow = null; + } + + $this->usedCssQuery->expects()->get_row($config['home_url'], $config['is_mobile']['is_mobile'])->andReturn($usedCssRow); + + } + + protected function configureCreateNewJob($config) { + if(!key_exists('create_new_job', $config) || !$config['create_new_job']) { + return; + } + + $this->options->expects()->get('remove_unused_css_safelist', [])->andReturn($config['create_new_job']['safelist']); + + Brain\Monkey\Filters\expectApplied('rocket_rucss_safelist')->with($config['create_new_job']['safelist'])->andReturn($config['create_new_job']['safelist']); + + $this->api->expects()->add_to_queue($config['home_url'], $config['create_new_job']['config'])->andReturn + ($config['create_new_job']['response']); + if(! key_exists('is_success_response', $config['create_new_job']) || ! $config['create_new_job']['is_success_response']){ + return; + } + + $this->usedCssQuery->expects()->create_new_job($config['home_url'], $config['create_new_job']['response']['contents']['jobId'], + $config['create_new_job']['response']['contents']['queueName'], $config['is_mobile']['is_mobile'] ); + } + + protected function configValidUsedCss($config) { + if(! key_exists('valid_used_css', $config)) { + return; + } + } + + protected function configApplyUsedCss($config) { + if(! key_exists('apply_used_css', $config)) { + return; + } + + $this->usedCssQuery->expects()->update_last_accessed($config['get_existing_used_css']['used_css']->id); + } +}