Completed
Push — update/show-recurring-payments... ( 106a5e...b030b6 )
by
unknown
415:44 queued 407:29
created

ManagerTest::tear_down()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName.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\Users as WorDBless_Users;
13
use WP_Error;
14
15
/**
16
 * Connection Manager functionality testing.
17
 */
18
class ManagerTest extends TestCase {
19
20
	/**
21
	 * Temporary stack for `wp_redirect`.
22
	 *
23
	 * @var array
24
	 */
25
	protected $arguments_stack = array();
26
27
	/**
28
	 * User ID added for the test.
29
	 *
30
	 * @var int
31
	 */
32
	protected $user_id;
33
34
	const DEFAULT_TEST_CAPS = array( 'default_test_caps' );
35
36
	/**
37
	 * Initialize the object before running the test method.
38
	 *
39
	 * @before
40
	 */
41
	public function set_up() {
42
		$this->manager = $this->getMockBuilder( 'Automattic\Jetpack\Connection\Manager' )
43
			->setMethods( array( 'get_access_token', 'get_connection_owner_id' ) )
44
			->getMock();
45
46
		$this->user_id = wp_insert_user(
47
			array(
48
				'user_login' => 'test_is_user_connected_with_user_id_logged_in',
49
				'user_pass'  => '123',
50
			)
51
		);
52
		wp_set_current_user( 0 );
53
	}
54
55
	/**
56
	 * Clean up the testing environment.
57
	 *
58
	 * @after
59
	 */
60
	public function tear_down() {
61
		wp_set_current_user( 0 );
62
		WorDBless_Users::init()->clear_all_users();
63
		unset( $this->manager );
64
		Constants::clear_constants();
65
	}
66
67
	/**
68
	 * Test the `is_active` functionality when connected.
69
	 *
70
	 * @covers Automattic\Jetpack\Connection\Manager::is_active
71
	 */
72
	public function test_is_active_when_connected() {
73
		$access_token = (object) array(
74
			'secret'           => 'abcd1234',
75
			'external_user_id' => 1,
76
		);
77
		$this->manager->expects( $this->once() )
78
			->method( 'get_access_token' )
79
			->will( $this->returnValue( $access_token ) );
80
81
		$this->assertTrue( $this->manager->is_active() );
82
	}
83
84
	/**
85
	 * Test the `is_active` functionality when not connected.
86
	 *
87
	 * @covers Automattic\Jetpack\Connection\Manager::is_active
88
	 */
89
	public function test_is_active_when_not_connected() {
90
		$this->manager->expects( $this->once() )
91
			->method( 'get_access_token' )
92
			->will( $this->returnValue( false ) );
93
94
		$this->assertFalse( $this->manager->is_active() );
95
	}
96
97
	/**
98
	 * Test the `api_url` generation.
99
	 *
100
	 * @covers Automattic\Jetpack\Connection\Manager::api_url
101
	 */
102
	public function test_api_url_defaults() {
103
		add_filter( 'jetpack_constant_default_value', array( $this, 'filter_api_constant' ), 10, 2 );
104
105
		$this->assertEquals(
106
			'https://jetpack.wordpress.com/jetpack.something/1/',
107
			$this->manager->api_url( 'something' )
108
		);
109
		$this->assertEquals(
110
			'https://jetpack.wordpress.com/jetpack.another_thing/1/',
111
			$this->manager->api_url( 'another_thing/' )
112
		);
113
114
		remove_filter( 'jetpack_constant_default_value', array( $this, 'filter_api_constant' ), 10, 2 );
0 ignored issues
show
Unused Code introduced by
The call to remove_filter() has too many arguments starting with 2.

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...
115
	}
116
117
	/**
118
	 * Testing the ability of the api_url method to follow set constants and filters.
119
	 *
120
	 * @covers Automattic\Jetpack\Connection\Manager::api_url
121
	 */
122
	public function test_api_url_uses_constants_and_filters() {
123
		Constants::set_constant( 'JETPACK__API_BASE', 'https://example.com/api/base.' );
124
		Constants::set_constant( 'JETPACK__API_VERSION', '1' );
125
		$this->assertEquals(
126
			'https://example.com/api/base.something/1/',
127
			$this->manager->api_url( 'something' )
128
		);
129
130
		Constants::set_constant( 'JETPACK__API_BASE', 'https://example.com/api/another.' );
131
		Constants::set_constant( 'JETPACK__API_VERSION', '99' );
132
		$this->assertEquals(
133
			'https://example.com/api/another.something/99/',
134
			$this->manager->api_url( 'something' )
135
		);
136
137
		$overwrite_filter = function () {
138
			$this->arguments_stack['jetpack_api_url'][] = array_merge( array( 'jetpack_api_url' ), func_get_args() );
139
			return 'completely overwrite';
140
		};
141
		add_filter( 'jetpack_api_url', $overwrite_filter, 10, 4 );
142
143
		$this->assertEquals(
144
			'completely overwrite',
145
			$this->manager->api_url( 'something' )
146
		);
147
148
		// The jetpack_api_url argument stack should not be empty, making sure the filter was
149
		// called with a proper name and arguments.
150
		$call_arguments = array_pop( $this->arguments_stack['jetpack_api_url'] );
151
		$this->assertEquals( 'something', $call_arguments[2] );
152
		$this->assertEquals(
153
			Constants::get_constant( 'JETPACK__API_BASE' ),
154
			$call_arguments[3]
155
		);
156
		$this->assertEquals(
157
			'/' . Constants::get_constant( 'JETPACK__API_VERSION' ) . '/',
158
			$call_arguments[4]
159
		);
160
161
		remove_filter( 'jetpack_api_url', $overwrite_filter, 10 );
162
	}
163
164
	/**
165
	 * Test the `is_user_connected` functionality.
166
	 *
167
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
168
	 */
169
	public function test_is_user_connected_with_default_user_id_logged_out() {
170
		$this->assertFalse( $this->manager->is_user_connected() );
171
	}
172
173
	/**
174
	 * Test the `is_user_connected` functionality.
175
	 *
176
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
177
	 */
178
	public function test_is_user_connected_with_false_user_id_logged_out() {
179
		$this->assertFalse( $this->manager->is_user_connected( false ) );
180
	}
181
182
	/**
183
	 * Test the `is_user_connected` functionality
184
	 *
185
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
186
	 */
187
	public function test_is_user_connected_with_user_id_logged_out_not_connected() {
188
		$this->manager->expects( $this->once() )
189
			->method( 'get_access_token' )
190
			->will( $this->returnValue( false ) );
191
192
		$this->assertFalse( $this->manager->is_user_connected( $this->user_id ) );
193
	}
194
195
	/**
196
	 * Test the `is_user_connected` functionality.
197
	 *
198
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
199
	 */
200 View Code Duplication
	public function test_is_user_connected_with_default_user_id_logged_in() {
201
		wp_set_current_user( $this->user_id );
202
203
		$access_token = (object) array(
204
			'secret'           => 'abcd1234',
205
			'external_user_id' => 1,
206
		);
207
		$this->manager->expects( $this->once() )
208
			->method( 'get_access_token' )
209
			->will( $this->returnValue( $access_token ) );
210
211
		$this->assertTrue( $this->manager->is_user_connected() );
212
	}
213
214
	/**
215
	 * Test the `is_user_connected` functionality.
216
	 *
217
	 * @covers Automattic\Jetpack\Connection\Manager::is_user_connected
218
	 */
219 View Code Duplication
	public function test_is_user_connected_with_user_id_logged_in() {
220
		$access_token = (object) array(
221
			'secret'           => 'abcd1234',
222
			'external_user_id' => 1,
223
		);
224
		$this->manager->expects( $this->once() )
225
			->method( 'get_access_token' )
226
			->will( $this->returnValue( $access_token ) );
227
228
		$this->assertTrue( $this->manager->is_user_connected( $this->user_id ) );
229
	}
230
231
	/**
232
	 * Unit test for the "Delete all tokens" functionality.
233
	 *
234
	 * @covers Automattic\Jetpack\Connection\Manager::delete_all_connection_tokens
235
	 */
236 View Code Duplication
	public function test_delete_all_connection_tokens() {
237
		( new Plugin( 'plugin-slug-1' ) )->add( 'Plugin Name 1' );
238
239
		( new Plugin( 'plugin-slug-2' ) )->add( 'Plugin Name 2' );
240
241
		$stub = $this->createMock( Plugin::class );
242
		$stub->method( 'is_only' )
243
			->willReturn( false );
244
		$manager = ( new Manager() )->set_plugin_instance( $stub );
245
246
		$this->assertFalse( $manager->delete_all_connection_tokens() );
247
	}
248
249
	/**
250
	 * Unit test for the "Disconnect from WP" functionality.
251
	 *
252
	 * @covers Automattic\Jetpack\Connection\Manager::disconnect_site_wpcom
253
	 */
254 View Code Duplication
	public function test_disconnect_site_wpcom() {
255
		( new Plugin( 'plugin-slug-1' ) )->add( 'Plugin Name 1' );
256
257
		( new Plugin( 'plugin-slug-2' ) )->add( 'Plugin Name 2' );
258
259
		$stub = $this->createMock( Plugin::class );
260
		$stub->method( 'is_only' )
261
			->willReturn( false );
262
		$manager = ( new Manager() )->set_plugin_instance( $stub );
263
264
		$this->assertFalse( $manager->disconnect_site_wpcom() );
265
	}
266
267
	/**
268
	 * Test the `jetpack_connection_custom_caps' method.
269
	 *
270
	 * @covers Automattic\Jetpack\Connection\Manager::jetpack_connection_custom_caps
271
	 * @dataProvider jetpack_connection_custom_caps_data_provider
272
	 *
273
	 * @param bool   $in_offline_mode Whether offline mode is active.
274
	 * @param string $custom_cap The custom capability that is being tested.
275
	 * @param array  $expected_caps The expected output.
276
	 */
277
	public function test_jetpack_connection_custom_caps( $in_offline_mode, $custom_cap, $expected_caps ) {
278
		// Mock the apply_filters( 'jetpack_offline_mode', ) call in Status::is_offline_mode.
279
		add_filter(
280
			'jetpack_offline_mode',
281
			function () use ( $in_offline_mode ) {
282
				return $in_offline_mode;
283
			}
284
		);
285
286
		$caps = $this->manager->jetpack_connection_custom_caps( self::DEFAULT_TEST_CAPS, $custom_cap, 1, array() );
287
		$this->assertEquals( $expected_caps, $caps );
288
	}
289
290
	/**
291
	 * Data provider test_jetpack_connection_custom_caps.
292
	 *
293
	 * Structure of the test data arrays:
294
	 *     [0] => 'in_offline_mode'   boolean Whether offline mode is active.
295
	 *     [1] => 'custom_cap'        string The custom capability that is being tested.
296
	 *     [2] => 'expected_caps'     array The expected output of the call to jetpack_connection_custom_caps.
297
	 */
298
	public function jetpack_connection_custom_caps_data_provider() {
299
300
		return array(
301
			'offline mode, jetpack_connect'          => array( true, 'jetpack_connect', array( 'do_not_allow' ) ),
302
			'offline mode, jetpack_reconnect'        => array( true, 'jetpack_reconnect', array( 'do_not_allow' ) ),
303
			'offline mode, jetpack_disconnect'       => array( true, 'jetpack_disconnect', array( 'manage_options' ) ),
304
			'offline mode, jetpack_connect_user'     => array( true, 'jetpack_connect_user', array( 'do_not_allow' ) ),
305
			'offline mode, unknown cap'              => array( true, 'unknown_cap', self::DEFAULT_TEST_CAPS ),
306
			'not offline mode, jetpack_connect'      => array( false, 'jetpack_connect', array( 'manage_options' ) ),
307
			'not offline mode, jetpack_reconnect'    => array( false, 'jetpack_reconnect', array( 'manage_options' ) ),
308
			'not offline mode, jetpack_disconnect'   => array( false, 'jetpack_disconnect', array( 'manage_options' ) ),
309
			'not offline mode, jetpack_connect_user' => array( false, 'jetpack_connect_user', array( 'read' ) ),
310
			'not offline mode, unknown cap'          => array( false, 'unknown_cap', self::DEFAULT_TEST_CAPS ),
311
		);
312
	}
313
314
	/**
315
	 * Test the `get_signed_token` functionality.
316
	 *
317
	 * @covers Automattic\Jetpack\Connection\Manager::get_signed_token
318
	 */
319
	public function test_get_signed_token() {
320
		$access_token = (object) array(
321
			'external_user_id' => 1,
322
		);
323
324
		$manager = ( new Manager() );
325
		// Missing secret.
326
		$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...
327
		$this->assertEquals( $invalid_token_error, $manager->get_signed_token( $access_token ) );
328
		// Secret is null.
329
		$access_token->secret = null;
330
		$this->assertEquals( $invalid_token_error, $manager->get_signed_token( $access_token ) );
331
		// Secret is empty.
332
		$access_token->secret = '';
333
		$this->assertEquals( $invalid_token_error, $manager->get_signed_token( $access_token ) );
334
		// Valid secret.
335
		$access_token->secret = 'abcd.1234';
336
337
		$signed_token = $manager->get_signed_token( $access_token );
338
		$this->assertTrue( strpos( $signed_token, 'token' ) !== false );
339
		$this->assertTrue( strpos( $signed_token, 'timestamp' ) !== false );
340
		$this->assertTrue( strpos( $signed_token, 'nonce' ) !== false );
341
		$this->assertTrue( strpos( $signed_token, 'signature' ) !== false );
342
	}
343
344
	/**
345
	 * Filter to set the default constant values.
346
	 *
347
	 * @param string $value Existing value (empty and ignored).
348
	 * @param string $name Constant name.
349
	 *
350
	 * @see Utils::DEFAULT_JETPACK__API_BASE
351
	 * @see Utils::DEFAULT_JETPACK__API_VERSION
352
	 *
353
	 * @return string
354
	 */
355
	public function filter_api_constant( $value, $name ) {
356
		return constant( __NAMESPACE__ . "\Utils::DEFAULT_$name" );
357
	}
358
359
}
360