Skip to content

Commit

Permalink
Merge pull request #338 from GoogleChromeLabs/add/default-network-fir…
Browse files Browse the repository at this point in the history
…st-caching-strategy-and-args

Add default caching strategies for navigations and page assets
  • Loading branch information
westonruter authored Dec 7, 2020
2 parents f7f4cfb + 5e69c71 commit 7c63ceb
Show file tree
Hide file tree
Showing 23 changed files with 1,599 additions and 246 deletions.
13 changes: 6 additions & 7 deletions pwa.php
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,6 @@ function _pwa_check_disabled_navigation_preload() {
/** WP_HTTPS_UI Class */
require_once PWA_PLUGIN_DIR . '/wp-includes/class-wp-https-ui.php';

/** WP_Service_Worker_Registry Interface */
require_once PWA_PLUGIN_DIR . '/wp-includes/interface-wp-service-worker-registry.php';

/** WP_Service_Worker_Registry_Aware Interface */
require_once PWA_PLUGIN_DIR . '/wp-includes/interface-wp-service-worker-registry-aware.php';

/** WP_Service_Workers Class */
require_once PWA_PLUGIN_DIR . '/wp-includes/class-wp-service-workers.php';

Expand All @@ -215,6 +209,10 @@ function _pwa_check_disabled_navigation_preload() {
/** WP_Service_Worker_Component Implementation Classes */
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-configuration-component.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-navigation-routing-component.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-core-asset-caching-component.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-theme-asset-caching-component.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-plugin-asset-caching-component.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-uploaded-image-caching-component.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-precaching-routes-component.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-precaching-routes.php';
require_once PWA_PLUGIN_DIR . '/wp-includes/components/class-wp-service-worker-caching-routes-component.php';
Expand Down Expand Up @@ -265,9 +263,10 @@ function _pwa_activate_plugin() {

/**
* Plugin deactivation hook.
*
* @global WP_Rewrite $wp_rewrite WordPress rewrite component.
*/
function _pwa_deactivate_plugin() {
/* @var WP_Rewrite $wp_rewrite */
global $wp_rewrite;
unset( $wp_rewrite->extra_rules_top['^wp\.serviceworker$'] );
flush_rewrite_rules( false );
Expand Down
212 changes: 185 additions & 27 deletions tests/components/test-class-wp-service-worker-caching-routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

/**
* Tests for class WP_Service_Worker_Caching_Routes.
*
* @coversDefaultClass WP_Service_Worker_Caching_Routes
*/
class Test_WP_Service_Worker_Caching_Routes extends WP_UnitTestCase {

Expand All @@ -31,30 +33,26 @@ public function setUp() {
/**
* Test registering a route.
*
* @param string $route Route.
* @param array $args Route arguments.
* @param string $route Route.
* @param array $args Route arguments.
* @param array $expected Expected registered route.
*
* @dataProvider data_register
* @covers WP_Service_Worker_Caching_Routes::register()
* @covers ::register()
* @covers ::get_all()
*/
public function test_register( $route, $args ) {
public function test_register( $route, $args, $expected = null ) {
$this->instance->register( $route, $args );

$routes = $this->instance->get_all();
$this->assertNotEmpty( $routes );

$strategy = '';
if ( isset( $args['strategy'] ) ) {
$strategy = $args['strategy'];
unset( $args['strategy'] );
if ( ! isset( $expected ) ) {
$expected = array_merge( compact( 'route' ), $args );
}

$this->assertEqualSetsWithIndex(
array(
'route' => $route,
'strategy' => $strategy,
'strategy_args' => $args,
),
$expected,
array_pop( $routes )
);
}
Expand All @@ -66,57 +64,186 @@ public function test_register( $route, $args ) {
*/
public function data_register() {
return array(
array(
'/\.(?:js|css)$/',
'js_or_css' => array(
'\.(?:js|css)$',
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_STALE_WHILE_REVALIDATE,
'cacheName' => 'static-resources',
),
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_STALE_WHILE_REVALIDATE,
'cache_name' => 'static-resources',
'route' => '\.(?:js|css)$',
),
),
array(
'/\.(?:png|gif|jpg|jpeg|svg)$/',
'images' => array(
'\.(?:png|gif|jpg|jpeg|svg)$',
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_FIRST,
'cacheName' => 'images',
),
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_FIRST,
'cache_name' => 'images',
'route' => '\.(?:png|gif|jpg|jpeg|svg)$',
),
),
array(
'firebase' => array(
'https://hacker-news.firebaseio.com/v0/*',
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_NETWORK_FIRST,
'networkTimeoutSeconds' => 3,
'cacheName' => 'stories',
),
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_NETWORK_FIRST,
'network_timeout_seconds' => 3,
'cache_name' => 'stories',
'route' => 'https://hacker-news.firebaseio.com/v0/*',
),
),
array(
'/.*(?:googleapis)\.com.*$/',
'googleapis' => array(
'.*(?:googleapis)\.com.*$',
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_NETWORK_ONLY,
),
),
array(
'/.*(?:gstatic)\.com.*$/',
'gstatic_1' => array(
'.*(?:gstatic)\.com.*$',
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_ONLY,
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_ONLY,
'expiration' => array(
'maxAgeSeconds' => 3,
),
'broadcastUpdate' => array(),
'cacheableResponse' => array(),
),
array(
'route' => '.*(?:gstatic)\.com.*$',
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_ONLY,
'expiration' => array(
'max_age_seconds' => 3,
),
'broadcast_update' => array(),
'cacheable_response' => array(),
),
),
'empty_plugin_configs' => array(
'.*(?:gstatic)\.com.*$',
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_ONLY,
'expiration' => array(
'maxAgeSeconds' => 3,
),
'broadcastUpdate' => null,
'cacheableResponse' => false,
),
array(
'route' => '.*(?:gstatic)\.com.*$',
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_ONLY,
'expiration' => array(
'max_age_seconds' => 3,
),
),
),
);
}

/**
* Test registering with plugins key.
*
* @covers ::register()
* @covers ::normalize_configuration()
* @expectedIncorrectUsage WP_Service_Worker_Caching_Routes::register
*/
public function test_register_obsolete_plugins_key() {
$this->instance->register(
'\.foo$',
array(
'strategy' => 'cacheOnly',
'plugins' => array(
'expiration' => array(
'maxEntries' => 2,
'maxAgeSeconds' => 3,
),
'broadcastUpdate' => array(),
'cacheableResponse' => array(),
),
)
);

$routes = $this->instance->get_all();
$this->assertEqualSetsWithIndex(
array(
'route' => '\.foo$',
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_CACHE_ONLY,
'expiration' => array(
'max_entries' => 2,
'max_age_seconds' => 3,
),
'broadcast_update' => array(),
'cacheable_response' => array(),
),
array_pop( $routes )
);
}

/**
* Test registering with unexpected keys.
*
* @covers ::register()
* @covers ::normalize_configuration()
* @expectedIncorrectUsage WP_Service_Worker_Caching_Routes::register
*/
public function test_register_unexpected_keys() {
$this->instance->register(
'\.foo$',
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_NETWORK_FIRST,
'cache_name' => 'foo',
'network_timeout_seconds' => 2,
'foo_bar' => 'baz',
)
);

$routes = $this->instance->get_all();
$this->assertEqualSetsWithIndex(
array(
'route' => '\.foo$',
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_NETWORK_FIRST,
'network_timeout_seconds' => 2,
'cache_name' => 'foo',
'foo_bar' => 'baz',
),
array_pop( $routes )
);
}

/**
* Test registering a route with an invalid route.
*
* @covers WP_Service_Worker_Caching_Routes::register()
* @covers ::register()
* @expectedIncorrectUsage WP_Service_Worker_Caching_Routes::register
*/
public function test_register_invalid_route() {
public function test_register_invalid_string_route() {
$this->instance->register( 3, WP_Service_Worker_Caching_Routes::STRATEGY_STALE_WHILE_REVALIDATE );
}

/**
* Test registering a route with an invalid route.
*
* @covers ::register()
* @expectedIncorrectUsage WP_Service_Worker_Caching_Routes::register
*/
public function test_register_invalid_empty_route() {
$this->instance->register( null, WP_Service_Worker_Caching_Routes::STRATEGY_STALE_WHILE_REVALIDATE );
}

/**
* Test registering a route with an invalid strategy.
*
* @covers WP_Service_Worker_Caching_Routes::register()
* @covers ::register()
* @covers ::normalize_configuration()
* @expectedIncorrectUsage WP_Service_Worker_Caching_Routes::register
*/
public function test_register_invalid_strategy() {
Expand All @@ -126,10 +253,41 @@ public function test_register_invalid_strategy() {
/**
* Test registering a route without a strategy.
*
* @covers WP_Service_Worker_Caching_Routes::register()
* @covers ::register()
* @covers ::normalize_configuration()
* @expectedIncorrectUsage WP_Service_Worker_Caching_Routes::register
*/
public function test_register_missing_strategy() {
$this->instance->register( '/\.(?:js|css)$/', array() );
}

/**
* Test prepare_strategy_args_for_js_export.
*
* @covers ::prepare_strategy_args_for_js_export()
*/
public function test_prepare_strategy_args_for_js_export() {
$prepared = WP_Service_Worker_Caching_Routes::prepare_strategy_args_for_js_export(
array(
'strategy' => WP_Service_Worker_Caching_Routes::STRATEGY_NETWORK_FIRST,
'network_timeout_seconds' => 2,
'cache_name' => 'bank-cash',
'expiration' => array(
'max_entries' => 4,
'max_age_seconds' => 20,
),
'broadcast_update' => array(),
)
);

$this->assertContains( WP_Service_Worker_Caching_Routes::STRATEGY_NETWORK_FIRST, $prepared );
$this->assertContains( '"strategy":"NetworkFirst"', $prepared );
$this->assertContains( '"networkTimeoutSeconds":2', $prepared );
$this->assertContains( '"cacheName":"bank-cash"', $prepared );
$this->assertContains( '{"maxEntries":4,"maxAgeSeconds":20}', $prepared );
$this->assertContains( 'broadcastUpdate', $prepared );
$this->assertContains( 'BroadcastUpdatePlugin', $prepared );
$this->assertContains( 'expiration', $prepared );
$this->assertContains( 'ExpirationPlugin', $prepared );
}
}
Loading

0 comments on commit 7c63ceb

Please sign in to comment.