Completed
Push — try/inline-connect ( 8d5d81...1de650 )
by
unknown
611:01 queued 599:40
created

WP_Test_Jetpack_REST_API_endpoints   F

Complexity

Total Complexity 60

Size/Duplication

Total Lines 1260
Duplicated Lines 20.08 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 253
loc 1260
rs 2.4
c 0
b 0
f 0
wmc 60
lcom 1
cbo 4

45 Methods

Rating   Name   Duplication   Size   Complexity  
A setUp() 0 8 1
A tearDown() 0 6 1
A load_rest_endpoints_direct() 0 3 1
A get_jetpack_connection_status() 0 4 2
A create_and_get_user() 0 5 2
B create_and_get_request() 0 16 7
A assertResponseStatus() 0 3 1
A assertResponseData() 0 12 3
A test_jetpack_admin_page_permission() 0 37 1
A test_connection_permission() 0 38 1
A test_disconnection_permission() 29 29 1
A test_plugin_activation_permission() 33 33 2
A test_admin_user_unlink_permission() 0 25 1
A test_manage_configure_modules_permission() 0 31 1
A test_jetpack_connection_status() 0 23 1
A test_jetpack_connection_status_staging() 0 26 1
A test_jetpack_connection_status_dev() 0 27 1
A test_disconnect_site_noauth() 0 9 1
A test_disconnect_site_auth_noparam() 13 13 1
A test_disconnect_site_auth_param_notconnected() 13 13 1
A test_disconnect_site_auth_param_connected() 0 19 1
A test_build_connect_url_no_blog_token_id() 0 37 1
A test_check_onboarding_token() 0 9 1
A test_build_connect_url_blog_token_and_id() 0 32 1
A mock_xmlrpc_success() 20 20 2
A test_unlink_user() 0 41 1
A test_unlink_user_cache_data_removal() 0 23 1
A test_setting_enum_save() 0 24 1
A test_setting_array_type() 0 23 1
A test_settings_retrieve() 0 21 1
B test_fetch_milestone_widget_data() 0 73 3
A test_fetch_nonexistent_widget_data() 10 10 1
A test_fetch_nonexistent_widget_instance_data() 10 10 1
A test_fetch_not_registered_widget_data() 0 20 2
A test_change_owner() 0 35 1
A test_recommendations_data() 25 25 1
A test_recommendations_step() 22 22 1
A test_licensing_error() 0 29 1
A test_get_user_connection_data_without_master_user() 0 11 1
A test_get_purchase_token() 16 16 1
A test_get_purchase_token_non_admin_user() 16 16 1
A test_get_purchase_token_no_site_registered() 15 15 1
A test_delete_purchase_token() 0 29 1
A test_delete_purchase_token_non_admin_user() 16 16 1
A test_delete_purchase_token_no_site_registered() 15 15 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like WP_Test_Jetpack_REST_API_endpoints often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use WP_Test_Jetpack_REST_API_endpoints, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * Class for REST API endpoints testing.
4
 *
5
 * @since 4.4.0
6
 * @package automattic/jetpack
7
 */
8
9
use Automattic\Jetpack\Connection\REST_Connector;
10
11
require_once( dirname( __FILE__ ) . '/../../../../modules/widgets/milestone.php' );
12
13
class WP_Test_Jetpack_REST_API_endpoints extends WP_UnitTestCase {
14
15
	/**
16
	 * Used to store an instance of the WP_REST_Server.
17
	 *
18
	 * @since 4.4.0
19
	 *
20
	 * @var WP_REST_Server
21
	 */
22
	private $server;
23
24
	/**
25
	 * Setup environment for REST API endpoints test.
26
	 *
27
	 * @since 4.4.0
28
	 */
29
	public function setUp() {
30
31
		parent::setUp();
32
33
		global $wp_rest_server;
34
		$this->server = $wp_rest_server = new WP_REST_Server;
35
		do_action( 'rest_api_init' );
36
	}
37
38
	/**
39
	 * Clean environment for REST API endpoints test.
40
	 *
41
	 * @since 4.4.0
42
	 */
43
	public function tearDown() {
44
		parent::tearDown();
45
46
		global $wp_rest_server;
47
		$wp_rest_server = null;
48
	}
49
50
	/**
51
	 * Loads the REST API endpoints to test their methods directly.
52
	 *
53
	 * @since 4.4.0
54
	 */
55
	protected function load_rest_endpoints_direct() {
56
		require_once dirname( __FILE__ ) . '/../../../../_inc/lib/class.core-rest-api-endpoints.php';
57
	}
58
59
	/**
60
	 * Get Jetpack connection status.
61
	 *
62
	 * @since 4.4.0
63
	 *
64
	 * @return array
65
	 */
66
	protected function get_jetpack_connection_status() {
67
		$status = REST_Connector::connection_status();
68
		return isset( $status->data ) ? $status->data : array();
69
	}
70
71
	/**
72
	 * Create and get a user using WP factory.
73
	 *
74
	 * @since 4.4.0
75
	 *
76
	 * @param string $role
77
	 *
78
	 * @return WP_User
79
	 */
80
	protected function create_and_get_user( $role = '' ) {
81
		return $this->factory->user->create_and_get( array(
82
			'role' => empty( $role ) ? 'subscriber' : $role,
83
		) );
84
	}
85
86
	/**
87
	 * Creates a WP_REST_Request and returns it.
88
	 *
89
	 * @since 4.4.0
90
	 *
91
	 * @param string $route       REST API path to be append to /jetpack/v4/
92
	 * @param array  $json_params When present, parameters are added to request in JSON format
93
	 * @param string $method      Request method to use, GET or POST
94
	 * @param array  $params      Parameters to add to endpoint
95
	 *
96
	 * @return WP_REST_Response
97
	 */
98
	protected function create_and_get_request( $route = '', $json_params = array(), $method = 'GET', $params = array() ) {
99
		$request = new WP_REST_Request( $method, "/jetpack/v4/$route" );
100
101
		if ( 'GET' !== $method && !empty( $json_params ) ) {
102
			$request->set_header( 'content-type', 'application/json' );
103
		}
104
		if ( ! empty( $json_params ) ) {
105
			$request->set_body( json_encode( $json_params ) );
106
		}
107
		if ( ! empty( $params ) && is_array( $params ) ) {
108
			foreach ( $params as $key => $value ) {
109
				$request->set_param( $key, $value );
110
			}
111
		}
112
		return $this->server->dispatch( $request );
113
	}
114
115
	/**
116
	 * Used to simulate a successful response to any XML-RPC request.
117
	 * Should be hooked on the `pre_http_resquest` filter.
118
	 *
119
	 * @param false  $preempt A preemptive return value of an HTTP request.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $preempt not be boolean?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
120
	 * @param array  $args    HTTP request arguments.
121
	 * @param string $url     The request URL.
122
	 *
123
	 * @return WP_REST_Response
124
	 */
125 View Code Duplication
	public function mock_xmlrpc_success( $preempt, $args, $url ) {
126
		if ( strpos( $url, 'https://jetpack.wordpress.com/xmlrpc.php' ) !== false ) {
127
			$response = array();
128
129
			$response['body'] = '
130
				<methodResponse>
131
					<params>
132
						<param>
133
							<value>1</value>
134
						</param>
135
					</params>
136
				</methodResponse>
137
			';
138
139
			$response['response']['code'] = 200;
140
			return $response;
141
		}
142
143
		return $preempt;
144
	}
145
146
	/**
147
	 * Check response status code.
148
	 *
149
	 * @since 4.4.0
150
	 *
151
	 * @param integer          $status
152
	 * @param WP_REST_Response $response
153
	 */
154
	protected function assertResponseStatus( $status, $response ) {
155
		$this->assertEquals( $status, $response->get_status() );
156
	}
157
158
	/**
159
	 * Check response data.
160
	 *
161
	 * @since 4.4.0
162
	 *
163
	 * @param array            $data
164
	 * @param WP_REST_Response $response
165
	 */
166
	protected function assertResponseData( $data, $response ) {
167
		$response_data = $response->get_data();
168
		$tested_data   = array();
169
		foreach ( $data as $key => $value ) {
170
			if ( isset( $response_data[$key] ) ) {
171
				$tested_data[$key] = $response_data[$key];
172
			} else {
173
				$tested_data[$key] = null;
174
			}
175
		}
176
		$this->assertEquals( $data, $tested_data );
177
	}
178
179
	/**
180
	 * Test permission to see if users can view Jetpack admin screen.
181
	 *
182
	 * @since 4.4.0
183
	 */
184
	public function test_jetpack_admin_page_permission() {
185
186
		$this->load_rest_endpoints_direct();
187
188
		// Current user doesn't have credentials, so checking permissions should fail
189
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::view_admin_page_permission_check() );
190
191
		// Setup a new current user with specified capability
192
		$user = $this->create_and_get_user();
193
194
		// Add Jetpack capability
195
		$user->add_cap( 'jetpack_admin_page' );
196
197
		// Setup global variables so this is the current user
198
		wp_set_current_user( $user->ID );
199
200
		// User has capability so this should work this time
201
		$this->assertTrue( Jetpack_Core_Json_Api_Endpoints::view_admin_page_permission_check() );
202
203
		// It should not work in Offline Mode.
204
		add_filter( 'jetpack_offline_mode', '__return_true' );
205
206
		// Subscribers only have access to connect, which is not available in Dev Mode so this should fail
207
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::view_admin_page_permission_check() );
208
209
		// Set user as admin
210
		$user->set_role( 'administrator' );
211
212
		// Reset user and setup globals again to reflect the role change.
213
		wp_set_current_user( 0 );
214
		wp_set_current_user( $user->ID );
215
216
		// Admins have acces to everything, to this should work
217
		$this->assertTrue( Jetpack_Core_Json_Api_Endpoints::view_admin_page_permission_check() );
218
219
		remove_filter( 'jetpack_offline_mode', '__return_true' );
220
	}
221
222
	/**
223
	 * Test permission to connect Jetpack site or link user.
224
	 *
225
	 * @since 4.4.0
226
	 */
227
	public function test_connection_permission() {
228
229
		$this->load_rest_endpoints_direct();
230
231
		// Current user doesn't have credentials, so checking permissions should fail
232
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::connect_url_permission_callback() );
233
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::get_user_connection_data_permission_callback() );
234
235
		// Setup a new current user with specified capability
236
		$user = $this->create_and_get_user();
237
238
		// Add Jetpack capability
239
		$user->add_cap( 'jetpack_connect_user' );
240
241
		// Setup global variables so this is the current user
242
		wp_set_current_user( $user->ID );
243
244
		// It should not work for non-admin users, except if a connection owner exists.
245
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::connect_url_permission_callback() );
246
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::get_user_connection_data_permission_callback() );
247
248
		// Set user as admin.
249
		$user->set_role( 'administrator' );
250
		// Reset user and setup globals again to reflect the role change.
251
		wp_set_current_user( 0 );
252
		wp_set_current_user( $user->ID );
253
		// User is admin and has capability so this should work this time.
254
		$this->assertTrue( Jetpack_Core_Json_Api_Endpoints::connect_url_permission_callback() );
255
		$this->assertTrue( Jetpack_Core_Json_Api_Endpoints::get_user_connection_data_permission_callback() );
256
257
		// It should not work in Offline Mode.
258
		add_filter( 'jetpack_offline_mode', '__return_true' );
259
260
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::connect_url_permission_callback() );
261
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::get_user_connection_data_permission_callback() );
262
263
		remove_filter( 'jetpack_offline_mode', '__return_true' );
264
	}
265
266
	/**
267
	 * Test permission to disconnect Jetpack site.
268
	 *
269
	 * @since 4.4.0
270
	 */
271 View Code Duplication
	public function test_disconnection_permission() {
272
273
		$this->load_rest_endpoints_direct();
274
275
		// Current user doesn't have credentials, so checking permissions should fail
276
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::disconnect_site_permission_callback() );
277
278
		$user = $this->create_and_get_user();
279
280
		// Add Jetpack capability
281
		$user->add_cap( 'jetpack_disconnect' );
282
283
		// Setup global variables so this is the current user
284
		wp_set_current_user( $user->ID );
285
286
		// User is not admin, so this should still fail
287
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::manage_modules_permission_check() );
288
289
		// Set user as admin
290
		$user->set_role( 'administrator' );
291
292
		// Reset user and setup globals again to reflect the role change.
293
		wp_set_current_user( 0 );
294
		wp_set_current_user( $user->ID );
295
296
		// User has capability so this should work this time
297
		$this->assertTrue( Jetpack_Core_Json_Api_Endpoints::disconnect_site_permission_callback() );
298
299
	}
300
301
	/**
302
	 * Test permission to activate plugins.
303
	 *
304
	 * @since 4.4.0
305
	 */
306 View Code Duplication
	public function test_plugin_activation_permission() {
307
308
		$this->load_rest_endpoints_direct();
309
310
		// Current user doesn't have credentials, so checking permissions should fail
311
		$this->assertInstanceOf( 'WP_Error', REST_Connector::activate_plugins_permission_check() );
312
313
		$user = $this->create_and_get_user();
314
315
		// Add Jetpack capability
316
		$user->add_cap( 'jetpack_admin_page' );
317
318
		// Setup global variables so this is the current user
319
		wp_set_current_user( $user->ID );
320
321
		// Should fail because requires more capabilities
322
		$this->assertInstanceOf( 'WP_Error', REST_Connector::activate_plugins_permission_check() );
323
324
		// Add Jetpack capability
325
		$user->add_cap( 'activate_plugins' );
326
		// Multisite's require additional primitive capabilities.
327
		if ( is_multisite() ) {
328
			$user->add_cap( 'manage_network_plugins' );
329
		}
330
331
		// Reset current user and setup global variables to refresh the capability we just added.
332
		wp_set_current_user( 0 );
333
		wp_set_current_user( $user->ID );
334
335
		// User has capability so this should work this time
336
		$this->assertTrue( REST_Connector::activate_plugins_permission_check() );
337
338
	}
339
340
	/**
341
	 * Test permission to disconnect Jetpack site for a user that is connected.
342
	 *
343
	 * @since 4.4.0
344
	 */
345
	public function test_admin_user_unlink_permission() {
346
347
		$this->load_rest_endpoints_direct();
348
349
		// Current user doesn't have credentials, so checking permissions should fail
350
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::unlink_user_permission_callback() );
351
352
		// Create an admin user.
353
		$user = $this->create_and_get_user( 'administrator' );
354
355
		// Add Jetpack capability
356
		$user->add_cap( 'jetpack_connect_user' );
357
358
		// Setup global variables so this is the current user
359
		wp_set_current_user( $user->ID );
360
361
		// This should still fail because user is not connected
362
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::unlink_user_permission_callback() );
363
364
		// Mock that it's connected
365
		Jetpack_Options::update_option( 'user_tokens', array( $user->ID => "honey.badger.$user->ID" ) );
366
367
		// User has the capability and is connected so this should work this time
368
		$this->assertTrue( Jetpack_Core_Json_Api_Endpoints::unlink_user_permission_callback() );
369
	}
370
371
	/**
372
	 * Test permission to manage and configure Jetpack modules.
373
	 *
374
	 * @since 4.4.0
375
	 */
376
	public function test_manage_configure_modules_permission() {
377
378
		// Current user doesn't have credentials, so checking permissions should fail
379
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::manage_modules_permission_check() );
380
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::configure_modules_permission_check() );
381
382
		// Create a user
383
		$user = $this->create_and_get_user();
384
385
		// Add Jetpack capability
386
		$user->add_cap( 'jetpack_manage_modules' );
387
		$user->add_cap( 'jetpack_configure_modules' );
388
389
		// Setup global variables so this is the current user
390
		wp_set_current_user( $user->ID );
391
392
		// User is not admin, so this should still fail
393
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::manage_modules_permission_check() );
394
		$this->assertInstanceOf( 'WP_Error', Jetpack_Core_Json_Api_Endpoints::configure_modules_permission_check() );
395
396
		// Set user as admin
397
		$user->set_role( 'administrator' );
398
399
		// Reset user and setup globals again to reflect the role change.
400
		wp_set_current_user( 0 );
401
		wp_set_current_user( $user->ID );
402
403
		// User has the capability and is connected so this should work this time
404
		$this->assertTrue( Jetpack_Core_Json_Api_Endpoints::manage_modules_permission_check() );
405
		$this->assertTrue( Jetpack_Core_Json_Api_Endpoints::configure_modules_permission_check() );
406
	}
407
408
	/**
409
	 * Test information about connection status.
410
	 *
411
	 * @since 4.4.0
412
	 */
413
	public function test_jetpack_connection_status() {
414
415
		// Mock a connection
416
		Jetpack_Options::update_option( 'id', 1234 );
417
		Jetpack_Options::update_option( 'blog_token', 'asd.qwe.1' );
418
419
		// Create REST request in JSON format and dispatch
420
		$response = $this->create_and_get_request( 'connection' );
421
422
		// Success, connected site.
423
		$this->assertResponseStatus( 200, $response );
424
		$this->assertResponseData( array(
425
			'isActive'    => true,
426
			'isStaging'   => false,
427
			'offlineMode' => array(
428
				'isActive'        => false,
429
				'constant'        => false,
430
				'url'             => false,
431
				'filter'          => false,
432
				'wpLocalConstant' => false,
433
			),
434
		), $response );
435
	}
436
437
	/**
438
	 * Test information about connection status in staging mode.
439
	 *
440
	 * @since 4.4.0
441
	 */
442
	public function test_jetpack_connection_status_staging() {
443
444
		Jetpack_Options::update_option( 'id', 1234 );
445
		Jetpack_Options::update_option( 'blog_token', 'asd.qwe.1' );
446
447
		add_filter( 'jetpack_is_staging_site', '__return_true' );
448
449
		// Create REST request in JSON format and dispatch
450
		$response = $this->create_and_get_request( 'connection' );
451
452
		// Success, connected site.
453
		$this->assertResponseStatus( 200, $response );
454
		$this->assertResponseData( array(
455
			'isActive'    => true,
456
			'isStaging'   => true,
457
			'offlineMode' => array(
458
				'isActive'        => false,
459
				'constant'        => false,
460
				'url'             => false,
461
				'filter'          => false,
462
				'wpLocalConstant' => false,
463
			),
464
		), $response );
465
466
		remove_filter( 'jetpack_is_staging_site', '__return_true' );
467
	}
468
469
	/**
470
	 * Test information about connection status in dev mode.
471
	 *
472
	 * @since 4.4.0
473
	 */
474
	public function test_jetpack_connection_status_dev() {
475
476
		// Create a user and set it up as current.
477
		$user = $this->create_and_get_user();
478
		wp_set_current_user( $user->ID );
479
480
		add_filter( 'jetpack_offline_mode', '__return_true' );
481
482
		// Create REST request in JSON format and dispatch
483
		$response = $this->create_and_get_request( 'connection' );
484
485
		// Success, authenticated user and connected site
486
		$this->assertResponseStatus( 200, $response );
487
		$this->assertResponseData( array(
488
			'isActive'    => false,
489
			'isStaging'   => false,
490
			'offlineMode' => array(
491
				'isActive'        => true,
492
				'constant'        => false,
493
				'url'             => false,
494
				'filter'          => true,
495
				'wpLocalConstant' => false,
496
			),
497
		), $response );
498
499
		remove_filter( 'jetpack_offline_mode', '__return_true' );
500
	}
501
502
	/**
503
	 * Test site disconnection with not authenticated user
504
	 *
505
	 * @since 4.4.0
506
	 */
507
	public function test_disconnect_site_noauth() {
508
509
		// Create REST request in JSON format and dispatch
510
		$response = $this->create_and_get_request( 'connection', array(), 'POST' );
511
512
		// Fails because user is not authenticated
513
		$this->assertResponseStatus( 401, $response );
514
		$this->assertResponseData( array( 'code' => 'invalid_user_permission_jetpack_disconnect' ), $response );
515
	}
516
517
	/**
518
	 * Test site disconnection with authenticated user and disconnected site
519
	 *
520
	 * @since 4.4.0
521
	 */
522 View Code Duplication
	public function test_disconnect_site_auth_noparam() {
523
524
		// Create a user and set it up as current.
525
		$user = $this->create_and_get_user( 'administrator' );
526
		wp_set_current_user( $user->ID );
527
528
		// Create REST request in JSON format and dispatch
529
		$response = $this->create_and_get_request( 'connection', array(), 'POST' );
530
531
		// Fails because user is authenticated but missing a param
532
		$this->assertResponseStatus( 404, $response );
533
		$this->assertResponseData( array( 'code' => 'invalid_param' ), $response );
534
	}
535
536
	/**
537
	 * Test site disconnection with authenticated user and disconnected site
538
	 *
539
	 * @since 4.4.0
540
	 */
541 View Code Duplication
	public function test_disconnect_site_auth_param_notconnected() {
542
543
		// Create a user and set it up as current.
544
		$user = $this->create_and_get_user( 'administrator' );
545
		wp_set_current_user( $user->ID );
546
547
		// Create REST request in JSON format and dispatch
548
		$response = $this->create_and_get_request( 'connection', array( 'isActive' => false ), 'POST' );
549
550
		// Fails because user is authenticated but site is not connected
551
		$this->assertResponseStatus( 400, $response );
552
		$this->assertResponseData( array( 'code' => 'disconnect_failed' ), $response );
553
	}
554
555
	/**
556
	 * Test site disconnection with authenticated user and connected site
557
	 *
558
	 * @since 4.4.0
559
	 */
560
	public function test_disconnect_site_auth_param_connected() {
561
562
		// Create a user and set it up as current.
563
		$user = $this->create_and_get_user( 'administrator' );
564
		wp_set_current_user( $user->ID );
565
566
		// Mock a connection
567
		Jetpack_Options::update_option( 'master_user', $user->ID );
568
		Jetpack_Options::update_option( 'id', 1234 );
569
		Jetpack_Options::update_option( 'blog_token', 'asd.qwe.1' );
570
		Jetpack_Options::update_option( 'user_tokens', array( $user->ID => "honey.badger.$user->ID" ) );
571
572
		// Create REST request in JSON format and dispatch
573
		$response = $this->create_and_get_request( 'connection', array( 'isActive' => false ), 'POST' );
574
575
		// Success, authenticated user and connected site
576
		$this->assertResponseStatus( 200, $response );
577
		$this->assertResponseData( array( 'code' => 'success' ), $response );
578
	}
579
580
	/**
581
	 * Test connection url build when there's no blog token or id.
582
	 *
583
	 * @since 4.4.0
584
	 */
585
	public function test_build_connect_url_no_blog_token_id() {
586
587
		// Create a user and set it up as current.
588
		$user = $this->create_and_get_user( 'administrator' );
589
		wp_set_current_user( $user->ID );
590
591
		// Build URL to compare scheme and host with the one in response
592
		$admin_url = wp_parse_url( admin_url() );
593
594
		// Create REST request in JSON format and dispatch
595
		$response = $this->create_and_get_request( 'connection/url' );
596
597
		// Success, URL was built
598
		$this->assertResponseStatus( 200, $response );
599
600
		// Format data to test it
601
		$response->data = wp_parse_url( $response->data );
602
		parse_str( $response->data['query'], $response->data['query'] );
603
604
		// It has a nonce
605
		$this->assertTrue( isset( $response->data['query']['_wpnonce'] ) );
606
		unset( $response->data['query']['_wpnonce'] );
607
608
		// The URL was properly built
609
		$this->assertResponseData(
610
			array(
611
				'scheme' => $admin_url['scheme'],
612
				'host'   => $admin_url['host'],
613
				'path'   => '/wp-admin/admin.php',
614
				'query'  =>
615
					array(
616
						'page'     => 'jetpack',
617
						'action'   => 'register',
618
					)
619
			), $response
620
		);
621
	}
622
623
	/**
624
	 * Test onboarding token and make sure it's a network option.
625
	 *
626
	 * @since 5.4.0
627
	 */
628
	public function test_check_onboarding_token() {
629
		$this->assertFalse( Jetpack_Options::get_option( 'onboarding' ) );
630
631
		Jetpack::create_onboarding_token();
632
633
		$this->assertTrue( Jetpack_Options::is_valid( array( 'onboarding' ) ) );
0 ignored issues
show
Documentation introduced by
array('onboarding') is of type array<integer,string,{"0":"string"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
634
		$this->assertTrue( ctype_alnum( Jetpack_Options::get_option( 'onboarding' ) ) );
635
		$this->assertTrue( in_array( 'onboarding', Jetpack_Options::get_option_names( 'network' ) ) );
636
	}
637
638
	/**
639
	 * Test connection url build when there's a blog token or id.
640
	 *
641
	 * @since 4.4.0
642
	 */
643
	public function test_build_connect_url_blog_token_and_id() {
644
645
		// Create a user and set it up as current.
646
		$user = $this->create_and_get_user( 'administrator' );
647
		wp_set_current_user( $user->ID );
648
649
		// Mock site already registered
650
		Jetpack_Options::update_option( 'blog_token', 'h0n3y.b4dg3r' );
651
		Jetpack_Options::update_option( 'id', '42' );
652
653
		// Create REST request in JSON format and dispatch
654
		$response = $this->create_and_get_request( 'connection/url' );
655
656
		// Success, URL was built
657
		$this->assertResponseStatus( 200, $response );
658
659
		$response->data = wp_parse_url( $response->data );
660
		parse_str( $response->data['query'], $response->data['query'] );
661
662
		// Because dotcom will not respond to a fake token, the method
663
		// generates a register URL
664
		$this->assertContains( 'register', $response->data['query'] );
665
666
		unset( $response->data['query'] );
667
		$this->assertResponseData(
668
			array(
669
				'scheme' => 'http',
670
				'host'   => 'example.org',
671
				'path'   => '/wp-admin/admin.php'
672
			), $response
673
		);
674
	}
675
676
	/**
677
	 * Test unlink user.
678
	 *
679
	 * @since 4.4.0
680
	 */
681
	public function test_unlink_user() {
682
683
		// Create an admin user and set it up as current.
684
		$user = $this->create_and_get_user( 'administrator' );
685
		$user->add_cap( 'jetpack_connect_user' );
686
		wp_set_current_user( $user->ID );
687
688
		// Mock site already registered
689
		Jetpack_Options::update_option( 'user_tokens', array( $user->ID => "honey.badger.$user->ID" ) );
690
691
		add_filter( 'pre_http_request', array( $this, 'mock_xmlrpc_success' ), 10, 3 );
692
693
		// Create REST request in JSON format and dispatch
694
		$response = $this->create_and_get_request( 'connection/user', array( 'linked' => false ), 'POST' );
695
696
		// Success status, users can unlink themselves
697
		$this->assertResponseStatus( 200, $response );
698
699
		// Set up user as master user
700
		Jetpack_Options::update_option( 'master_user', $user->ID );
701
702
		// Create REST request in JSON format and dispatch
703
		$response = $this->create_and_get_request( 'connection/user', array( 'linked' => false ), 'POST' );
704
705
		// User can't unlink because doesn't have permission
706
		$this->assertResponseStatus( 403, $response );
707
708
		// Add proper permission
709
		$user->set_role( 'administrator' );
710
		wp_set_current_user( 0 );
711
		wp_set_current_user( $user->ID );
712
713
		// Create REST request in JSON format and dispatch
714
		$response = $this->create_and_get_request( 'connection/user', array( 'linked' => false ), 'POST' );
715
716
		remove_filter( 'pre_http_request', array( $this, 'mock_xmlrpc_success' ), 10, 3 );
0 ignored issues
show
Unused Code introduced by
The call to remove_filter() has too many arguments starting with 3.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
717
718
		// No way. Master user can't be unlinked. This is intended
719
		$this->assertResponseStatus( 403, $response );
720
721
	}
722
723
	/** Test unlinking a user will also remove related cached data.
724
	 *
725
	 * @since 8.8.0
726
	 */
727
	public function test_unlink_user_cache_data_removal() {
728
729
		// Create an admin user and set it up as current.
730
		$user = $this->create_and_get_user( 'administrator' );
731
		$user->add_cap( 'jetpack_connect_user' );
732
		wp_set_current_user( $user->ID );
733
734
		// Mock site already registered.
735
		Jetpack_Options::update_option( 'user_tokens', array( $user->ID => "honey.badger.$user->ID" ) );
736
		// Add a dummy transient.
737
		$transient_key = "jetpack_connected_user_data_$user->ID";
738
		set_transient( $transient_key, 'dummy', DAY_IN_SECONDS );
739
740
		add_filter( 'pre_http_request', array( $this, 'mock_xmlrpc_success' ), 10, 3 );
741
742
		// Create REST request in JSON format and dispatch.
743
		$this->create_and_get_request( 'connection/user', array( 'linked' => false ), 'POST' );
744
745
		remove_filter( 'pre_http_request', array( $this, 'mock_xmlrpc_success' ), 10, 3 );
0 ignored issues
show
Unused Code introduced by
The call to remove_filter() has too many arguments starting with 3.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
746
747
		// Transient should be deleted after unlinking user.
748
		$this->assertFalse( get_transient( $transient_key ) );
749
	}
750
751
	/**
752
	 * Test that a setting using 'enum' property is saved correctly.
753
	 *
754
	 * @since 4.4.0
755
	 */
756
	public function test_setting_enum_save() {
757
758
		// Create a user and set it up as current.
759
		$user = $this->create_and_get_user( 'administrator' );
760
		$user->add_cap( 'jetpack_activate_modules' );
761
		wp_set_current_user( $user->ID );
762
763
		Jetpack::update_active_modules( array( 'carousel' ) );
764
765
		// Test endpoint that will be removed in 4.5
766
		$response = $this->create_and_get_request( 'module/carousel', array( 'carousel_background_color' => 'black' ), 'POST' );
767
		$this->assertResponseStatus( 200, $response );
768
769
		// Test endpoint that will be implemented in 4.5
770
		$response = $this->create_and_get_request( 'settings/carousel', array( 'carousel_background_color' => 'white' ), 'POST' );
771
		$this->assertResponseStatus( 200, $response );
772
773
		$response = $this->create_and_get_request( 'settings', array( 'carousel_background_color' => 'black' ), 'POST' );
774
		$this->assertResponseStatus( 200, $response );
775
776
		// It should also save correctly with a POST body that is not JSON encoded
777
		$response = $this->create_and_get_request( 'settings', array(), 'POST', array( 'carousel_background_color' => 'black' ) );
778
		$this->assertResponseStatus( 200, $response );
779
	}
780
781
	/**
782
	 * Test that an arg with array type can be saved.
783
	 *
784
	 * @since 4.4.0
785
	 */
786
	public function test_setting_array_type() {
787
788
		// Create a user and set it up as current.
789
		$user = $this->create_and_get_user( 'administrator' );
790
		$user->add_cap( 'jetpack_activate_modules' );
791
		wp_set_current_user( $user->ID );
792
793
		Jetpack::update_active_modules( array( 'sharedaddy' ) );
794
795
		// Verify that saving another thing fails
796
		$response = $this->create_and_get_request( 'settings', array( 'show' => 'post' ), 'POST' );
797
		$this->assertResponseStatus( 400, $response );
798
799
		$response = $this->create_and_get_request( 'settings', array( 'show' => array( 'post', 'page' ) ), 'POST' );
800
		$this->assertResponseStatus( 200, $response );
801
802
		// It should also work correctly with a POST body that is not JSON encoded
803
		$response = $this->create_and_get_request( 'settings', array(), 'POST',  array( 'show' => 'post' ) );
804
		$this->assertResponseStatus( 400, $response );
805
806
		$response = $this->create_and_get_request( 'settings', array(), 'POST', array( 'show' => array( 'post', 'page' ) ) );
807
		$this->assertResponseStatus( 200, $response );
808
	}
809
810
	/**
811
	 * Test that a setting is retrieved correctly.
812
	 * Here we test three types of settings:
813
	 * - module settings
814
	 * - module activation state
815
	 *
816
	 * @since 4.6.0
817
	 */
818
	public function test_settings_retrieve() {
819
820
		// Create a user and set it up as current.
821
		$user = $this->create_and_get_user( 'administrator' );
822
		$user->add_cap( 'jetpack_activate_modules' );
823
		wp_set_current_user( $user->ID );
824
825
		Jetpack::update_active_modules( array( 'carousel' ) );
826
		update_option( 'carousel_background_color', 'white' );
827
828
		$response = $this->create_and_get_request( 'settings', array(), 'GET' );
829
		$response_data = $response->get_data();
830
831
		$this->assertResponseStatus( 200, $response );
832
833
		$this->assertArrayHasKey( 'carousel_background_color', $response_data );
834
		$this->assertEquals( 'white', $response_data['carousel_background_color'] );
835
836
		$this->assertArrayHasKey( 'carousel', $response_data );
837
		$this->assertTrue( $response_data['carousel'] );
838
	}
839
840
	/**
841
	 * Test fetching milestone widget data.
842
	 *
843
	 * @since 5.5.0
844
	 */
845
	public function test_fetch_milestone_widget_data() {
846
		jetpack_register_widget_milestone();
847
848
		global $_wp_sidebars_widgets, $wp_registered_widgets;
849
850
		$widget_instances = array(
851
			3 => array(
852
				'title' => 'Ouou',
853
				'event' => 'The Biog Day',
854
				'unit' => 'years',
855
				'type' => 'until',
856
				'message' => 'The big day is here.',
857
				'year' => date( 'Y' ) + 10,
858
				'month' => date( 'm' ),
859
				'hour' => '0',
860
				'min' => '00',
861
				'day' => date( 'd' )
862
			)
863
		);
864
865
		update_option( 'widget_milestone_widget', $widget_instances );
866
867
		$sidebars = wp_get_sidebars_widgets();
868
		foreach( $sidebars as $key => $sidebar ) {
869
			$sidebars[ $key ][] = 'milestone_widget-3';
870
		}
871
		$_wp_sidebars_widgets = $sidebars;
872
		wp_set_sidebars_widgets( $sidebars );
873
874
		$wp_registered_widgets['milestone_widget-3'] = array(
875
			'name' => 'Milestone Widget',
876
			'id' => 'milestone_widget-3',
877
			'callback' => array( 'Milestone_Widget', 'widget' ),
878
			'params' => array()
879
		);
880
881
		$response = $this->create_and_get_request( 'widgets/milestone_widget-3', array(), 'GET' );
882
883
		// Should return the widget data
884
		$this->assertResponseStatus( 200, $response );
885
		$this->assertResponseData(
886
			array(
887
				'message' => '<div class="milestone-countdown"><span class="difference">10</span> <span class="label">years to go.</span></div>'
888
			),
889
			$response
890
		);
891
892
		$widget_instances[3] = array_merge(
893
			$widget_instances[3],
894
			array(
895
				'year' => date( 'Y' ) + 1,
896
				'unit' => 'months',
897
			)
898
		);
899
		update_option( 'widget_milestone_widget', $widget_instances );
900
		$response = $this->create_and_get_request( 'widgets/milestone_widget-3', array(), 'GET' );
901
902
		$this->assertResponseStatus( 200, $response );
903
		$this->assertResponseData(
904
			array(
905
				'message' => '<div class="milestone-countdown"><span class="difference">12</span> <span class="label">months to go.</span></div>'
906
			),
907
			$response
908
		);
909
910
		// Cleaning up the sidebars
911
		$sidebars = wp_get_sidebars_widgets();
912
		foreach( $sidebars as $key => $sidebar ) {
913
			$sidebars[ $key ] = array_diff( $sidebar, array( 'milestone_widget-3' ) );
914
		}
915
		$_wp_sidebars_widgets = $sidebars;
916
		wp_set_sidebars_widgets( $sidebars );
917
	}
918
919
	/**
920
	 * Test fetching a widget that does not exist.
921
	 *
922
	 * @since 5.5.0
923
	 */
924 View Code Duplication
	public function test_fetch_nonexistent_widget_data() {
925
		jetpack_register_widget_milestone();
926
927
		$response = $this->create_and_get_request( 'widgets/some_other_slug-133', array(), 'GET' );
928
929
		// Fails because there is no such widget
930
		$this->assertResponseStatus( 404, $response );
931
932
		unregister_widget( 'Milestone_Widget' );
933
	}
934
935
	/**
936
	 * Test fetching a nonexistent instance of an existing widget.
937
	 *
938
	 * @since 5.5.0
939
	 */
940 View Code Duplication
	public function test_fetch_nonexistent_widget_instance_data() {
941
		jetpack_register_widget_milestone();
942
943
		$response = $this->create_and_get_request( 'widgets/milestone_widget-333', array(), 'GET' );
944
945
		// Fails because there is no such widget instance
946
		$this->assertResponseStatus( 404, $response );
947
948
		unregister_widget( 'Milestone_Widget' );
949
	}
950
951
	/**
952
	 * Test fetching a widget that exists but has not been registered.
953
	 *
954
	 * @since 5.5.0
955
	 */
956
	public function test_fetch_not_registered_widget_data() {
957
		update_option(
958
			'widget_milestone_widget',
959
			array(
960
				3 => array(
961
					'title' => 'Ouou',
962
					'event' => 'The Biog Day',
963
				)
964
			)
965
		);
966
967
		foreach( wp_get_sidebars_widgets() as $sidebar ) {
968
			$this->assertFalse( array_search( 'milestone_widget-3', $sidebar ) );
969
		}
970
971
		$response = $this->create_and_get_request( 'widgets/milestone_widget-3', array(), 'GET' );
972
973
		// Fails because the widget is inactive
974
		$this->assertResponseStatus( 404, $response );
975
	}
976
977
	/**
978
	 * Test changing the master user.
979
	 *
980
	 * @since 6.2.0
981
	 * @since 7.7.0 No longer need to be master user to update.
982
	 */
983
	public function test_change_owner() {
984
985
		// Create a user and set it up as current.
986
		$user = $this->create_and_get_user( 'administrator' );
987
		$user->add_cap( 'jetpack_disconnect' );
988
		wp_set_current_user( $user->ID );
989
990
		// Mock site already registered
991
		Jetpack_Options::update_option( 'user_tokens', array( $user->ID => "honey.badger.$user->ID" ) );
992
993
		// Set up user as master user
994
		Jetpack_Options::update_option( 'master_user', $user->ID );
995
996
		// Attempt owner change with bad user
997
		$response = $this->create_and_get_request( 'connection/owner', array( 'owner' => 999 ), 'POST' );
998
		$this->assertResponseStatus( 400, $response );
999
1000
		// Attempt owner change to same user
1001
		$response = $this->create_and_get_request( 'connection/owner', array( 'owner' => $user->ID ), 'POST' );
1002
		$this->assertResponseStatus( 400, $response );
1003
1004
		// Create another user
1005
		$new_owner = $this->create_and_get_user( 'administrator' );
1006
		Jetpack_Options::update_option( 'user_tokens', array(
1007
			$user->ID => "honey.badger.$user->ID",
1008
			$new_owner->ID => "honey.badger.$new_owner->ID",
1009
		) );
1010
1011
		// Change owner to valid user
1012
		add_filter( 'pre_http_request', array( $this, 'mock_xmlrpc_success' ), 10, 3 );
1013
		$response = $this->create_and_get_request( 'connection/owner', array( 'owner' => $new_owner->ID ), 'POST' );
1014
		$this->assertResponseStatus( 200, $response );
1015
		$this->assertEquals( $new_owner->ID, Jetpack_Options::get_option( 'master_user' ), 'Master user not changed' );
1016
		remove_filter( 'pre_http_request', array( $this, 'mock_xmlrpc_success' ), 10 );
1017
	}
1018
1019
	/**
1020
	 * Test saving and retrieving the recommendations data.
1021
	 *
1022
	 * @since 9.3.0
1023
	 */
1024 View Code Duplication
	public function test_recommendations_data() {
1025
		// Create a user and set it up as current.
1026
		$user = $this->create_and_get_user( 'administrator' );
1027
		$user->add_cap( 'jetpack_configure_modules' );
1028
		wp_set_current_user( $user->ID );
1029
1030
		$test_data = array(
1031
			'param1' => 'val1',
1032
			'param2' => 'val2',
1033
		);
1034
1035
		$response = $this->create_and_get_request(
1036
			'recommendations/data',
1037
			array(
1038
				'data' => $test_data,
1039
			),
1040
			'POST'
1041
		);
1042
		$this->assertResponseStatus( 200, $response );
1043
		$this->assertTrue( $response->get_data() );
1044
1045
		$response = $this->create_and_get_request( 'recommendations/data', array(), 'GET' );
1046
		$this->assertResponseStatus( 200, $response );
1047
		$this->assertResponseData( $test_data, $response );
1048
	}
1049
1050
	/**
1051
	 * Test saving and retrieving the recommendations step.
1052
	 *
1053
	 * @since 9.3.0
1054
	 */
1055 View Code Duplication
	public function test_recommendations_step() {
1056
		// Create a user and set it up as current.
1057
		$user = $this->create_and_get_user( 'administrator' );
1058
		$user->add_cap( 'jetpack_configure_modules' );
1059
		wp_set_current_user( $user->ID );
1060
1061
		$test_data = 'step-1';
1062
1063
		$response = $this->create_and_get_request(
1064
			'recommendations/step',
1065
			array(
1066
				'step' => $test_data,
1067
			),
1068
			'POST'
1069
		);
1070
		$this->assertResponseStatus( 200, $response );
1071
		$this->assertTrue( $response->get_data() );
1072
1073
		$response = $this->create_and_get_request( 'recommendations/step', array(), 'GET' );
1074
		$this->assertResponseStatus( 200, $response );
1075
		$this->assertResponseData( array( 'step' => $test_data ), $response );
1076
	}
1077
1078
	/**
1079
	 * Test saving and retrieving licensing errors.
1080
	 *
1081
	 * @since 9.0.0
1082
	 */
1083
	public function test_licensing_error() {
1084
		// Create a user and set it up as current.
1085
		$user = $this->create_and_get_user( 'administrator' );
1086
		$user->add_cap( 'jetpack_admin_page' );
1087
		wp_set_current_user( $user->ID );
1088
1089
		// Should be empty by default.
1090
		$request  = new WP_REST_Request( 'GET', '/jetpack/v4/licensing/error' );
1091
		$response = $this->server->dispatch( $request );
1092
		$this->assertResponseStatus( 200, $response );
1093
		$this->assertEquals( '', $response->get_data() );
1094
1095
		// Should accept updates.
1096
		$response = $this->create_and_get_request(
1097
			'licensing/error',
1098
			array(
1099
				'error' => 'foo',
1100
			),
1101
			'POST'
1102
		);
1103
		$this->assertResponseStatus( 200, $response );
1104
		$this->assertEquals( true, $response->get_data() );
1105
1106
		// Should return updated value.
1107
		$request  = new WP_REST_Request( 'GET', '/jetpack/v4/licensing/error' );
1108
		$response = $this->server->dispatch( $request );
1109
		$this->assertResponseStatus( 200, $response );
1110
		$this->assertEquals( 'foo', $response->get_data() );
1111
	}
1112
1113
	/**
1114
	 * Test fetching user connection data without a connection owner.
1115
	 *
1116
	 * @since 9.4
1117
	 */
1118
	public function test_get_user_connection_data_without_master_user() {
1119
		// Create a user and set it up as current.
1120
		$user = $this->create_and_get_user( 'administrator' );
1121
		wp_set_current_user( $user->ID );
1122
		// No master user set.
1123
		$response = $this->create_and_get_request( 'connection/data' );
1124
		$this->assertResponseStatus( 200, $response );
1125
1126
		$response_data = $response->get_data();
1127
		$this->assertNull( $response_data['connectionOwner'] );
1128
	}
1129
1130
	/**
1131
	 * Test fetching a site's purchase token.
1132
	 *
1133
	 * @since 9.9.0
1134
	 */
1135 View Code Duplication
	public function test_get_purchase_token() {
1136
		$purchase_token = '1ApurchaseToken1';
1137
		Jetpack_Options::update_option( 'id', 1234 );
1138
		Jetpack_Options::update_option( 'purchase_token', $purchase_token );
1139
1140
		// Create a user and set it up as current.
1141
		$user = $this->create_and_get_user( 'administrator' );
1142
		wp_set_current_user( $user->ID );
1143
1144
		// Fetch purchase token.
1145
		$response = $this->create_and_get_request( 'purchase-token', array(), 'GET' );
1146
1147
		// Confirm purchase token exists.
1148
		$this->assertResponseStatus( 200, $response );
1149
		$this->assertEquals( $purchase_token, $response->get_data() );
1150
	}
1151
1152
	/**
1153
	 * Test fetching a site's purchase token with a non-administrator user.
1154
	 *
1155
	 * @since 9.9.0
1156
	 */
1157 View Code Duplication
	public function test_get_purchase_token_non_admin_user() {
1158
		$purchase_token = '1ApurchaseToken1';
1159
		Jetpack_Options::update_option( 'id', 1234 );
1160
		Jetpack_Options::update_option( 'purchase_token', $purchase_token );
1161
1162
		// Create a user and set it up as current.
1163
		$user = $this->create_and_get_user();
1164
		wp_set_current_user( $user->ID );
1165
1166
		// Fetch purchase token.
1167
		$response = $this->create_and_get_request( 'purchase-token', array(), 'GET' );
1168
1169
		// Request fails because the user doesn't have the `manage_options` permission.
1170
		$this->assertResponseStatus( 403, $response );
1171
		$this->assertResponseData( array( 'code' => 'invalid_permission_manage_purchase_token' ), $response );
1172
	}
1173
1174
	/**
1175
	 * Test fetching a site's purchase token when no site is registered.
1176
	 *
1177
	 * @since 9.9.0
1178
	 */
1179 View Code Duplication
	public function test_get_purchase_token_no_site_registered() {
1180
		$purchase_token = '1ApurchaseToken1';
1181
		Jetpack_Options::update_option( 'purchase_token', $purchase_token );
1182
1183
		// Create a user and set it up as current.
1184
		$user = $this->create_and_get_user( 'administrator' );
1185
		wp_set_current_user( $user->ID );
1186
1187
		// Fetch purchase token.
1188
		$response = $this->create_and_get_request( 'purchase-token', array(), 'GET' );
1189
1190
		// Confirm that the request failed.
1191
		$this->assertResponseStatus( 500, $response );
1192
		$this->assertResponseData( array( 'code' => 'site_not_registered' ), $response );
1193
	}
1194
1195
	/**
1196
	 * Test deleting a site's purchase token.
1197
	 *
1198
	 * @since 9.9.0
1199
	 */
1200
	public function test_delete_purchase_token() {
1201
		$purchase_token = '1ApurchaseToken1';
1202
		Jetpack_Options::update_option( 'id', 1234 );
1203
		Jetpack_Options::update_option( 'purchase_token', $purchase_token );
1204
1205
		// Create a user and set it up as current.
1206
		$user = $this->create_and_get_user( 'administrator' );
1207
		wp_set_current_user( $user->ID );
1208
1209
		// Fetch the purchase token.
1210
		$response = $this->create_and_get_request( 'purchase-token', array(), 'GET' );
1211
1212
		// Confirm the purchase token exists.
1213
		$this->assertResponseStatus( 200, $response );
1214
		$this->assertEquals( $purchase_token, $response->get_data() );
1215
1216
		// Delete the purchase token.
1217
		$response = $this->create_and_get_request( 'purchase-token', array(), 'DELETE' );
1218
1219
		$this->assertResponseStatus( 200, $response );
1220
		$this->assertTrue( $response->get_data() );
1221
1222
		// Fetch purchase token again.
1223
		$response = $this->create_and_get_request( 'purchase-token', array(), 'GET' );
1224
1225
		// Confirm the purchase token does not exist.
1226
		$this->assertResponseStatus( 200, $response );
1227
		$this->assertSame( '', $response->get_data() );
1228
	}
1229
1230
	/**
1231
	 * Test deleting a site's purchase token with a non-administrator user.
1232
	 *
1233
	 * @since 9.9.0
1234
	 */
1235 View Code Duplication
	public function test_delete_purchase_token_non_admin_user() {
1236
		$purchase_token = '1ApurchaseToken1';
1237
		Jetpack_Options::update_option( 'id', 1234 );
1238
		Jetpack_Options::update_option( 'purchase_token', $purchase_token );
1239
1240
		// Create a user and set it up as current.
1241
		$user = $this->create_and_get_user();
1242
		wp_set_current_user( $user->ID );
1243
1244
		// Fetch the purchase token.
1245
		$response = $this->create_and_get_request( 'purchase-token', array(), 'GET' );
1246
1247
		// Request fails because the user doesn't have the `manage_options` permission.
1248
		$this->assertResponseStatus( 403, $response );
1249
		$this->assertResponseData( array( 'code' => 'invalid_permission_manage_purchase_token' ), $response );
1250
	}
1251
1252
	/**
1253
	 * Test deleting a site's purchase token when no site is registered.
1254
	 *
1255
	 * @since 9.9.0
1256
	 */
1257 View Code Duplication
	public function test_delete_purchase_token_no_site_registered() {
1258
		$purchase_token = '1ApurchaseToken1';
1259
		Jetpack_Options::update_option( 'purchase_token', $purchase_token );
1260
1261
		// Create a user and set it up as current.
1262
		$user = $this->create_and_get_user( 'administrator' );
1263
		wp_set_current_user( $user->ID );
1264
1265
		// Fetch purchase token.
1266
		$response = $this->create_and_get_request( 'purchase-token', array(), 'DELETE' );
1267
1268
		// Confirm that the request failed.
1269
		$this->assertResponseStatus( 500, $response );
1270
		$this->assertResponseData( array( 'code' => 'site_not_registered' ), $response );
1271
	}
1272
} // class end
1273