Completed
Push — update/xmlrpc_methods_visibili... ( 4deffa...c66ca4 )
by
unknown
453:46 queued 443:50
created

Jetpack_XMLRPC_Server_Test   A

Complexity

Total Complexity 26

Size/Duplication

Total Lines 430
Duplicated Lines 13.49 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
dl 58
loc 430
rs 10
c 0
b 0
f 0
wmc 26
lcom 1
cbo 3

20 Methods

Rating   Name   Duplication   Size   Complexity  
A set_up() 0 14 1
A test_xmlrpc_get_user_by_id() 8 8 1
A test_xmlrpc_get_user_by_user_login() 8 8 1
A test_xmlrpc_get_user_by_user_email() 8 8 1
A test_xmlrpc_get_user_invalid_input() 9 9 1
A test_xmlrpc_get_user_no_matching_user() 9 9 1
A assertGetUserEqual() 0 8 1
A test_xmlrpc_remote_register_nonce_validation() 0 29 2
A test_successful_remote_register_return() 0 19 1
A test_remote_connect_error_when_site_active() 0 34 2
A test_remote_connect_empty_nonce() 0 17 1
A test_remote_connect_fails_no_blog_token() 0 22 1
A test_remote_connect_nonce_validation_error() 0 26 1
A test_remote_connect_success() 0 19 1
A return_ok_status() 0 9 1
A return_invalid_nonce_status() 0 9 1
A return_nonce_404_status() 0 9 1
A get_mocked_ixr_client() 0 25 5
A get_mocked_xmlrpc_server() 0 15 1
A test_remote_connect_error_invalid_user() 16 18 1

How to fix   Duplicated Code   

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:

1
<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase
2
/**
3
 * Tests the Legacy Jetpack_XMLRPC_Server class.
4
 */
5
6
use Automattic\Jetpack\Connection\Tokens;
7
use WorDBless\BaseTestCase;
8
9
/**
10
 * Class to test the legacy Jetpack_XMLRPC_Server class.
11
 */
12
class Jetpack_XMLRPC_Server_Test extends BaseTestCase {
13
14
	use \Yoast\PHPUnitPolyfills\Polyfills\AssertStringContains;
15
16
	/**
17
	 * The test user ID
18
	 *
19
	 * @var integer
20
	 */
21
	protected $xmlrpc_admin = 0;
22
23
	/**
24
	 * Set up before each test
25
	 *
26
	 * @before
27
	 */
28
	protected function set_up() {
29
		parent::setUp();
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (setUp() instead of set_up()). Are you sure this is correct? If so, you might want to change this to $this->setUp().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
30
		$user_id = wp_insert_user(
31
			array(
32
				'user_login' => 'admin',
33
				'user_pass'  => 'pass',
34
				'user_email' => '[email protected]',
35
				'role'       => 'administrator',
36
			)
37
		);
38
		( new Tokens() )->update_user_token( $user_id, sprintf( '%s.%s.%d', 'key', 'private', $user_id ), false );
39
40
		$this->xmlrpc_admin = $user_id;
41
	}
42
43
	/**
44
	 * Test test_xmlrpc_get_user_by_id
45
	 */
46 View Code Duplication
	public function test_xmlrpc_get_user_by_id() {
47
		$user   = get_user_by( 'id', $this->xmlrpc_admin );
48
		$server = new Jetpack_XMLRPC_Server();
49
50
		$response = $server->get_user( $user->ID );
51
		$this->assertGetUserEqual( $user, $response );
52
		$this->assertEquals( 'key', $response['token_key'] );
53
	}
54
55
	/**
56
	 * Test test_xmlrpc_get_user_by_id
57
	 */
58 View Code Duplication
	public function test_xmlrpc_get_user_by_user_login() {
59
		$user   = get_user_by( 'id', $this->xmlrpc_admin );
60
		$server = new Jetpack_XMLRPC_Server();
61
62
		$response = $server->get_user( $user->user_login );
63
		$this->assertGetUserEqual( $user, $response );
64
		$this->assertEquals( 'key', $response['token_key'] );
65
	}
66
67
	/**
68
	 * Test test_xmlrpc_get_user_by_id
69
	 */
70 View Code Duplication
	public function test_xmlrpc_get_user_by_user_email() {
71
		$user   = get_user_by( 'id', $this->xmlrpc_admin );
72
		$server = new Jetpack_XMLRPC_Server();
73
74
		$response = $server->get_user( $user->user_email );
75
		$this->assertGetUserEqual( $user, $response );
76
		$this->assertEquals( 'key', $response['token_key'] );
77
	}
78
79
	/**
80
	 * Test test_xmlrpc_get_user_by_id
81
	 */
82 View Code Duplication
	public function test_xmlrpc_get_user_invalid_input() {
83
		$server = new Jetpack_XMLRPC_Server();
84
85
		$missing_response = $server->get_user( '' );
86
87
		$this->assertEquals( 'IXR_Error', get_class( $missing_response ) );
88
		$this->assertEquals( 400, $missing_response->code );
89
		$this->assertEquals( 'Jetpack: [invalid_user] Invalid user identifier.', $missing_response->message );
90
	}
91
92
	/**
93
	 * Test test_xmlrpc_get_user_by_id
94
	 */
95 View Code Duplication
	public function test_xmlrpc_get_user_no_matching_user() {
96
		$server = new Jetpack_XMLRPC_Server();
97
98
		$missing_response = $server->get_user( '[email protected]' );
99
100
		$this->assertEquals( 'IXR_Error', get_class( $missing_response ) );
101
		$this->assertEquals( 404, $missing_response->code );
102
		$this->assertEquals( 'Jetpack: [user_unknown] User not found.', $missing_response->message );
103
	}
104
105
	/**
106
	 * Test test_xmlrpc_get_user_by_id
107
	 *
108
	 * @param WP_User $user The user object.
109
	 * @param array   $response XMLRPC response.
110
	 * @return void
111
	 */
112
	protected function assertGetUserEqual( $user, $response ) {
113
		$this->assertEquals( $user->ID, $response['id'] );
114
		$this->assertEquals( md5( strtolower( trim( $user->user_email ) ) ), $response['email_hash'] );
115
		$this->assertEquals( $user->user_login, $response['login'] );
116
		$this->assertEquals( sort( $user->roles ), sort( $response['roles'] ) );
117
		$this->assertEquals( sort( $user->caps ), sort( $response['caps'] ) );
118
		$this->assertEquals( sort( $user->allcaps ), sort( $response['allcaps'] ) );
119
	}
120
121
	/**
122
	 * Test test_xmlrpc_get_user_by_id
123
	 */
124
	public function test_xmlrpc_remote_register_nonce_validation() {
125
		$server  = new Jetpack_XMLRPC_Server();
126
		$filters = array(
127
			'return_invalid_nonce_status' => array(
128
				'code'    => 400,
129
				'message' => 'invalid_nonce',
130
			),
131
			'return_nonce_404_status'     => array(
132
				'code'    => 400,
133
				'message' => 'invalid_nonce',
134
			),
135
		);
136
137
		foreach ( $filters as $filter => $expected ) {
138
			add_filter( 'pre_http_request', array( $this, $filter ) );
139
			$response = $server->remote_register(
140
				array(
141
					'nonce'      => '12345',
142
					'local_user' => $this->xmlrpc_admin,
143
				)
144
			);
145
			remove_filter( 'pre_http_request', array( $this, $filter ) );
146
147
			$this->assertInstanceOf( 'IXR_Error', $response );
148
			$this->assertEquals( $expected['code'], $response->code );
149
150
			$this->assertStringContainsString( sprintf( '[%s]', $expected['message'] ), $response->message );
151
		}
152
	}
153
154
	/**
155
	 * Test test_xmlrpc_get_user_by_id
156
	 */
157
	public function test_successful_remote_register_return() {
158
		$server = new Jetpack_XMLRPC_Server();
159
160
		// Set these so that we don't try to register unnecessarily.
161
		Jetpack_Options::update_option( 'blog_token', 1 );
162
		Jetpack_Options::update_option( 'id', 1001 );
163
164
		add_filter( 'pre_http_request', array( $this, 'return_ok_status' ) );
165
		$response = $server->remote_register(
166
			array(
167
				'nonce'      => '12345',
168
				'local_user' => $this->xmlrpc_admin,
169
			)
170
		);
171
		remove_filter( 'pre_http_request', array( $this, 'return_ok_status' ) );
172
173
		$this->assertArrayHasKey( 'client_id', $response );
174
		$this->assertEquals( 1001, $response['client_id'] );
175
	}
176
177
	/**
178
	 * Test test_xmlrpc_get_user_by_id
179
	 */
180
	public function test_remote_connect_error_when_site_active() {
181
		// Simulate the site being active.
182
		Jetpack_Options::update_options(
183
			array(
184
				'blog_token' => 1,
185
				'id'         => 1001,
186
			)
187
		);
188
		( new Tokens() )->update_user_token( 1, sprintf( '%s.%d', 'token', 1 ), true );
189
190
		try {
191
			$server = new Jetpack_XMLRPC_Server();
192
193
			$response = $server->remote_connect(
194
				array(
195
					'nonce'      => '1234',
196
					'local_user' => $this->xmlrpc_admin,
197
				)
198
			);
199
200
			$this->assertInstanceOf( 'IXR_Error', $response );
201
			$this->assertObjectHasAttribute( 'code', $response );
202
			$this->assertObjectHasAttribute( 'message', $response );
203
			$this->assertEquals( 400, $response->code );
204
			$this->assertEquals(
205
				'Jetpack: [token_fetch_failed] Failed to fetch user token from WordPress.com.',
206
				$response->message
207
			);
208
		} finally {
209
			foreach ( array( 'blog_token', 'id', 'master_user', 'user_tokens' ) as $option_name ) {
210
				Jetpack_Options::delete_option( $option_name );
211
			}
212
		}
213
	}
214
215
	/**
216
	 * Test test_xmlrpc_get_user_by_id
217
	 */
218 View Code Duplication
	public function test_remote_connect_error_invalid_user() {
219
		$server   = new Jetpack_XMLRPC_Server();
220
		$response = $server->remote_connect(
221
			array(
222
				'nonce'      => '1234',
223
				'local_user' => '100000000',
224
			)
225
		);
226
227
		$this->assertInstanceOf( 'IXR_Error', $response );
228
		$this->assertObjectHasAttribute( 'code', $response );
229
		$this->assertObjectHasAttribute( 'message', $response );
230
		$this->assertEquals( 400, $response->code );
231
		$this->assertEquals(
232
			'Jetpack: [input_error] Valid user is required.',
233
			$response->message
234
		);
235
	}
236
237
	/**
238
	 * Test test_xmlrpc_get_user_by_id
239
	 */
240
	public function test_remote_connect_empty_nonce() {
241
		$server   = new Jetpack_XMLRPC_Server();
242
		$response = $server->remote_connect(
243
			array(
244
				'local_user' => $this->xmlrpc_admin,
245
			)
246
		);
247
248
		$this->assertInstanceOf( 'IXR_Error', $response );
249
		$this->assertObjectHasAttribute( 'code', $response );
250
		$this->assertObjectHasAttribute( 'message', $response );
251
		$this->assertEquals( 400, $response->code );
252
		$this->assertEquals(
253
			'Jetpack: [input_error] A non-empty nonce must be supplied.',
254
			$response->message
255
		);
256
	}
257
258
	/**
259
	 * Test test_xmlrpc_get_user_by_id
260
	 */
261
	public function test_remote_connect_fails_no_blog_token() {
262
		Jetpack_Options::delete_option( 'blog_token' );
263
264
		$server = new Jetpack_XMLRPC_Server();
265
266
		add_filter( 'pre_http_request', array( $this, '__return_token' ) );
267
		$response = $server->remote_connect(
268
			array(
269
				'nonce'      => '1234',
270
				'local_user' => $this->xmlrpc_admin,
271
			)
272
		);
273
274
		$this->assertInstanceOf( 'IXR_Error', $response );
275
		$this->assertObjectHasAttribute( 'code', $response );
276
		$this->assertObjectHasAttribute( 'message', $response );
277
		$this->assertEquals( 400, $response->code );
278
		$this->assertEquals(
279
			'Jetpack: [token_fetch_failed] Failed to fetch user token from WordPress.com.',
280
			$response->message
281
		);
282
	}
283
284
	/**
285
	 * Test test_xmlrpc_get_user_by_id
286
	 */
287
	public function test_remote_connect_nonce_validation_error() {
288
		Jetpack_Options::update_options(
289
			array(
290
				'id'         => 1001,
291
				'blog_token' => '123456.123456',
292
			)
293
		);
294
295
		$server   = $this->get_mocked_xmlrpc_server();
296
		$response = $server->remote_connect(
297
			array(
298
				'nonce'      => '1234',
299
				'local_user' => $this->xmlrpc_admin,
300
			),
301
			$this->get_mocked_ixr_client( true, false )
302
		);
303
304
		$this->assertInstanceOf( 'IXR_Error', $response );
305
		$this->assertObjectHasAttribute( 'code', $response );
306
		$this->assertObjectHasAttribute( 'message', $response );
307
		$this->assertEquals( 400, $response->code );
308
		$this->assertEquals(
309
			'Jetpack: [token_fetch_failed] Failed to fetch user token from WordPress.com.',
310
			$response->message
311
		);
312
	}
313
314
	/**
315
	 * Test test_xmlrpc_get_user_by_id
316
	 */
317
	public function test_remote_connect_success() {
318
		Jetpack_Options::update_options(
319
			array(
320
				'id'         => 1001,
321
				'blog_token' => '123456.123456',
322
			)
323
		);
324
325
		$server   = $this->get_mocked_xmlrpc_server();
326
		$response = $server->remote_connect(
327
			array(
328
				'nonce'      => '1234',
329
				'local_user' => $this->xmlrpc_admin,
330
			),
331
			$this->get_mocked_ixr_client( true, 'this_is.a_token' )
332
		);
333
334
		$this->assertTrue( $response );
335
	}
336
337
	/*
338
	 * Helpers
339
	 */
340
341
	/**
342
	 * Return an "ok" status.
343
	 *
344
	 * @return array
345
	 */
346
	public function return_ok_status() {
347
		return array(
348
			'body'     => 'OK',
349
			'response' => array(
350
				'code'    => 200,
351
				'message' => '',
352
			),
353
		);
354
	}
355
356
	/**
357
	 * Return an "invalid nonce" status.
358
	 *
359
	 * @return array
360
	 */
361
	public function return_invalid_nonce_status() {
362
		return array(
363
			'body'     => 'FAIL: NOT OK',
364
			'response' => array(
365
				'code'    => 200,
366
				'message' => '',
367
			),
368
		);
369
	}
370
371
	/**
372
	 * Return an "nonce 404" status.
373
	 *
374
	 * @return array
375
	 */
376
	public function return_nonce_404_status() {
377
		return array(
378
			'body'     => '',
379
			'response' => array(
380
				'code'    => 404,
381
				'message' => '',
382
			),
383
		);
384
	}
385
386
	/**
387
	 * Get a mocked IXR client.
388
	 *
389
	 * @param bool   $query_called Whether `query` should be called.
390
	 * @param string $response Return value for `getResponse`.
391
	 * @param bool   $query_return Return value for `query`.
392
	 * @param string $error Return value for `isError`.
0 ignored issues
show
Documentation introduced by
Should the type for parameter $error not be string|null?

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...
393
	 * @return Jetpack_IXR_Client
394
	 */
395
	protected function get_mocked_ixr_client( $query_called = false, $response = '', $query_return = true, $error = null ) {
396
		$xml = $this->getMockBuilder( 'Jetpack_IXR_Client' )
397
			->setMethods(
398
				array(
399
					'query',
400
					'isError',
401
					'getResponse',
402
				)
403
			)
404
			->getMock();
405
406
		$xml->expects( $this->exactly( $query_called ? 1 : 0 ) )
407
			->method( 'query' )
408
			->will( $this->returnValue( $query_return ) );
409
410
		$xml->expects( $this->exactly( $query_called ? 1 : 0 ) )
411
			->method( 'isError' )
412
			->will( $this->returnValue( empty( $error ) ? false : true ) );
413
414
		$xml->expects( $this->exactly( $error ? 0 : 1 ) )
415
			->method( 'getResponse' )
416
			->will( $this->returnValue( $response ) );
417
418
		return $xml;
419
	}
420
421
	/**
422
	 * Get a mocked XMLRPC server.
423
	 *
424
	 * @return Jetpack_XMLRPC_Server
425
	 */
426
	protected function get_mocked_xmlrpc_server() {
427
		$server = $this->getMockBuilder( 'Jetpack_XMLRPC_Server' )
428
			->setMethods(
429
				array(
430
					'do_post_authorization',
431
				)
432
			)
433
			->getMock();
434
435
		$server->expects( $this->any() )
436
			->method( 'do_post_authorization' )
437
			->will( $this->returnValue( true ) );
438
439
		return $server;
440
	}
441
}
442