Completed
Push — try/add-jetpack-purchase-token ( a226ea...b55274 )
by
unknown
22:36 queued 12:39
created

WP_Test_Jetpack_REST_API_endpoints   F

Complexity

Total Complexity 58

Size/Duplication

Total Lines 1208
Duplicated Lines 16.64 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
dl 201
loc 1208
rs 3.36
c 0
b 0
f 0
wmc 58
lcom 1
cbo 4

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