diff --git a/inc/Engine/CDN/RocketCDN/Rest.php b/inc/Engine/CDN/RocketCDN/Rest.php index 7404cb7bf9..b660c147a7 100644 --- a/inc/Engine/CDN/RocketCDN/Rest.php +++ b/inc/Engine/CDN/RocketCDN/Rest.php @@ -146,6 +146,25 @@ public function register_routes(): void { ], ] ); + + register_rest_route( + self::ROUTE_NAMESPACE, + self::ROUTE_BASE . '/driver', + [ + 'methods' => WP_REST_Server::CREATABLE, + 'callback' => [ $this, 'save_cdn_type' ], + 'permission_callback' => [ $this, 'check_permission' ], + 'args' => [ + 'driver' => [ + 'required' => true, + 'validate_callback' => function ( $param ) { + return in_array( $param, [ 'byocdn', 'rocketcdn' ], true ); + }, + 'sanitize_callback' => 'sanitize_text_field', + ], + ], + ] + ); } /** @@ -338,4 +357,27 @@ function ( $page ) { protected function get_free_page_limit(): int { return 3; } + + /** + * Save cdn driver + * + * Persists the active driver tab selection so the UI + * can restore the correct view after a page refresh. + * + * @param WP_REST_Request $request REST request. + * @return WP_REST_Response + */ + public function save_cdn_type( WP_REST_Request $request ) { + $cdn_type = $request->get_param( 'driver' ); + + $this->options->set( 'cdn_type', $cdn_type ); + $this->options_api->set( 'settings', $this->options->get_options() ); + + return new WP_REST_Response( + [ + 'cdn_type' => $cdn_type, + ], + 200 + ); + } } diff --git a/tests/Fixtures/inc/Engine/CDN/RocketCDN/Rest/SaveCdnType.php b/tests/Fixtures/inc/Engine/CDN/RocketCDN/Rest/SaveCdnType.php new file mode 100644 index 0000000000..db78a00cbf --- /dev/null +++ b/tests/Fixtures/inc/Engine/CDN/RocketCDN/Rest/SaveCdnType.php @@ -0,0 +1,41 @@ + [ + 'config' => [ + 'params' => [ 'driver' => 'rocketcdn' ], + 'unauthenticated' => false, + ], + 'expected' => [ + 'cdn_type_response' => 'rocketcdn', + ], + ], + 'shouldSaveByocdnDriver' => [ + 'config' => [ + 'params' => [ 'driver' => 'byocdn' ], + 'unauthenticated' => false, + ], + 'expected' => [ + 'cdn_type_response' => 'byocdn', + ], + ], + 'shouldRejectInvalidDriver' => [ + 'config' => [ + 'params' => [ 'driver' => 'invalid_driver' ], + 'unauthenticated' => false, + ], + 'expected' => [ + 'code' => 'rest_invalid_param', + 'status' => 400, + ], + ], + 'shouldReturnForbiddenWhenUnauthenticated' => [ + 'config' => [ + 'params' => [ 'driver' => 'rocketcdn' ], + 'unauthenticated' => true, + ], + 'expected' => [ + 'code' => 'rest_forbidden', + ], + ], +]; diff --git a/tests/Integration/inc/Engine/CDN/RocketCDN/Rest/SaveCdnType.php b/tests/Integration/inc/Engine/CDN/RocketCDN/Rest/SaveCdnType.php new file mode 100644 index 0000000000..a0f0ae38b4 --- /dev/null +++ b/tests/Integration/inc/Engine/CDN/RocketCDN/Rest/SaveCdnType.php @@ -0,0 +1,103 @@ +admin_id = $this->factory()->user->create( [ 'role' => 'administrator' ] ); + wp_set_current_user( $this->admin_id ); + + $container = apply_filters( 'rocket_container', null ); + $this->options_data = $container->get( 'options' ); + $this->options_api = $container->get( 'options_api' ); + } + + public function tear_down() { + wp_set_current_user( 0 ); + + $settings = $this->options_api->get( 'settings', [] ); + unset( $settings['cdn_type'] ); + $this->options_api->set( 'settings', $settings ); + + parent::tear_down(); + } + + public function configTestData() { + if ( empty( $this->config ) ) { + $this->loadTestDataConfig(); + } + + return isset( $this->config['test_data'] ) + ? $this->config['test_data'] + : $this->config; + } + + protected function loadTestDataConfig() { + $obj = new \ReflectionObject( $this ); + $filename = $obj->getFileName(); + + $this->config = $this->getTestData( dirname( $filename ), basename( $filename, '.php' ) ); + } + + /** + * @dataProvider configTestData + */ + public function testShouldDoAsExpected( array $config, array $expected ) { + if ( ! empty( $config['unauthenticated'] ) ) { + wp_set_current_user( 0 ); + } + + $response = $this->doRestRequest( + 'POST', + '/wp-rocket/v1/rocketcdn/driver', + $config['params'] + ); + + foreach ( $expected as $key => $value ) { + switch ( $key ) { + case 'cdn_type_response': + $settings = $this->options_api->get( 'settings', [] ); + $this->assertSame( $value, $response['cdn_type'] ); + $this->assertSame( $value, $settings['cdn_type'] ?? null ); + break; + case 'code': + $this->assertSame( $value, $response['code'] ); + break; + case 'status': + $this->assertSame( $value, $response['data']['status'] ); + break; + } + } + } +}