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

ManagerIntegrationTest::test_is_connected()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
nc 4
nop 3
dl 0
loc 15
rs 9.7666
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
2
/**
3
 * Connection Manager functionality testing.
4
 *
5
 * @package automattic/jetpack-connection
6
 */
7
8
namespace Automattic\Jetpack\Connection;
9
10
use Automattic\Jetpack\Constants;
11
12
/**
13
 * Connection Manager functionality testing.
14
 */
15
class ManagerIntegrationTest extends \WorDBless\BaseTestCase {
16
17
	/**
18
	 * The connection manager.
19
	 *
20
	 * @var Manager
21
	 */
22
	private $manager;
23
24
	/**
25
	 * Initialize the object before running the test method.
26
	 *
27
	 * @before
28
	 */
29
	public function set_up() {
30
		$this->manager = new Manager();
31
	}
32
33
	/**
34
	 * Test the `is_connected' method.
35
	 *
36
	 * @covers Automattic\Jetpack\Connection\Manager::is_connected
37
	 * @dataProvider is_connected_data_provider
38
	 *
39
	 * @param object|boolean $blog_token The blog token. False if the blog token does not exist.
40
	 * @param int|boolean    $blog_id The blog id. False if the blog id does not exist.
41
	 * @param boolean        $expected_output The expected output.
42
	 */
43
	public function test_is_connected( $blog_token, $blog_id, $expected_output ) {
44
		if ( $blog_token ) {
45
			\Jetpack_Options::update_option( 'blog_token', 'asdasd.123123' );
46
		} else {
47
			\Jetpack_Options::delete_option( 'blog_token' );
48
		}
49
50
		if ( $blog_id ) {
51
			\Jetpack_Options::update_option( 'id', $blog_id );
52
		} else {
53
			\Jetpack_Options::delete_option( 'id' );
54
		}
55
56
		$this->assertEquals( $expected_output, $this->manager->is_connected() );
57
	}
58
59
	/**
60
	 * Data provider for test_is_connected.
61
	 *
62
	 * Structure of the test data arrays:
63
	 *     [0] => 'blog_token'      object|boolean The blog token or false if the blog token does not exist.
64
	 *     [1] => 'blog_id'         int|boolean The blog id or false if the blog id does not exist.
65
	 *     [2] => 'expected_output' boolean The expected output of the call to is_connected.
66
	 */
67
	public function is_connected_data_provider() {
68
69
		return array(
70
			'blog token, blog id'       => array( true, 1234, true ),
71
			'blog token, no blog id'    => array( true, false, false ),
72
			'no blog token, blog id'    => array( false, 1234, false ),
73
			'no blog token, no blog id' => array( false, false, false ),
74
		);
75
	}
76
77
	/**
78
	 * Test get_connected_users
79
	 */
80
	public function test_get_connected_users() {
81
		$id_admin = wp_insert_user(
82
			array(
83
				'user_login' => 'admin',
84
				'user_pass'  => 'pass',
85
				'role'       => 'administrator',
86
			)
87
		);
88
89
		$id_author = wp_insert_user(
90
			array(
91
				'user_login' => 'author',
92
				'user_pass'  => 'pass',
93
				'role'       => 'author',
94
			)
95
		);
96
97
		\Jetpack_Options::update_option(
98
			'user_tokens',
99
			array(
100
				$id_admin  => 'asd123',
101
				$id_author => 'asd123',
102
			)
103
		);
104
105
		$all_users = $this->manager->get_connected_users();
106
		$admins    = $this->manager->get_connected_users( 'manage_options' );
107
108
		$this->assertCount( 2, $all_users );
109
		$this->assertCount( 1, $admins );
110
		$this->assertSame( $id_admin, $admins[0]->ID );
111
	}
112
113
	/**
114
	 * Test get_connection_owner and is_owner
115
	 */
116
	public function test_get_connection_owner_and_has_connected_owner() {
117
		$this->assertFalse( $this->manager->get_connection_owner() );
118
		$this->assertFalse( $this->manager->has_connected_owner() );
119
120
		$id_admin = wp_insert_user(
121
			array(
122
				'user_login' => 'admin',
123
				'user_pass'  => 'pass',
124
				'role'       => 'administrator',
125
			)
126
		);
127
128
		$id_author = wp_insert_user(
129
			array(
130
				'user_login' => 'author',
131
				'user_pass'  => 'pass',
132
				'role'       => 'author',
133
			)
134
		);
135
136
		\Jetpack_Options::update_option( 'master_user', $id_admin );
137
138
		// Before tokens are created, no owner is found.
139
		$this->assertFalse( $this->manager->get_connection_owner() );
140
		$this->assertFalse( $this->manager->has_connected_owner() );
141
142
		\Jetpack_Options::update_option(
143
			'user_tokens',
144
			array(
145
				$id_admin  => 'asd.123.' . $id_admin,
146
				$id_author => 'asd.123.' . $id_author,
147
			)
148
		);
149
150
		$owner = $this->manager->get_connection_owner();
151
152
		$this->assertInstanceOf( 'WP_User', $owner );
153
		$this->assertSame( $id_admin, $owner->ID );
154
		$this->assertTrue( $this->manager->has_connected_owner() );
155
	}
156
157
	/**
158
	 * Test has_connected_user and has_connected_admin
159
	 */
160
	public function test_has_connected_user_and_has_connected_admin() {
161
		$this->assertFalse( $this->manager->has_connected_user() );
162
		$this->assertFalse( $this->manager->has_connected_admin() );
163
164
		// Create the user.
165
		$id_author = wp_insert_user(
166
			array(
167
				'user_login' => 'author',
168
				'user_pass'  => 'pass',
169
				'role'       => 'author',
170
			)
171
		);
172
173
		$this->assertFalse( $this->manager->has_connected_user() );
174
		$this->assertFalse( $this->manager->has_connected_admin() );
175
176
		// Connect the user.
177
		\Jetpack_Options::update_option(
178
			'user_tokens',
179
			array(
180
				$id_author => 'asd.123.' . $id_author,
181
			)
182
		);
183
184
		$this->assertTrue( $this->manager->has_connected_user() );
185
		$this->assertFalse( $this->manager->has_connected_admin() );
186
187
		$id_admin = wp_insert_user(
188
			array(
189
				'user_login' => 'admin',
190
				'user_pass'  => 'pass',
191
				'role'       => 'administrator',
192
			)
193
		);
194
195
		\Jetpack_Options::update_option(
196
			'user_tokens',
197
			array(
198
				$id_admin  => 'asd.123.' . $id_admin,
199
				$id_author => 'asd.123.' . $id_author,
200
			)
201
		);
202
203
		$this->assertTrue( $this->manager->has_connected_user() );
204
		$this->assertTrue( $this->manager->has_connected_admin() );
205
206
	}
207
208
	/**
209
	 * Test is_connection_owner
210
	 */
211
	public function test_is_connection_owner() {
212
		$master_user_id = wp_insert_user(
213
			array(
214
				'user_login' => 'sample_user',
215
				'user_pass'  => 'asdqwe',
216
				'role'       => 'administrator',
217
			)
218
		);
219
		$other_user_id  = wp_insert_user(
220
			array(
221
				'user_login' => 'other_user',
222
				'user_pass'  => 'asdqwe',
223
				'role'       => 'administrator',
224
			)
225
		);
226
		\Jetpack_Options::update_option(
227
			'user_tokens',
228
			array(
229
				$master_user_id => 'asd.qwe.' . $master_user_id,
230
			)
231
		);
232
		// No owner and non-logged in user context.
233
		$this->assertFalse( $this->manager->is_connection_owner() );
234
		\Jetpack_Options::update_option( 'master_user', $master_user_id );
235
236
		$this->assertFalse( $this->manager->is_connection_owner() );
237
238
		wp_set_current_user( $master_user_id );
239
		$this->assertTrue( $this->manager->is_connection_owner() );
240
241
		wp_set_current_user( $other_user_id );
242
		$this->assertFalse( $this->manager->is_connection_owner() );
243
244
	}
245
246
	/**
247
	 * Test get_access_token method
248
	 *
249
	 * @dataProvider get_access_token_data_provider
250
	 *
251
	 * @param bool|string $create_blog_token The blog token to be created.
252
	 * @param bool|array  $create_user_tokens The user tokens to be created.
253
	 * @param bool|int    $master_user The ID of the master user to be defined.
254
	 * @param bool|int    $user_id_query The user ID that will be used to fetch the token.
255
	 * @param bool|string $token_key_query The token_key that will be used to fetch the token.
256
	 * @param bool|string $expected_error_code If an error is expected, the error code.
257
	 * @param bool|object $expected_token If success is expected, the expected token object.
258
	 * @return void
259
	 */
260
	public function test_get_access_token( $create_blog_token, $create_user_tokens, $master_user, $user_id_query, $token_key_query, $expected_error_code, $expected_token ) {
261
262
		// Set up.
263
		if ( $create_blog_token ) {
264
			\Jetpack_Options::update_option( 'blog_token', $create_blog_token );
265
			\Jetpack_Options::update_option( 'id', 1234 );
266
		}
267
		if ( $create_user_tokens ) {
268
			\Jetpack_Options::update_option( 'user_tokens', $create_user_tokens );
269
			foreach ( array_keys( $create_user_tokens ) as $uid ) {
270
				wp_insert_user(
271
					array(
272
						'user_login' => 'sample_user' . $uid,
273
						'user_pass'  => 'asdqwe',
274
					)
275
				);
276
			}
277
			if ( $master_user ) {
278
				\Jetpack_Options::update_option( 'master_user', $master_user );
279
			}
280
		}
281
282
		if ( 'CONNECTION_OWNER' === $user_id_query ) {
283
			$user_id_query = true;
284
		}
285
286
		$token = ( new Tokens() )->get_access_token( $user_id_query, $token_key_query, false );
0 ignored issues
show
Bug introduced by
It seems like $token_key_query defined by parameter $token_key_query on line 260 can also be of type boolean; however, Automattic\Jetpack\Conne...ens::get_access_token() does only seem to accept false|string, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
Bug introduced by
It seems like $user_id_query can also be of type boolean; however, Automattic\Jetpack\Conne...ens::get_access_token() does only seem to accept false|integer, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
287
288
		if ( $expected_error_code ) {
289
			$this->assertInstanceOf( 'WP_Error', $token );
290
			$this->assertSame( $expected_error_code, $token->get_error_code() );
291
		} else {
292
			$this->assertEquals( $expected_token, $token );
293
		}
294
	}
295
296
	/**
297
	 * Data provider for test_get_access_token
298
	 *
299
	 * @return array
300
	 */
301
	public function get_access_token_data_provider() {
302
		return array(
303
			'no tokens'                        => array(
304
				false, // blog token.
305
				false, // user tokens.
306
				false, // master_user.
307
				false, // user_id_query.
308
				false, // token_key_query.
309
				'no_possible_tokens', // expected error code.
310
				false, // expected token.
311
			),
312
			'no tokens'                        => array(
313
				false, // blog token.
314
				false, // user tokens.
315
				false, // master_user.
316
				22, // user_id_query.
317
				false, // token_key_query.
318
				'no_user_tokens', // expected error code.
319
				false, // expected token.
320
			),
321
			'no tokens for the user'           => array(
322
				false, // blog token.
323
				array(
324
					11 => 'asd.zxc.11',
325
				), // user tokens.
326
				false, // master_user.
327
				22, // user_id_query.
328
				false, // token_key_query.
329
				'no_token_for_user', // expected error code.
330
				false, // expected token.
331
			),
332
			'malformed user token'             => array(
333
				false, // blog token.
334
				array(
335
					11 => 'asdzxc.11',
336
				), // user tokens.
337
				false, // master_user.
338
				11, // user_id_query.
339
				false, // token_key_query.
340
				'token_malformed', // expected error code.
341
				false, // expected token.
342
			),
343
			'user mismatch'                    => array(
344
				false, // blog token.
345
				array(
346
					11 => 'asd.zxc.22',
347
				), // user tokens.
348
				false, // master_user.
349
				11, // user_id_query.
350
				false, // token_key_query.
351
				'user_id_mismatch', // expected error code.
352
				false, // expected token.
353
			),
354
			'Connection owner not defined'     => array(
355
				false, // blog token.
356
				array(
357
					11 => 'asd.zxc.11',
358
				), // user tokens.
359
				false, // master_user.
360
				'CONNECTION_OWNER', // user_id_query.
361
				false, // token_key_query.
362
				'empty_master_user_option', // expected error code.
363
				false, // expected token.
364
			),
365
			'Connection owner'                 => array(
366
				false, // blog token.
367
				array(
368
					11 => 'asd.zxc.11',
369
				), // user tokens.
370
				11, // master_user.
371
				'CONNECTION_OWNER', // user_id_query.
372
				false, // token_key_query.
373
				false, // expected error code.
374
				(object) array(
375
					'secret'           => 'asd.zxc',
376
					'external_user_id' => 11,
377
				), // expected token.
378
			),
379
			'Find blog token'                  => array(
380
				'asdasd.qweqwe', // blog token.
381
				false, // user tokens.
382
				false, // master_user.
383
				false, // user_id_query.
384
				false, // token_key_query.
385
				false, // expected error code.
386
				(object) array(
387
					'secret'           => 'asdasd.qweqwe',
388
					'external_user_id' => 0,
389
				), // expected token.
390
			),
391
			'Find user token'                  => array(
392
				false, // blog token.
393
				array(
394
					11 => 'qwe.asd.11',
395
					12 => 'asd.zxc.12',
396
				), // user tokens.
397
				false, // master_user.
398
				11, // user_id_query.
399
				false, // token_key_query.
400
				false, // expected error code.
401
				(object) array(
402
					'secret'           => 'qwe.asd',
403
					'external_user_id' => 11,
404
				), // expected token.
405
			),
406
			'Find user token with secret'      => array(
407
				false, // blog token.
408
				array(
409
					11 => 'qwe.asd.11',
410
					12 => 'asd.zxc.12',
411
				), // user tokens.
412
				false, // master_user.
413
				12, // user_id_query.
414
				'asd', // token_key_query.
415
				false, // expected error code.
416
				(object) array(
417
					'secret'           => 'asd.zxc',
418
					'external_user_id' => 12,
419
				), // expected token.
420
			),
421
			'Find blog token with secret'      => array(
422
				'asdasd.qweqwe', // blog token.
423
				false, // user tokens.
424
				false, // master_user.
425
				false, // user_id_query.
426
				'asdasd', // token_key_query.
427
				false, // expected error code.
428
				(object) array(
429
					'secret'           => 'asdasd.qweqwe',
430
					'external_user_id' => 0,
431
				), // expected token.
432
			),
433
			'Dont find user token with secret' => array(
434
				false, // blog token.
435
				array(
436
					11 => 'qwe.asd.11',
437
					12 => 'asd.zxc.12',
438
				), // user tokens.
439
				false, // master_user.
440
				12, // user_id_query.
441
				'qqq', // token_key_query.
442
				'no_valid_user_token', // expected error code.
443
				false, // expected token.
444
			),
445
			'Dont find blog token with secret' => array(
446
				'asdasd.qweqwe', // blog token.
447
				false, // user tokens.
448
				false, // master_user.
449
				false, // user_id_query.
450
				'kaasdas', // token_key_query.
451
				'no_valid_blog_token', // expected error code.
452
				false, // expected token.
453
			),
454
		);
455
	}
456
457
	/**
458
	 * Make sure we don´t change how we return errors
459
	 */
460
	public function test_get_access_token_suppress_errors() {
461
		$this->assertFalse( ( new Tokens() )->get_access_token( 123 ) );
462
		$this->assertInstanceOf( 'WP_Error', ( new Tokens() )->get_access_token( 123, '', false ) );
463
	}
464
465
	/**
466
	 * Test the `is_site_connection' method.
467
	 *
468
	 * @covers Automattic\Jetpack\Connection\Manager::is_site_connection
469
	 * @dataProvider data_provider_for_test_is_site_connection
470
	 *
471
	 * @param boolean $is_connected              If the blog is connected.
472
	 * @param boolean $has_connected_user        If the blog has a connected user.
473
	 * @param boolean $master_user_option_is_set If the master_user option is set.
474
	 * @param boolean $expected                  The expected output.
475
	 */
476
	public function test_is_site_connection( $is_connected, $has_connected_user, $master_user_option_is_set, $expected ) {
477
		$id_admin = wp_insert_user(
478
			array(
479
				'user_login' => 'admin',
480
				'user_pass'  => 'pass',
481
				'role'       => 'administrator',
482
			)
483
		);
484
485
		if ( $is_connected ) {
486
			\Jetpack_Options::update_option( 'id', 1234 );
487
			\Jetpack_Options::update_option( 'blog_token', 'asdasd.123123' );
488
		} else {
489
			\Jetpack_Options::delete_option( 'blog_token' );
490
			\Jetpack_Options::delete_option( 'id' );
491
		}
492
493
		if ( $has_connected_user ) {
494
			\Jetpack_Options::update_option(
495
				'user_tokens',
496
				array(
497
					$id_admin => 'asd123',
498
				)
499
			);
500
		} else {
501
			\Jetpack_Options::delete_option( 'user_tokens' );
502
		}
503
504
		if ( $master_user_option_is_set ) {
505
			\Jetpack_Options::update_option( 'master_user', $id_admin );
506
		} else {
507
			\Jetpack_Options::delete_option( 'master_user' );
508
		}
509
510
		$this->assertEquals( $expected, $this->manager->is_site_connection() );
511
	}
512
513
	/**
514
	 * Data provider for test_is_site_connection.
515
	 *
516
	 * Structure of the test data arrays:
517
	 *     [0] => 'is_connected'              boolean If the blog is connected.
518
	 *     [1] => 'has_connected_user'        boolean If the blog has a connected user.
519
	 *     [2] => 'master_user_option_is_set' boolean If the master_user option is set.
520
	 *     [3] => 'expected'                  boolean The expected output of the call to is_site_connection.
521
	 */
522
	public function data_provider_for_test_is_site_connection() {
523
524
		return array(
525
			'connected, has connected_user, master_user option is set'         => array( true, true, true, false ),
526
			'not connected, has connected_user, master_user option is set'     => array( false, true, true, false ),
527
			'connected, no connected_user, master_user option is set'          => array( true, false, true, false ),
528
			'not connected, no connected_user, master_user option is set'      => array( false, false, true, false ),
529
			'not connected, has connected_user, master_user option is not set' => array( false, true, false, false ),
530
			'not connected, no connected_user, master_user option is not set'  => array( false, false, false, false ),
531
			'connected, has connected_user, master_user option is not set'     => array( true, true, false, false ),
532
			'connected, no connected_user, master_user option is not set'      => array( true, false, false, true ),
533
		);
534
	}
535
536
	/**
537
	 * Test the `try_registration()` method.
538
	 *
539
	 * @see Manager::try_registration()
540
	 */
541
	public function test_try_registration() {
542
		add_filter( 'pre_http_request', array( Test_REST_Endpoints::class, 'intercept_register_request' ), 10, 3 );
543
		set_transient( 'jetpack_assumed_site_creation_date', '2021-01-01 01:01:01' );
544
		Constants::$set_constants['JETPACK__API_BASE'] = 'https://jetpack.wordpress.com/jetpack.';
545
546
		$result = $this->manager->try_registration();
547
548
		remove_filter( 'pre_http_request', array( Test_REST_Endpoints::class, 'intercept_register_request' ), 10 );
549
		delete_transient( 'jetpack_assumed_site_creation_date' );
550
551
		static::assertTrue( $result );
552
	}
553
554
}
555