Completed
Push — try/search-config-via-wpadmin ( cb094f...014825 )
by
unknown
74:32 queued 64:33
created

Test_REST_Endpoints::build_reconnect_request()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
2
3
namespace Automattic\Jetpack\Connection;
4
5
use Automattic\Jetpack\Connection\Plugin as Connection_Plugin;
6
use Automattic\Jetpack\Connection\Plugin_Storage as Connection_Plugin_Storage;
7
use Automattic\Jetpack\Constants;
8
use PHPUnit\Framework\TestCase;
9
use Requests_Utility_CaseInsensitiveDictionary;
10
use WorDBless\Options as WorDBless_Options;
11
use WP_REST_Request;
12
use WP_REST_Server;
13
use WP_User;
14
15
/**
16
 * Unit tests for the REST API endpoints.
17
 *
18
 * @package automattic/jetpack-connection
19
 * @see \Automattic\Jetpack\Connection\REST_Connector
20
 */
21
class Test_REST_Endpoints extends TestCase {
22
23
	const BLOG_TOKEN = 'new.blogtoken';
24
	const BLOG_ID    = 42;
25
	const USER_ID    = 111;
26
27
	/**
28
	 * REST Server object.
29
	 *
30
	 * @var WP_REST_Server
31
	 */
32
	private $server;
33
34
	/**
35
	 * The original hostname to restore after tests are finished.
36
	 *
37
	 * @var string
38
	 */
39
	private $api_host_original;
40
41
	/**
42
	 * Setting up the test.
43
	 *
44
	 * @before
45
	 */
46
	public function set_up() {
47
		global $wp_rest_server;
48
49
		$wp_rest_server = new WP_REST_Server();
50
		$this->server   = $wp_rest_server;
51
52
		do_action( 'rest_api_init' );
53
		new REST_Connector( new Manager() );
54
55
		add_action( 'jetpack_disabled_raw_options', array( $this, 'bypass_raw_options' ) );
56
57
		$user = wp_get_current_user();
58
		$user->add_cap( 'jetpack_reconnect' );
59
		$user->add_cap( 'jetpack_connect' );
60
61
		$this->api_host_original                                  = Constants::get_constant( 'JETPACK__WPCOM_JSON_API_BASE' );
62
		Constants::$set_constants['JETPACK__WPCOM_JSON_API_BASE'] = 'https://public-api.wordpress.com';
63
64
		Constants::$set_constants['JETPACK__API_BASE'] = 'https://jetpack.wordpress.com/jetpack.';
65
66
		set_transient( 'jetpack_assumed_site_creation_date', '2020-02-28 01:13:27' );
67
	}
68
69
	/**
70
	 * Returning the environment into its initial state.
71
	 *
72
	 * @after
73
	 */
74
	public function tear_down() {
75
		remove_action( 'jetpack_disabled_raw_options', array( $this, 'bypass_raw_options' ) );
76
77
		$user = wp_get_current_user();
78
		$user->remove_cap( 'jetpack_reconnect' );
79
80
		Constants::$set_constants['JETPACK__WPCOM_JSON_API_BASE'] = $this->api_host_original;
81
82
		delete_transient( 'jetpack_assumed_site_creation_date' );
83
84
		WorDBless_Options::init()->clear_options();
85
	}
86
87
	/**
88
	 * Testing the `/jetpack/v4/remote_authorize` endpoint.
89
	 */
90
	public function test_remote_authorize() {
91
		add_filter( 'jetpack_options', array( $this, 'mock_jetpack_site_connection_options' ), 10, 2 );
92
		add_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ), 10, 3 );
93
94
		wp_cache_set(
95
			self::USER_ID,
96
			(object) array(
97
				'ID'         => self::USER_ID,
98
				'user_email' => '[email protected]',
99
			),
100
			'users'
101
		);
102
103
		$secret_1 = 'Az0g39toGWlYiTJ4NnDuAz0g39toGWlY';
104
105
		$secrets = array(
106
			'jetpack_authorize_' . self::USER_ID => array(
107
				'secret_1' => $secret_1,
108
				'secret_2' => 'zfIFcym2Jlzd8AVgzfIFcym2Jlzd8AVg',
109
				'exp'      => time() + 60,
110
			),
111
		);
112
113
		// phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
114
		$options_filter = function ( $value ) use ( $secrets ) {
115
			return $secrets;
116
		};
117
		add_filter( 'pre_option_' . Secrets::LEGACY_SECRETS_OPTION_NAME, $options_filter );
118
119
		$user_caps_filter = function ( $allcaps, $caps, $args, $user ) {
120
			if ( $user instanceof WP_User && self::USER_ID === $user->ID ) {
0 ignored issues
show
Bug introduced by
The class WP_User does not exist. Is this class maybe located in a folder that is not analyzed, or in a newer version of your dependencies than listed in your composer.lock/composer.json?
Loading history...
121
				$allcaps['manage_options'] = true;
122
				$allcaps['administrator']  = true;
123
			}
124
125
			return $allcaps;
126
		};
127
		add_filter( 'user_has_cap', $user_caps_filter, 10, 4 );
128
129
		$this->request = new WP_REST_Request( 'POST', '/jetpack/v4/remote_authorize' );
130
		$this->request->set_header( 'Content-Type', 'application/json' );
131
		$this->request->set_body( '{ "state": "' . self::USER_ID . '", "secret": "' . $secret_1 . '", "redirect_uri": "https://example.org", "code": "54321" }' );
132
133
		$response = $this->server->dispatch( $this->request );
134
		$data     = $response->get_data();
135
136
		remove_filter( 'user_has_cap', $user_caps_filter );
137
		remove_filter( 'pre_option_' . Secrets::LEGACY_SECRETS_OPTION_NAME, $options_filter );
138
		remove_filter( 'pre_http_request', array( $this, 'intercept_auth_token_request' ) );
139
		remove_filter( 'jetpack_options', array( $this, 'mock_jetpack_site_connection_options' ) );
140
141
		wp_cache_delete( self::USER_ID, 'users' );
142
143
		wp_set_current_user( 0 );
144
145
		$this->assertEquals( 200, $response->get_status() );
146
		$this->assertEquals( 'authorized', $data['result'] );
147
	}
148
149
	/**
150
	 * Testing the `/jetpack/v4/connection` endpoint.
151
	 */
152
	public function test_connection() {
153
		add_filter( 'jetpack_offline_mode', '__return_true' );
154
		try {
155
			$this->request = new WP_REST_Request( 'GET', '/jetpack/v4/connection' );
156
157
			$response = $this->server->dispatch( $this->request );
158
			$data     = $response->get_data();
159
160
			$this->assertFalse( $data['isActive'] );
161
			$this->assertFalse( $data['isRegistered'] );
162
			$this->assertTrue( $data['offlineMode']['isActive'] );
163
		} finally {
164
			remove_filter( 'jetpack_offline_mode', '__return_true' );
165
		}
166
	}
167
168
	/**
169
	 * Testing the `/jetpack/v4/connection` endpoint jetpack_connection_status filter.
170
	 */
171
	public function test_connection_jetpack_connection_status_filter() {
172
		add_filter(
173
			'jetpack_connection_status',
174
			function ( $status_data ) {
175
				$this->assertTrue( is_array( $status_data ) );
176
				return array();
177
			}
178
		);
179
		try {
180
			$this->request = new WP_REST_Request( 'GET', '/jetpack/v4/connection' );
181
182
			$response = $this->server->dispatch( $this->request );
183
			$data     = $response->get_data();
184
185
			$this->assertSame( array(), $data );
186
		} finally {
187
			remove_all_filters( 'jetpack_connection_status' );
188
		}
189
	}
190
191
	/**
192
	 * Testing the `/jetpack/v4/connection/plugins` endpoint.
193
	 */
194
	public function test_connection_plugins() {
195
		$user = wp_get_current_user();
196
		$user->add_cap( 'activate_plugins' );
197
198
		$plugins = array(
199
			array(
200
				'name' => 'Plugin Name 1',
201
				'slug' => 'plugin-slug-1',
202
			),
203
			array(
204
				'name' => 'Plugin Name 2',
205
				'slug' => 'plugin-slug-2',
206
			),
207
		);
208
209
		array_walk(
210
			$plugins,
211
			function ( $plugin ) {
212
				( new Connection_Plugin( $plugin['slug'] ) )->add( $plugin['name'] );
213
			}
214
		);
215
216
		Connection_Plugin_Storage::configure();
217
218
		$this->request = new WP_REST_Request( 'GET', '/jetpack/v4/connection/plugins' );
219
220
		$response = $this->server->dispatch( $this->request );
221
222
		$user->remove_cap( 'activate_plugins' );
223
224
		$this->assertEquals( $plugins, $response->get_data() );
225
	}
226
227
	/**
228
	 * Testing the `connection/reconnect` endpoint, full reconnect.
229
	 */
230
	public function test_connection_reconnect_full() {
231
		$this->setup_reconnect_test( null );
232
		add_filter( 'jetpack_connection_disconnect_site_wpcom', '__return_false' );
233
		add_filter( 'pre_http_request', array( static::class, 'intercept_register_request' ), 10, 3 );
234
235
		$response = $this->server->dispatch( $this->build_reconnect_request() );
236
		$data     = $response->get_data();
237
238
		remove_filter( 'pre_http_request', array( static::class, 'intercept_register_request' ), 10 );
239
		remove_filter( 'jetpack_connection_disconnect_site_wpcom', '__return_false' );
240
		$this->shutdown_reconnect_test( null );
241
242
		$this->assertEquals( 200, $response->get_status() );
243
		$this->assertEquals( 'in_progress', $data['status'] );
244
		$this->assertSame( 0, strpos( $data['authorizeUrl'], 'https://jetpack.wordpress.com/jetpack.authorize/' ) );
245
	}
246
247
	/**
248
	 * Testing the `connection/reconnect` endpoint, successful partial reconnect (blog token).
249
	 */
250 View Code Duplication
	public function test_connection_reconnect_partial_blog_token_success() {
251
		$this->setup_reconnect_test( 'blog_token' );
252
		add_filter( 'pre_http_request', array( $this, 'intercept_refresh_blog_token_request' ), 10, 3 );
253
254
		$response = $this->server->dispatch( $this->build_reconnect_request() );
255
		$data     = $response->get_data();
256
257
		remove_filter( 'pre_http_request', array( $this, 'intercept_refresh_blog_token_request' ), 10 );
258
		$this->shutdown_reconnect_test( 'blog_token' );
259
260
		$this->assertEquals( 200, $response->get_status() );
261
		$this->assertEquals( 'completed', $data['status'] );
262
	}
263
264
	/**
265
	 * Testing the `connection/reconnect` endpoint, failed partial reconnect (blog token).
266
	 */
267 View Code Duplication
	public function test_connection_reconnect_partial_blog_token_fail() {
268
		$this->setup_reconnect_test( 'blog_token' );
269
		add_filter( 'pre_http_request', array( $this, 'intercept_refresh_blog_token_request_fail' ), 10, 3 );
270
271
		$response = $this->server->dispatch( $this->build_reconnect_request() );
272
		$data     = $response->get_data();
273
274
		remove_filter( 'pre_http_request', array( $this, 'intercept_refresh_blog_token_request_fail' ), 10 );
275
		$this->shutdown_reconnect_test( 'blog_token' );
276
277
		$this->assertEquals( 500, $response->get_status() );
278
		$this->assertEquals( 'jetpack_secret', $data['code'] );
279
	}
280
281
	/**
282
	 * Testing the `connection/reconnect` endpoint, successful partial reconnect (user token).
283
	 */
284
	public function test_connection_reconnect_partial_user_token_success() {
285
		$this->setup_reconnect_test( 'user_token' );
286
287
		$response = $this->server->dispatch( $this->build_reconnect_request() );
288
		$data     = $response->get_data();
289
290
		$this->shutdown_reconnect_test( 'user_token' );
291
292
		$this->assertEquals( 200, $response->get_status() );
293
		$this->assertEquals( 'in_progress', $data['status'] );
294
		$this->assertSame( 0, strpos( $data['authorizeUrl'], 'https://jetpack.wordpress.com/jetpack.authorize/' ) );
295
	}
296
297
	/**
298
	 * Testing the `connection/reconnect` endpoint, site_connection (full reconnect).
299
	 */
300
	public function test_connection_reconnect_site_connection() {
301
		add_filter( 'jetpack_options', array( $this, 'mock_jetpack_site_connection_options' ), 10, 2 );
302
		add_filter( 'jetpack_connection_disconnect_site_wpcom', '__return_false' );
303
		add_filter( 'pre_http_request', array( static::class, 'intercept_register_request' ), 10, 3 );
304
305
		$response = $this->server->dispatch( $this->build_reconnect_request() );
306
		$data     = $response->get_data();
307
308
		remove_filter( 'pre_http_request', array( static::class, 'intercept_register_request' ), 10 );
309
		remove_filter( 'jetpack_connection_disconnect_site_wpcom', '__return_false' );
310
		remove_filter( 'jetpack_options', array( $this, 'mock_jetpack_site_connection_options' ) );
311
312
		$this->assertEquals( 200, $response->get_status() );
313
		$this->assertEquals( 'completed', $data['status'] );
314
	}
315
316
	/**
317
	 * Testing the `connection/reconnect` endpoint when the token validation request fails.
318
	 */
319
	public function test_connection_reconnect_when_token_validation_request_fails() {
320
		$this->setup_reconnect_test( 'token_validation_failed' );
321
		add_filter( 'jetpack_connection_disconnect_site_wpcom', '__return_false' );
322
		add_filter( 'pre_http_request', array( static::class, 'intercept_register_request' ), 10, 3 );
323
324
		$response = $this->server->dispatch( $this->build_reconnect_request() );
325
		$data     = $response->get_data();
326
327
		remove_filter( 'pre_http_request', array( static::class, 'intercept_register_request' ), 10 );
328
		remove_filter( 'jetpack_connection_disconnect_site_wpcom', '__return_false' );
329
		$this->shutdown_reconnect_test( 'token_validation_failed' );
330
331
		$this->assertEquals( 200, $response->get_status() );
332
		$this->assertEquals( 'in_progress', $data['status'] );
333
		$this->assertSame( 0, strpos( $data['authorizeUrl'], 'https://jetpack.wordpress.com/jetpack.authorize/' ) );
334
	}
335
336
	/**
337
	 * Testing the `connection/register` endpoint.
338
	 */
339
	public function test_connection_register() {
340
		add_filter( 'pre_http_request', array( static::class, 'intercept_register_request' ), 10, 3 );
341
342
		$this->request = new WP_REST_Request( 'POST', '/jetpack/v4/connection/register' );
343
		$this->request->set_header( 'Content-Type', 'application/json' );
344
345
		$this->request->set_body( wp_json_encode( array( 'registration_nonce' => wp_create_nonce( 'jetpack-registration-nonce' ) ) ) );
346
347
		$response = $this->server->dispatch( $this->request );
348
		$data     = $response->get_data();
349
350
		remove_filter( 'pre_http_request', array( static::class, 'intercept_register_request' ), 10 );
351
352
		$this->assertEquals( 200, $response->get_status() );
353
		$this->assertSame( 0, strpos( $data['authorizeUrl'], 'https://jetpack.wordpress.com/jetpack.authorize_iframe/' ) );
354
	}
355
356
	/**
357
	 * This filter callback allow us to skip the database query by `Jetpack_Options` to retrieve the option.
358
	 *
359
	 * @param array $options List of options already skipping the database request.
360
	 *
361
	 * @return array
362
	 */
363
	public function bypass_raw_options( array $options ) {
364
		$options[ Secrets::LEGACY_SECRETS_OPTION_NAME ] = true;
365
366
		return $options;
367
	}
368
369
	/**
370
	 * Intercept the `jetpack.register` API request sent to WP.com, and mock the response.
371
	 *
372
	 * @param bool|array $response The existing response.
373
	 * @param array      $args The request arguments.
374
	 * @param string     $url The request URL.
375
	 *
376
	 * @return array
377
	 */
378
	public static function intercept_register_request( $response, $args, $url ) {
379
		if ( false === strpos( $url, 'jetpack.register' ) ) {
380
			return $response;
381
		}
382
383
		return array(
384
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
385
			'body'     => wp_json_encode(
386
				array(
387
					'jetpack_id'     => '12345',
388
					'jetpack_secret' => 'sample_secret',
389
				)
390
			),
391
			'response' => array(
392
				'code'    => 200,
393
				'message' => 'OK',
394
			),
395
		);
396
	}
397
398
	/**
399
	 * Intercept the `jetpack-token-health` API request sent to WP.com, and mock the "invalid blog token" response.
400
	 *
401
	 * @param bool|array $response The existing response.
402
	 * @param array      $args The request arguments.
403
	 * @param string     $url The request URL.
404
	 *
405
	 * @return array
406
	 */
407
	public function intercept_validate_tokens_request_invalid_blog_token( $response, $args, $url ) {
408
		if ( false === strpos( $url, 'jetpack-token-health' ) ) {
409
			return $response;
410
		}
411
412
		return $this->build_validate_tokens_response( 'blog_token' );
413
	}
414
415
	/**
416
	 * Intercept the `jetpack-token-health` API request sent to WP.com, and mock the "invalid user token" response.
417
	 *
418
	 * @param bool|array $response The existing response.
419
	 * @param array      $args The request arguments.
420
	 * @param string     $url The request URL.
421
	 *
422
	 * @return array
423
	 */
424
	public function intercept_validate_tokens_request_invalid_user_token( $response, $args, $url ) {
425
		if ( false === strpos( $url, 'jetpack-token-health' ) ) {
426
			return $response;
427
		}
428
429
		return $this->build_validate_tokens_response( 'user_token' );
430
	}
431
432
	/**
433
	 * Intercept the `jetpack-token-health` API request sent to WP.com, and mock the "valid tokens" response.
434
	 *
435
	 * @param bool|array $response The existing response.
436
	 * @param array      $args The request arguments.
437
	 * @param string     $url The request URL.
438
	 *
439
	 * @return array
440
	 */
441
	public function intercept_validate_tokens_request_valid_tokens( $response, $args, $url ) {
442
		if ( false === strpos( $url, 'jetpack-token-health' ) ) {
443
			return $response;
444
		}
445
446
		return $this->build_validate_tokens_response( null );
447
	}
448
449
	/**
450
	 * Intercept the `jetpack-token-health` API request sent to WP.com, and mock failed response.
451
	 *
452
	 * @param bool|array $response The existing response.
453
	 * @param array      $args The request arguments.
454
	 * @param string     $url The request URL.
455
	 *
456
	 * @return array
457
	 */
458 View Code Duplication
	public function intercept_validate_tokens_request_failed( $response, $args, $url ) {
459
		if ( false === strpos( $url, 'jetpack-token-health' ) ) {
460
			return $response;
461
		}
462
463
		return array(
464
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
465
			'body'     => wp_json_encode( array( 'dummy_error' => true ) ),
466
			'response' => array(
467
				'code'    => 500,
468
				'message' => 'failed',
469
			),
470
		);
471
	}
472
473
	/**
474
	 * Build the response for a tokens validation request
475
	 *
476
	 * @param string $invalid_token Accepted values: 'blog_token', 'user_token'.
477
	 *
478
	 * @return array
479
	 */
480
	private function build_validate_tokens_response( $invalid_token ) {
481
		$body = array(
482
			'blog_token' => array(
483
				'is_healthy' => true,
484
			),
485
			'user_token' => array(
486
				'is_healthy'     => true,
487
				'is_master_user' => true,
488
			),
489
		);
490
491
		switch ( $invalid_token ) {
492
			case 'blog_token':
493
				$body['blog_token'] = array(
494
					'is_healthy' => false,
495
					'code'       => 'unknown_token',
496
				);
497
				break;
498
			case 'user_token':
499
				$body['user_token'] = array(
500
					'is_healthy' => false,
501
					'code'       => 'unknown_token',
502
				);
503
				break;
504
		}
505
506
		return array(
507
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
508
			'body'     => wp_json_encode( $body ),
509
			'response' => array(
510
				'code'    => 200,
511
				'message' => 'OK',
512
			),
513
		);
514
	}
515
516
	/**
517
	 * Intercept the `jetpack-refresh-blog-token` API request sent to WP.com, and mock the success response.
518
	 *
519
	 * @param bool|array $response The existing response.
520
	 * @param array      $args The request arguments.
521
	 * @param string     $url The request URL.
522
	 *
523
	 * @return array
524
	 */
525 View Code Duplication
	public function intercept_refresh_blog_token_request( $response, $args, $url ) {
526
		if ( false === strpos( $url, 'jetpack-refresh-blog-token' ) ) {
527
			return $response;
528
		}
529
530
		return array(
531
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
532
			'body'     => wp_json_encode( array( 'jetpack_secret' => self::BLOG_TOKEN ) ),
533
			'response' => array(
534
				'code'    => 200,
535
				'message' => 'OK',
536
			),
537
		);
538
	}
539
540
	/**
541
	 * Intercept the `jetpack-refresh-blog-token` API request sent to WP.com, and mock the failure response.
542
	 *
543
	 * @param bool|array $response The existing response.
544
	 * @param array      $args The request arguments.
545
	 * @param string     $url The request URL.
546
	 *
547
	 * @return array
548
	 */
549 View Code Duplication
	public function intercept_refresh_blog_token_request_fail( $response, $args, $url ) {
550
		if ( false === strpos( $url, 'jetpack-refresh-blog-token' ) ) {
551
			return $response;
552
		}
553
554
		return array(
555
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
556
			'body'     => wp_json_encode( array( 'jetpack_secret_missing' => true ) ), // Meaningless body.
557
			'response' => array(
558
				'code'    => 200,
559
				'message' => 'OK',
560
			),
561
		);
562
	}
563
564
	/**
565
	 * Intercept the `jetpack-token-health` API request sent to WP.com, and mock the "invalid blog token" response.
566
	 *
567
	 * @param bool|array $response The existing response.
568
	 * @param array      $args The request arguments.
569
	 * @param string     $url The request URL.
570
	 *
571
	 * @return array
572
	 */
573
	public function intercept_auth_token_request( $response, $args, $url ) {
574
		if ( false === strpos( $url, '/jetpack.token/' ) ) {
575
			return $response;
576
		}
577
578
		return array(
579
			'headers'  => new Requests_Utility_CaseInsensitiveDictionary( array( 'content-type' => 'application/json' ) ),
580
			'body'     => wp_json_encode(
581
				array(
582
					'access_token' => 'mock.token',
583
					'token_type'   => 'X_JETPACK',
584
					'scope'        => ( new Manager() )->sign_role( 'administrator' ),
585
				)
586
			),
587
			'response' => array(
588
				'code'    => 200,
589
				'message' => 'OK',
590
			),
591
		);
592
	}
593
594
	/**
595
	 * Intercept the `Jetpack_Options` call and mock the values.
596
	 * Site level / user-less connection set-up.
597
	 *
598
	 * @param mixed  $value The current option value.
599
	 * @param string $name Option name.
600
	 *
601
	 * @return mixed
602
	 */
603
	public function mock_jetpack_site_connection_options( $value, $name ) {
604
		switch ( $name ) {
605
			case 'blog_token':
606
				return self::BLOG_TOKEN;
607
			case 'id':
608
				return self::BLOG_ID;
609
		}
610
611
		return $value;
612
	}
613
614
	/**
615
	 * Intercept the `Jetpack_Options` call and mock the values.
616
	 * Full connection set-up.
617
	 *
618
	 * @param mixed  $value The current option value.
619
	 * @param string $name Option name.
620
	 *
621
	 * @return mixed
622
	 */
623
	public function mock_jetpack_options( $value, $name ) {
624
		switch ( $name ) {
625
			case 'blog_token':
626
				return self::BLOG_TOKEN;
627
			case 'id':
628
				return self::BLOG_ID;
629
			case 'master_user':
630
				return self::USER_ID;
631
			case 'user_tokens':
632
				return array(
633
					self::USER_ID => 'new.usertoken.' . self::USER_ID,
634
				);
635
		}
636
637
		return $value;
638
	}
639
640
	/**
641
	 * Build the `connection/reconnect` request object.
642
	 *
643
	 * @return WP_REST_Request
644
	 */
645
	private function build_reconnect_request() {
646
		$this->request = new WP_REST_Request( 'POST', '/jetpack/v4/connection/reconnect' );
647
		$this->request->set_header( 'Content-Type', 'application/json' );
648
649
		return $this->request;
650
	}
651
652
	/**
653
	 * Setup the environment to test the reconnection process.
654
	 *
655
	 * @param string|null $invalid_token The invalid token to be returned in the response. Null if the tokens should be valid.
656
	 */
657
	private function setup_reconnect_test( $invalid_token ) {
658
		switch ( $invalid_token ) {
659
			case 'blog_token':
660
				add_filter(
661
					'pre_http_request',
662
					array(
663
						$this,
664
						'intercept_validate_tokens_request_invalid_blog_token',
665
					),
666
					10,
667
					3
668
				);
669
				break;
670
			case 'user_token':
671
				add_filter(
672
					'pre_http_request',
673
					array(
674
						$this,
675
						'intercept_validate_tokens_request_invalid_user_token',
676
					),
677
					10,
678
					3
679
				);
680
				break;
681
			case 'token_validation_failed':
682
				add_filter(
683
					'pre_http_request',
684
					array(
685
						$this,
686
						'intercept_validate_tokens_request_failed',
687
					),
688
					10,
689
					3
690
				);
691
				break;
692
			case null:
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $invalid_token of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
693
				add_filter(
694
					'pre_http_request',
695
					array(
696
						$this,
697
						'intercept_validate_tokens_request_valid_tokens',
698
					),
699
					10,
700
					3
701
				);
702
				break;
703
		}
704
705
		add_filter( 'jetpack_options', array( $this, 'mock_jetpack_options' ), 10, 2 );
706
	}
707
708
	/**
709
	 * Restore the environment after the `reconnect` test has been run.
710
	 *
711
	 * @param string|null $invalid_token The invalid token to be returned in the response. Null if the tokens should be valid.
712
	 */
713
	private function shutdown_reconnect_test( $invalid_token ) {
714
		switch ( $invalid_token ) {
715
			case 'blog_token':
716
				remove_filter(
717
					'pre_http_request',
718
					array(
719
						$this,
720
						'intercept_validate_tokens_request_invalid_blog_token',
721
					),
722
					10
723
				);
724
				break;
725
			case 'user_token':
726
				remove_filter(
727
					'pre_http_request',
728
					array(
729
						$this,
730
						'intercept_validate_tokens_request_invalid_user_token',
731
					),
732
					10
733
				);
734
				break;
735
			case 'token_validation_failed':
736
				remove_filter(
737
					'pre_http_request',
738
					array(
739
						$this,
740
						'intercept_validate_tokens_request_failed',
741
					),
742
					10
743
				);
744
				break;
745
			case null:
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $invalid_token of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
746
				remove_filter(
747
					'pre_http_request',
748
					array(
749
						$this,
750
						'intercept_validate_tokens_request_valid_tokens',
751
					),
752
					10
753
				);
754
				break;
755
		}
756
757
		remove_filter( 'jetpack_options', array( $this, 'mock_jetpack_options' ), 10 );
758
		remove_filter( 'pre_http_request', array( $this, 'intercept_validate_tokens_request' ), 10 );
759
	}
760
761
}
762