Completed
Push — update/phpunit-php-8-packages ( 8ca541 )
by
unknown
91:32 queued 83:34
created

ManagerTest::setUp()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 43
rs 9.232
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A ManagerTest::tear_down() 0 7 1
A ManagerTest::test_is_active_when_connected() 0 11 1
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
use PHPUnit\Framework\TestCase;
12
use WorDBless\Options as WorDBless_Options;
13
use WorDBless\Users as WorDBless_Users;
14
use WP_Error;
15
16
/**
17
 * Connection Manager functionality testing.
18
 */
19
class ManagerTest extends TestCase {
20
21
	/**
22
	 * Temporary stack for `wp_redirect`.
23
	 *
24
	 * @var array
25
	 */
26
	protected $arguments_stack = array();
27
28
	/**
29
	 * User ID added for the test.
30
	 *
31
	 * @var int
32
	 */
33
	protected $user_id;
34
35
	const DEFAULT_TEST_CAPS = array( 'default_test_caps' );
36
37
	/**
38
	 * Initialize the object before running the test method.
39
	 *
40
	 * @before
41
	 */
42
	public function set_up() {
43
		$this->manager = $this->getMockBuilder( 'Automattic\Jetpack\Connection\Manager' )
44
			->setMethods( array( 'get_access_token' ) )
45
			->getMock();
46
47
		$this->user_id = wp_insert_user(
48
			array(
49
				'user_login' => 'test_is_user_connected_with_user_id_logged_in',
50
				'user_pass'  => '123',
51
			)
52
		);
53
		wp_set_current_user( 0 );
54
	}
55
56
	/**
57
	 * Clean up the testing environment.
58
	 *
59
	 * @after
60
	 */
61
	public function tear_down() {
62
		wp_set_current_user( 0 );
63
		WorDBless_Options::init()->clear_options();
64
		WorDBless_Users::init()->clear_all_users();
65
		unset( $this->manager );
66
		Constants::clear_constants();
67
	}
68
69
	/**
70
	 * Test the `is_active` functionality when connected.
71
	 *
72
	 * @covers Automattic\Jetpack\Connection\Manager::is_active
73
	 */
74
	public function test_is_active_when_connected() {
75
		$access_token = (object) array(
76
			'secret'           => 'abcd1234',
77
			'external_user_id' => 1,
78
		);
79
		$this->manager->expects( $this->once() )
80
			->method( 'get_access_token' )
81
			->will( $this->returnValue( $access_token ) );
82
83
		$this->assertTrue( $this->manager->is_active() );
84
	}
85
86
	/**
87
	 * Test the `is_active` functionality when not connected.
88
	 *
89
	 * @covers Automattic\Jetpack\Connection\Manager::is_active
90
	 */
91
	public function test_is_active_when_not_connected() {
92
		$this->manager->expects( $this->once() )
93
			->method( 'get_access_token' )
94
			->will( $this->returnValue( false ) );
95
96
		$this->assertFalse( $this->manager->is_active() );
97
	}
98
99
	/**
100
	 * Test the `api_url` generation.
101
	 *
102
	 * @covers Automattic\Jetpack\Connection\Manager::api_url
103
	 */
104
	public function test_api_url_defaults() {
105
		add_filter( 'jetpack_constant_default_value', array( $this, 'filter_api_constant' ), 10, 2 );
106
107
		$this->assertEquals(
108
			'https://jetpack.wordpress.com/jetpack.something/1/',
109
			$this->manager->api_url( 'something' )
110
		);
111
		$this->assertEquals(
112
			'https://jetpack.wordpress.com/jetpack.another_thing/1/',
113
			$this->manager->api_url( 'another_thing/' )
114
		);
115
116
		remove_filter( 'jetpack_constant_default_value', array( $this, 'filter_api_constant' ), 10, 2 );
117
	}
118
119
	/**
120
	 * Testing the ability of the api_url method to follow set constants and filters.
121
	 *
122
	 * @covers Automattic\Jetpack\Connection\Manager::api_url
123
	 */
124
	public function test_api_url_uses_constants_and_filters() {
125
		Constants::set_constant( 'JETPACK__API_BASE', 'https://example.com/api/base.' );
126
		Constants::set_constant( 'JETPACK__API_VERSION', '1' );
127
		$this->assertEquals(
128
			'https://example.com/api/base.something/1/',
129
			$this->manager->api_url( 'something' )
130
		);
131
132
		Constants::set_constant( 'JETPACK__API_BASE', 'https://example.com/api/another.' );
133
		Constants::set_constant( 'JETPACK__API_VERSION', '99' );
134
		$this->assertEquals(
135
			'https://example.com/api/another.something/99/',
136
			$this->manager->api_url( 'something' )
137
		);
138
139
		$overwrite_filter = function () {
140
			$this->arguments_stack['jetpack_api_url'][] = array_merge( array( 'jetpack_api_url' ), func_get_args() );
141
			return 'completely overwrite';
142
		};
143
		add_filter( 'jetpack_api_url', $overwrite_filter, 10, 4 );
144
145
		$this->assertEquals(
146
			'completely overwrite',
147
			$this->manager->api_url( 'something' )
148
		);
149
150
		// The jetpack_api_url argument stack should not be empty, making sure the filter was
151
		// called with a proper name and arguments.
152
		$call_arguments = array_pop( $this->arguments_stack['jetpack_api_url'] );
153
		$this->assertEquals( 'something', $call_arguments[2] );
154
		$this->assertEquals(
155
			Constants::get_constant( 'JETPACK__API_BASE' ),
156
			$call_arguments[3]
157
		);
158
		$this->assertEquals(
159
			'/' . Constants::get_constant( 'JETPACK__API_VERSION' ) . '/',
160
			$call_arguments[4]
161
		);
162
163
		remove_filter( 'jetpack_api_url', $overwrite_filter, 10 );
164
	}
165
166
	/**
167
	 * Test the `is_user_connected` functionality.
168
	 *
169
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
170
	 */
171
	public function test_is_user_connected_with_default_user_id_logged_out() {
172
		$this->assertFalse( $this->manager->is_user_connected() );
173
	}
174
175
	/**
176
	 * Test the `is_user_connected` functionality.
177
	 *
178
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
179
	 */
180
	public function test_is_user_connected_with_false_user_id_logged_out() {
181
		$this->assertFalse( $this->manager->is_user_connected( false ) );
182
	}
183
184
	/**
185
	 * Test the `is_user_connected` functionality
186
	 *
187
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
188
	 */
189
	public function test_is_user_connected_with_user_id_logged_out_not_connected() {
190
		$this->manager->expects( $this->once() )
191
			->method( 'get_access_token' )
192
			->will( $this->returnValue( false ) );
193
194
		$this->assertFalse( $this->manager->is_user_connected( $this->user_id ) );
195
	}
196
197
	/**
198
	 * Test the `is_user_connected` functionality.
199
	 *
200
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
201
	 */
202 View Code Duplication
	public function test_is_user_connected_with_default_user_id_logged_in() {
203
		wp_set_current_user( $this->user_id );
204
205
		$access_token = (object) array(
206
			'secret'           => 'abcd1234',
207
			'external_user_id' => 1,
208
		);
209
		$this->manager->expects( $this->once() )
210
			->method( 'get_access_token' )
211
			->will( $this->returnValue( $access_token ) );
212
213
		$this->assertTrue( $this->manager->is_user_connected() );
214
	}
215
216
	/**
217
	 * Test the `is_user_connected` functionality.
218
	 *
219
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
220
	 */
221 View Code Duplication
	public function test_is_user_connected_with_user_id_logged_in() {
222
		$access_token = (object) array(
223
			'secret'           => 'abcd1234',
224
			'external_user_id' => 1,
225
		);
226
		$this->manager->expects( $this->once() )
227
			->method( 'get_access_token' )
228
			->will( $this->returnValue( $access_token ) );
229
230
		$this->assertTrue( $this->manager->is_user_connected( $this->user_id ) );
231
	}
232
233
	/**
234
	 * Unit test for the "Delete all tokens" functionality.
235
	 *
236
	 * @covers Automattic\Jetpack\Connection\Manager::delete_all_connection_tokens
237
	 */
238 View Code Duplication
	public function test_delete_all_connection_tokens() {
239
		( new Plugin( 'plugin-slug-1' ) )->add( 'Plugin Name 1' );
240
241
		( new Plugin( 'plugin-slug-2' ) )->add( 'Plugin Name 2' );
242
243
		$stub = $this->createMock( Plugin::class );
244
		$stub->method( 'is_only' )
245
			->willReturn( false );
246
		$manager = ( new Manager() )->set_plugin_instance( $stub );
247
248
		$this->assertFalse( $manager->delete_all_connection_tokens() );
249
	}
250
251
	/**
252
	 * Unit test for the "Disconnect from WP" functionality.
253
	 *
254
	 * @covers Automattic\Jetpack\Connection\Manager::disconnect_site_wpcom
255
	 */
256 View Code Duplication
	public function test_disconnect_site_wpcom() {
257
		( new Plugin( 'plugin-slug-1' ) )->add( 'Plugin Name 1' );
258
259
		( new Plugin( 'plugin-slug-2' ) )->add( 'Plugin Name 2' );
260
261
		$stub = $this->createMock( Plugin::class );
262
		$stub->method( 'is_only' )
263
			->willReturn( false );
264
		$manager = ( new Manager() )->set_plugin_instance( $stub );
265
266
		$this->assertFalse( $manager->disconnect_site_wpcom() );
267
	}
268
269
	/**
270
	 * Test the `jetpack_connection_custom_caps' method.
271
	 *
272
	 * @covers Automattic\Jetpack\Connection\Manager::jetpack_connection_custom_caps
273
	 * @dataProvider jetpack_connection_custom_caps_data_provider
274
	 *
275
	 * @param bool   $in_offline_mode Whether offline mode is active.
276
	 * @param string $custom_cap The custom capability that is being tested.
277
	 * @param array  $expected_caps The expected output.
278
	 */
279
	public function test_jetpack_connection_custom_caps( $in_offline_mode, $custom_cap, $expected_caps ) {
280
		// Mock the apply_filters( 'jetpack_offline_mode', ) call in Status::is_offline_mode.
281
		add_filter(
282
			'jetpack_offline_mode',
283
			function () use ( $in_offline_mode ) {
284
				return $in_offline_mode;
285
			}
286
		);
287
288
		$caps = $this->manager->jetpack_connection_custom_caps( self::DEFAULT_TEST_CAPS, $custom_cap, 1, array() );
289
		$this->assertEquals( $expected_caps, $caps );
290
	}
291
292
	/**
293
	 * Data provider test_jetpack_connection_custom_caps.
294
	 *
295
	 * Structure of the test data arrays:
296
	 *     [0] => 'in_offline_mode'   boolean Whether offline mode is active.
297
	 *     [1] => 'custom_cap'        string The custom capability that is being tested.
298
	 *     [2] => 'expected_caps'     array The expected output of the call to jetpack_connection_custom_caps.
299
	 */
300
	public function jetpack_connection_custom_caps_data_provider() {
301
302
		return array(
303
			'offline mode, jetpack_connect'          => array( true, 'jetpack_connect', array( 'do_not_allow' ) ),
304
			'offline mode, jetpack_reconnect'        => array( true, 'jetpack_reconnect', array( 'do_not_allow' ) ),
305
			'offline mode, jetpack_disconnect'       => array( true, 'jetpack_disconnect', array( 'manage_options' ) ),
306
			'offline mode, jetpack_connect_user'     => array( true, 'jetpack_connect_user', array( 'do_not_allow' ) ),
307
			'offline mode, unknown cap'              => array( true, 'unknown_cap', self::DEFAULT_TEST_CAPS ),
308
			'not offline mode, jetpack_connect'      => array( false, 'jetpack_connect', array( 'manage_options' ) ),
309
			'not offline mode, jetpack_reconnect'    => array( false, 'jetpack_reconnect', array( 'manage_options' ) ),
310
			'not offline mode, jetpack_disconnect'   => array( false, 'jetpack_disconnect', array( 'manage_options' ) ),
311
			'not offline mode, jetpack_connect_user' => array( false, 'jetpack_connect_user', array( 'read' ) ),
312
			'not offline mode, unknown cap'          => array( false, 'unknown_cap', self::DEFAULT_TEST_CAPS ),
313
		);
314
	}
315
316
	/**
317
	 * Test the `is_registered' method.
318
	 *
319
	 * @covers Automattic\Jetpack\Connection\Manager::is_registered
320
	 * @dataProvider is_registered_data_provider
321
	 *
322
	 * @param object|boolean $blog_token The blog token. False if the blog token does not exist.
323
	 * @param int|boolean    $blog_id The blog id. False if the blog id does not exist.
324
	 * @param boolean        $expected_output The expected output.
325
	 */
326
	public function test_is_registered( $blog_token, $blog_id, $expected_output ) {
327
		$this->manager->expects( $this->once() )
328
			->method( 'get_access_token' )
329
			->will( $this->returnValue( $blog_token ) );
330
331
		if ( $blog_id ) {
332
			update_option( 'jetpack_options', array( 'id' => $blog_id ) );
333
		} else {
334
			update_option( 'jetpack_options', array() );
335
		}
336
337
		$this->assertEquals( $expected_output, $this->manager->is_registered() );
338
	}
339
340
	/**
341
	 * Data provider for test_is_registered.
342
	 *
343
	 * Structure of the test data arrays:
344
	 *     [0] => 'blog_token'      object|boolean The blog token or false if the blog token does not exist.
345
	 *     [1] => 'blog_id'         int|boolean The blog id or false if the blog id does not exist.
346
	 *     [2] => 'expected_output' boolean The expected output of the call to is_registered.
347
	 */
348
	public function is_registered_data_provider() {
349
		$access_token = (object) array(
350
			'secret'           => 'abcd1234',
351
			'external_user_id' => 1,
352
		);
353
354
		return array(
355
			'blog token, blog id'       => array( $access_token, 1234, true ),
356
			'blog token, no blog id'    => array( $access_token, false, false ),
357
			'no blog token, blog id'    => array( false, 1234, false ),
358
			'no blog token, no blog id' => array( false, false, false ),
359
		);
360
	}
361
362
	/**
363
	 * Test the `get_signed_token` functionality.
364
	 *
365
	 * @covers Automattic\Jetpack\Connection\Manager::get_signed_token
366
	 */
367
	public function test_get_signed_token() {
368
		$access_token = (object) array(
369
			'external_user_id' => 1,
370
		);
371
372
		$manager = ( new Manager() );
373
		// Missing secret.
374
		$invalid_token_error = new WP_Error( 'invalid_token' );
0 ignored issues
show
Unused Code introduced by
The call to WP_Error::__construct() has too many arguments starting with 'invalid_token'.

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...
375
		$this->assertEquals( $invalid_token_error, $manager->get_signed_token( $access_token ) );
376
		// Secret is null.
377
		$access_token->secret = null;
378
		$this->assertEquals( $invalid_token_error, $manager->get_signed_token( $access_token ) );
379
		// Secret is empty.
380
		$access_token->secret = '';
381
		$this->assertEquals( $invalid_token_error, $manager->get_signed_token( $access_token ) );
382
		// Valid secret.
383
		$access_token->secret = 'key.abcd1234';
384
385
		$signed_token = $manager->get_signed_token( $access_token );
386
		$this->assertTrue( strpos( $signed_token, 'token' ) !== false );
387
		$this->assertTrue( strpos( $signed_token, 'timestamp' ) !== false );
388
		$this->assertTrue( strpos( $signed_token, 'nonce' ) !== false );
389
		$this->assertTrue( strpos( $signed_token, 'signature' ) !== false );
390
	}
391
392
	/**
393
	 * Filter to set the default constant values.
394
	 *
395
	 * @param string $value Existing value (empty and ignored).
396
	 * @param string $name Constant name.
397
	 *
398
	 * @see Utils::DEFAULT_JETPACK__API_BASE
399
	 * @see Utils::DEFAULT_JETPACK__API_VERSION
400
	 *
401
	 * @return string
402
	 */
403
	public function filter_api_constant( $value, $name ) {
404
		return constant( __NAMESPACE__ . "\Utils::DEFAULT_$name" );
405
	}
406
407
}
408