Completed
Branch develop (a2474f)
by
unknown
02:30
created

test_get_items_orderby_slug()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 25
Code Lines 20

Duplication

Lines 25
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
eloc 20
nc 1
nop 0
dl 25
loc 25
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * Unit tests covering WP_REST_Users_Controller functionality.
4
 *
5
 * @package WordPress
6
 * @subpackage JSON API
7
 */
8
9
class WP_Test_REST_Users_Controller extends WP_Test_REST_Controller_Testcase {
10
	/**
11
	 * This function is run before each method
12
	 */
13
	public function setUp() {
14
		parent::setUp();
15
16
		$this->user = $this->factory->user->create( array(
17
			'role' => 'administrator',
18
		) );
19
20
		$this->editor = $this->factory->user->create( array(
21
			'role'       => 'editor',
22
			'user_email' => '[email protected]',
23
		) );
24
25
		$this->endpoint = new WP_REST_Users_Controller();
26
	}
27
28 View Code Duplication
	public function test_register_routes() {
29
		$routes = $this->server->get_routes();
30
31
		$this->assertArrayHasKey( '/wp/v2/users', $routes );
32
		$this->assertCount( 2, $routes['/wp/v2/users'] );
33
		$this->assertArrayHasKey( '/wp/v2/users/(?P<id>[\d]+)', $routes );
34
		$this->assertCount( 3, $routes['/wp/v2/users/(?P<id>[\d]+)'] );
35
		$this->assertArrayHasKey( '/wp/v2/users/me', $routes );
36
	}
37
38 View Code Duplication
	public function test_context_param() {
39
		// Collection
40
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users' );
41
		$response = $this->server->dispatch( $request );
42
		$data = $response->get_data();
43
		$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );
44
		$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );
45
		// Single
46
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users/' . $this->user );
47
		$response = $this->server->dispatch( $request );
48
		$data = $response->get_data();
49
		$this->assertEquals( 'view', $data['endpoints'][0]['args']['context']['default'] );
50
		$this->assertEquals( array( 'view', 'embed', 'edit' ), $data['endpoints'][0]['args']['context']['enum'] );
51
	}
52
53 View Code Duplication
	public function test_registered_query_params() {
54
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users' );
55
		$response = $this->server->dispatch( $request );
56
		$data = $response->get_data();
57
		$keys = array_keys( $data['endpoints'][0]['args'] );
58
		sort( $keys );
59
		$this->assertEquals( array(
60
			'context',
61
			'exclude',
62
			'include',
63
			'offset',
64
			'order',
65
			'orderby',
66
			'page',
67
			'per_page',
68
			'roles',
69
			'search',
70
			'slug',
71
			), $keys );
72
	}
73
74 View Code Duplication
	public function test_get_items() {
75
		wp_set_current_user( $this->user );
76
77
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
78
		$request->set_param( 'context', 'view' );
79
		$response = $this->server->dispatch( $request );
80
81
		$this->assertEquals( 200, $response->get_status() );
82
83
		$all_data = $response->get_data();
84
		$data = $all_data[0];
85
		$userdata = get_userdata( $data['id'] );
86
		$this->check_user_data( $userdata, $data, 'view', $data['_links'] );
87
	}
88
89 View Code Duplication
	public function test_get_items_with_edit_context() {
90
		wp_set_current_user( $this->user );
91
92
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
93
		$request->set_param( 'context', 'edit' );
94
		$response = $this->server->dispatch( $request );
95
96
		$this->assertEquals( 200, $response->get_status() );
97
98
		$all_data = $response->get_data();
99
		$data = $all_data[0];
100
		$userdata = get_userdata( $data['id'] );
101
		$this->check_user_data( $userdata, $data, 'edit', $data['_links'] );
102
	}
103
104 View Code Duplication
	public function test_get_items_with_edit_context_without_permission() {
105
		//test with a user not logged in
106
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
107
		$request->set_param( 'context', 'edit' );
108
		$response = $this->server->dispatch( $request );
109
110
		$this->assertEquals( 401, $response->get_status() );
111
112
		//test with a user logged in but without sufficient capabilities; capability in question: 'list_users'
113
		wp_set_current_user( $this->editor );
114
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
115
		$request->set_param( 'context', 'edit' );
116
		$response = $this->server->dispatch( $request );
117
118
		$this->assertEquals( 403, $response->get_status() );
119
	}
120
121
	public function test_get_items_unauthenticated_only_shows_public_users() {
122
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
123
		$response = $this->server->dispatch( $request );
124
125
		$this->assertEquals( array(), $response->get_data() );
126
127
		$this->factory->post->create( array( 'post_author' => $this->editor ) );
128
		$this->factory->post->create( array( 'post_author' => $this->user, 'post_status' => 'draft' ) );
129
130
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
131
		$response = $this->server->dispatch( $request );
132
		$users = $response->get_data();
133
134
		foreach ( $users as $user ) {
135
			$this->assertTrue( count_user_posts( $user['id'] ) > 0 );
136
137
			// Ensure we don't expose non-public data
138
			$this->assertArrayNotHasKey( 'capabilities', $user );
139
			$this->assertArrayNotHasKey( 'email', $user );
140
			$this->assertArrayNotHasKey( 'roles', $user );
141
		}
142
	}
143
144
	/**
145
	 * @group test
146
	 */
147 View Code Duplication
	public function test_get_items_pagination_headers() {
148
		wp_set_current_user( $this->user );
149
		// Start of the index, including the three existing users
150
		for ( $i = 0; $i < 47; $i++ ) {
151
			$this->factory->user->create( array(
152
				'name'   => "User {$i}",
153
				) );
154
		}
155
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
156
		$response = $this->server->dispatch( $request );
157
		$headers = $response->get_headers();
158
		$this->assertEquals( 50, $headers['X-WP-Total'] );
159
		$this->assertEquals( 5, $headers['X-WP-TotalPages'] );
160
		$next_link = add_query_arg( array(
161
			'page'    => 2,
162
			), rest_url( 'wp/v2/users' ) );
163
		$this->assertFalse( stripos( $headers['Link'], 'rel="prev"' ) );
164
		$this->assertContains( '<' . $next_link . '>; rel="next"', $headers['Link'] );
165
		// 3rd page
166
		$this->factory->user->create( array(
167
				'name'   => 'User 51',
168
				) );
169
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
170
		$request->set_param( 'page', 3 );
171
		$response = $this->server->dispatch( $request );
172
		$headers = $response->get_headers();
173
		$this->assertEquals( 51, $headers['X-WP-Total'] );
174
		$this->assertEquals( 6, $headers['X-WP-TotalPages'] );
175
		$prev_link = add_query_arg( array(
176
			'page'    => 2,
177
			), rest_url( 'wp/v2/users' ) );
178
		$this->assertContains( '<' . $prev_link . '>; rel="prev"', $headers['Link'] );
179
		$next_link = add_query_arg( array(
180
			'page'    => 4,
181
			), rest_url( 'wp/v2/users' ) );
182
		$this->assertContains( '<' . $next_link . '>; rel="next"', $headers['Link'] );
183
		// Last page
184
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
185
		$request->set_param( 'page', 6 );
186
		$response = $this->server->dispatch( $request );
187
		$headers = $response->get_headers();
188
		$this->assertEquals( 51, $headers['X-WP-Total'] );
189
		$this->assertEquals( 6, $headers['X-WP-TotalPages'] );
190
		$prev_link = add_query_arg( array(
191
			'page'    => 5,
192
			), rest_url( 'wp/v2/users' ) );
193
		$this->assertContains( '<' . $prev_link . '>; rel="prev"', $headers['Link'] );
194
		$this->assertFalse( stripos( $headers['Link'], 'rel="next"' ) );
195
		// Out of bounds
196
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
197
		$request->set_param( 'page', 8 );
198
		$response = $this->server->dispatch( $request );
199
		$headers = $response->get_headers();
200
		$this->assertEquals( 51, $headers['X-WP-Total'] );
201
		$this->assertEquals( 6, $headers['X-WP-TotalPages'] );
202
		$prev_link = add_query_arg( array(
203
			'page'    => 6,
204
			), rest_url( 'wp/v2/users' ) );
205
		$this->assertContains( '<' . $prev_link . '>; rel="prev"', $headers['Link'] );
206
		$this->assertFalse( stripos( $headers['Link'], 'rel="next"' ) );
207
	}
208
209
	public function test_get_items_per_page() {
210
		wp_set_current_user( $this->user );
211
		for ( $i = 0; $i < 20; $i++ ) {
212
			$this->factory->user->create( array( 'display_name' => "User {$i}" ) );
213
		}
214
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
215
		$response = $this->server->dispatch( $request );
216
		$this->assertEquals( 10, count( $response->get_data() ) );
217
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
218
		$request->set_param( 'per_page', 5 );
219
		$response = $this->server->dispatch( $request );
220
		$this->assertEquals( 5, count( $response->get_data() ) );
221
	}
222
223
	public function test_get_items_page() {
224
		wp_set_current_user( $this->user );
225
		for ( $i = 0; $i < 20; $i++ ) {
226
			$this->factory->user->create( array( 'display_name' => "User {$i}" ) );
227
		}
228
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
229
		$request->set_param( 'per_page', 5 );
230
		$request->set_param( 'page', 2 );
231
		$response = $this->server->dispatch( $request );
232
		$this->assertEquals( 5, count( $response->get_data() ) );
233
		$prev_link = add_query_arg( array(
234
			'per_page'  => 5,
235
			'page'      => 1,
236
			), rest_url( 'wp/v2/users' ) );
237
		$headers = $response->get_headers();
238
		$this->assertContains( '<' . $prev_link . '>; rel="prev"', $headers['Link'] );
239
	}
240
241
	public function test_get_items_orderby_name() {
242
		wp_set_current_user( $this->user );
243
		$low_id = $this->factory->user->create( array( 'display_name' => 'AAAAA' ) );
244
		$mid_id = $this->factory->user->create( array( 'display_name' => 'NNNNN' ) );
0 ignored issues
show
Unused Code introduced by
$mid_id is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
245
		$high_id = $this->factory->user->create( array( 'display_name' => 'ZZZZ' ) );
246
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
247
		$request->set_param( 'orderby', 'name' );
248
		$request->set_param( 'order', 'desc' );
249
		$request->set_param( 'per_page', 1 );
250
		$response = $this->server->dispatch( $request );
251
		$data = $response->get_data();
252
		$this->assertEquals( $high_id, $data[0]['id'] );
253
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
254
		$request->set_param( 'orderby', 'name' );
255
		$request->set_param( 'order', 'asc' );
256
		$request->set_param( 'per_page', 1 );
257
		$response = $this->server->dispatch( $request );
258
		$data = $response->get_data();
259
		$this->assertEquals( $low_id, $data[0]['id'] );
260
	}
261
262 View Code Duplication
	public function test_get_items_orderby_url() {
263
		wp_set_current_user( $this->user );
264
265
		$low_id = $this->factory->user->create( array( 'user_url' => 'http://a.com' ) );
266
		$high_id = $this->factory->user->create( array( 'user_url' => 'http://b.com' ) );
267
268
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
269
		$request->set_param( 'orderby', 'url' );
270
		$request->set_param( 'order', 'desc' );
271
		$request->set_param( 'per_page', 1 );
272
		$request->set_param( 'include', array( $low_id, $high_id ) );
273
		$response = $this->server->dispatch( $request );
274
		$data = $response->get_data();
275
276
		$this->assertEquals( $high_id, $data[0]['id'] );
277
278
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
279
		$request->set_param( 'orderby', 'url' );
280
		$request->set_param( 'order', 'asc' );
281
		$request->set_param( 'per_page', 1 );
282
		$request->set_param( 'include', array( $low_id, $high_id ) );
283
		$response = $this->server->dispatch( $request );
284
		$data = $response->get_data();
285
		$this->assertEquals( $low_id, $data[0]['id'] );
286
	}
287
288 View Code Duplication
	public function test_get_items_orderby_slug() {
289
		wp_set_current_user( $this->user );
290
291
		$high_id = $this->factory->user->create( array( 'user_nicename' => 'blogin' ) );
292
		$low_id = $this->factory->user->create( array( 'user_nicename' => 'alogin' ) );
293
294
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
295
		$request->set_param( 'orderby', 'slug' );
296
		$request->set_param( 'order', 'desc' );
297
		$request->set_param( 'per_page', 1 );
298
		$request->set_param( 'include', array( $low_id, $high_id ) );
299
		$response = $this->server->dispatch( $request );
300
		$data = $response->get_data();
301
302
		$this->assertEquals( $high_id, $data[0]['id'] );
303
304
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
305
		$request->set_param( 'orderby', 'slug' );
306
		$request->set_param( 'order', 'asc' );
307
		$request->set_param( 'per_page', 1 );
308
		$request->set_param( 'include', array( $low_id, $high_id ) );
309
		$response = $this->server->dispatch( $request );
310
		$data = $response->get_data();
311
		$this->assertEquals( $low_id, $data[0]['id'] );
312
	}
313
314 View Code Duplication
	public function test_get_items_orderby_email() {
315
		wp_set_current_user( $this->user );
316
317
		$high_id = $this->factory->user->create( array( 'user_email' => '[email protected]' ) );
318
		$low_id = $this->factory->user->create( array( 'user_email' => '[email protected]' ) );
319
320
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
321
		$request->set_param( 'orderby', 'email' );
322
		$request->set_param( 'order', 'desc' );
323
		$request->set_param( 'per_page', 1 );
324
		$request->set_param( 'include', array( $low_id, $high_id ) );
325
		$response = $this->server->dispatch( $request );
326
		$data = $response->get_data();
327
		$this->assertEquals( $high_id, $data[0]['id'] );
328
329
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
330
		$request->set_param( 'orderby', 'email' );
331
		$request->set_param( 'order', 'asc' );
332
		$request->set_param( 'per_page', 1 );
333
		$request->set_param( 'include', array( $low_id, $high_id ) );
334
		$response = $this->server->dispatch( $request );
335
		$data = $response->get_data();
336
		$this->assertEquals( $low_id, $data[0]['id'] );
337
	}
338
339 View Code Duplication
	public function test_get_items_orderby_email_unauthenticated() {
340
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
341
		$request->set_param( 'orderby', 'email' );
342
		$request->set_param( 'order', 'desc' );
343
		$response = $this->server->dispatch( $request );
344
		$this->assertErrorResponse( 'rest_forbidden_orderby', $response, 401 );
345
	}
346
347 View Code Duplication
	public function test_get_items_orderby_registered_date_unauthenticated() {
348
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
349
		$request->set_param( 'orderby', 'registered_date' );
350
		$request->set_param( 'order', 'desc' );
351
		$response = $this->server->dispatch( $request );
352
		$this->assertErrorResponse( 'rest_forbidden_orderby', $response, 401 );
353
	}
354
355
	public function test_get_items_offset() {
356
		wp_set_current_user( $this->user );
357
		// 2 users created in __construct(), plus default user
358
		$this->factory->user->create();
359
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
360
		$request->set_param( 'offset', 1 );
361
		$response = $this->server->dispatch( $request );
362
		$this->assertCount( 3, $response->get_data() );
363
		// 'offset' works with 'per_page'
364
		$request->set_param( 'per_page', 2 );
365
		$response = $this->server->dispatch( $request );
366
		$this->assertCount( 2, $response->get_data() );
367
		// 'offset' takes priority over 'page'
368
		$request->set_param( 'page', 3 );
369
		$response = $this->server->dispatch( $request );
370
		$this->assertCount( 2, $response->get_data() );
371
	}
372
373
	public function test_get_items_include_query() {
374
		wp_set_current_user( $this->user );
375
		$id1 = $this->factory->user->create();
376
		$id2 = $this->factory->user->create();
0 ignored issues
show
Unused Code introduced by
$id2 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
377
		$id3 = $this->factory->user->create();
378
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
379
		// Orderby=>asc
380
		$request->set_param( 'include', array( $id3, $id1 ) );
381
		$response = $this->server->dispatch( $request );
382
		$data = $response->get_data();
383
		$this->assertEquals( 2, count( $data ) );
384
		$this->assertEquals( $id1, $data[0]['id'] );
385
		// Orderby=>include
386
		$request->set_param( 'orderby', 'include' );
387
		$response = $this->server->dispatch( $request );
388
		$data = $response->get_data();
389
		$this->assertEquals( 2, count( $data ) );
390
		$this->assertEquals( $id3, $data[0]['id'] );
391
		// No privileges
392
		wp_set_current_user( 0 );
393
		$response = $this->server->dispatch( $request );
394
		$data = $response->get_data();
395
		$this->assertEquals( 0, count( $data ) );
396
397
	}
398
399 View Code Duplication
	public function test_get_items_exclude_query() {
400
		wp_set_current_user( $this->user );
401
		$id1 = $this->factory->user->create();
402
		$id2 = $this->factory->user->create();
403
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
404
		$response = $this->server->dispatch( $request );
405
		$data = $response->get_data();
406
		$this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ) ) );
407
		$this->assertTrue( in_array( $id2, wp_list_pluck( $data, 'id' ) ) );
408
		$request->set_param( 'exclude', array( $id2 ) );
409
		$response = $this->server->dispatch( $request );
410
		$data = $response->get_data();
411
		$this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ) ) );
412
		$this->assertFalse( in_array( $id2, wp_list_pluck( $data, 'id' ) ) );
413
	}
414
415
	public function test_get_items_search() {
416
		wp_set_current_user( $this->user );
417
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
418
		$request->set_param( 'search', 'yololololo' );
419
		$response = $this->server->dispatch( $request );
420
		$this->assertEquals( 0, count( $response->get_data() ) );
421
		$yolo_id = $this->factory->user->create( array( 'display_name' => 'yololololo' ) );
422
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
423
		$request->set_param( 'search', (string) $yolo_id );
424
		$response = $this->server->dispatch( $request );
425
		$this->assertEquals( 1, count( $response->get_data() ) );
426
		// default to wildcard search
427
		$adam_id = $this->factory->user->create( array(
428
			'role'          => 'author',
429
			'user_nicename' => 'adam',
430
		) );
431
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
432
		$request->set_param( 'search', 'ada' );
433
		$response = $this->server->dispatch( $request );
434
		$data = $response->get_data();
435
		$this->assertEquals( 1, count( $data ) );
436
		$this->assertEquals( $adam_id, $data[0]['id'] );
437
	}
438
439 View Code Duplication
	public function test_get_items_slug_query() {
440
		wp_set_current_user( $this->user );
441
		$this->factory->user->create( array( 'display_name' => 'foo', 'user_login' => 'bar' ) );
442
		$id2 = $this->factory->user->create( array( 'display_name' => 'Moo', 'user_login' => 'foo' ) );
443
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
444
		$request->set_param( 'slug', 'foo' );
445
		$response = $this->server->dispatch( $request );
446
		$data = $response->get_data();
447
		$this->assertEquals( 1, count( $data ) );
448
		$this->assertEquals( $id2, $data[0]['id'] );
449
	}
450
451
	// Note: Do not test using editor role as there is an editor role created in testing and it makes it hard to test this functionality.
452
	public function test_get_items_roles() {
453
		wp_set_current_user( $this->user );
454
		$tango = $this->factory->user->create( array( 'display_name' => 'tango', 'role' => 'subscriber' ) );
455
		$yolo  = $this->factory->user->create( array( 'display_name' => 'yolo', 'role' => 'author' ) );
456
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
457
		$request->set_param( 'roles', 'author,subscriber' );
458
		$response = $this->server->dispatch( $request );
459
		$data = $response->get_data();
460
		$this->assertEquals( 2, count( $data ) );
461
		$this->assertEquals( $tango, $data[0]['id'] );
462
		$this->assertEquals( $yolo, $data[1]['id'] );
463
		$request->set_param( 'roles', 'author' );
464
		$response = $this->server->dispatch( $request );
465
		$data = $response->get_data();
466
		$this->assertEquals( 1, count( $data ) );
467
		$this->assertEquals( $yolo, $data[0]['id'] );
468
		wp_set_current_user( 0 );
469
		$request->set_param( 'roles', 'author' );
470
		$response = $this->server->dispatch( $request );
471
		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 401 );
472
		wp_set_current_user( $this->editor );
473
		$request->set_param( 'roles', 'author' );
474
		$response = $this->server->dispatch( $request );
475
		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 403 );
476
	}
477
478
	public function test_get_items_invalid_roles() {
479
		wp_set_current_user( $this->user );
480
		$lolz = $this->factory->user->create( array( 'display_name' => 'lolz', 'role' => 'author' ) );
481
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
482
		$request->set_param( 'roles', 'ilovesteak,author' );
483
		$response = $this->server->dispatch( $request );
484
		$data = $response->get_data();
485
		$this->assertEquals( 1, count( $data ) );
486
		$this->assertEquals( $lolz, $data[0]['id'] );
487
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
488
		$request->set_param( 'roles', 'steakisgood' );
489
		$response = $this->server->dispatch( $request );
490
		$data = $response->get_data();
491
		$this->assertEquals( 0, count( $data ) );
492
		$this->assertEquals( array(), $data );
493
	}
494
495
	public function test_get_item() {
496
		$user_id = $this->factory->user->create();
497
		wp_set_current_user( $this->user );
498
499
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $user_id ) );
500
501
		$response = $this->server->dispatch( $request );
502
		$this->check_get_user_response( $response, 'embed' );
503
	}
504
505
	public function test_prepare_item() {
506
		wp_set_current_user( $this->user );
507
		$request = new WP_REST_Request;
508
		$request->set_param( 'context', 'edit' );
509
		$user = get_user_by( 'id', get_current_user_id() );
510
		$data = $this->endpoint->prepare_item_for_response( $user, $request );
511
		$this->check_get_user_response( $data, 'edit' );
512
	}
513
514 View Code Duplication
	public function test_get_user_avatar_urls() {
515
		wp_set_current_user( $this->user );
516
517
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->editor ) );
518
519
		$response = $this->server->dispatch( $request );
520
521
		$data = $response->get_data();
522
		$this->assertArrayHasKey( 24,  $data['avatar_urls'] );
523
		$this->assertArrayHasKey( 48,  $data['avatar_urls'] );
524
		$this->assertArrayHasKey( 96,  $data['avatar_urls'] );
525
526
		$user = get_user_by( 'id', $this->editor );
527
		/**
528
		 * Ignore the subdomain, since 'get_avatar_url randomly sets the Gravatar
529
		 * server when building the url string.
530
		 */
531
		$this->assertEquals( substr( get_avatar_url( $user->user_email ), 9 ), substr( $data['avatar_urls'][96], 9 ) );
532
	}
533
534 View Code Duplication
	public function test_get_user_invalid_id() {
535
		wp_set_current_user( $this->user );
536
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/100' );
537
		$response = $this->server->dispatch( $request );
538
539
		$this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
540
	}
541
542
	public function test_get_user_empty_capabilities() {
543
		wp_set_current_user( $this->user );
544
		$this->allow_user_to_manage_multisite();
545
546
		$lolz = $this->factory->user->create( array( 'display_name' => 'lolz', 'roles' => '' ) );
547
		delete_user_option( $lolz, 'capabilities' );
548
		delete_user_option( $lolz, 'user_level' );
549
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/' . $lolz );
550
		$request->set_param( 'context', 'edit' );
551
		$response = $this->server->dispatch( $request );
552
		$data = $response->get_data();
553
554
		$this->assertEquals( $data['capabilities'], new stdClass() );
555
		$this->assertEquals( $data['extra_capabilities'], new stdClass() );
556
	}
557
558
	public function test_get_item_without_permission() {
559
		wp_set_current_user( $this->editor );
560
561
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->user ) );
562
		$response = $this->server->dispatch( $request );
563
564
		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 403 );
565
	}
566
567
	public function test_get_item_published_author_post() {
568
		$this->author_id = $this->factory->user->create( array(
569
			'role' => 'author',
570
		) );
571
		$this->post_id = $this->factory->post->create( array(
572
			'post_author' => $this->author_id,
573
		));
574
		wp_set_current_user( 0 );
575
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->author_id ) );
576
		$response = $this->server->dispatch( $request );
577
		$this->check_get_user_response( $response, 'embed' );
578
	}
579
580
	public function test_get_item_published_author_pages() {
581
		$this->author_id = $this->factory->user->create( array(
582
			'role' => 'author',
583
		) );
584
		wp_set_current_user( 0 );
585
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->author_id ) );
586
		$response = $this->server->dispatch( $request );
587
		$this->assertEquals( 401, $response->get_status() );
588
		$this->post_id = $this->factory->post->create( array(
589
			'post_author' => $this->author_id,
590
			'post_type'   => 'page',
591
		));
592
		$response = $this->server->dispatch( $request );
593
		$this->check_get_user_response( $response, 'embed' );
594
	}
595
596 View Code Duplication
	public function test_get_user_with_edit_context() {
597
		$user_id = $this->factory->user->create();
598
		$this->allow_user_to_manage_multisite();
599
600
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $user_id ) );
601
		$request->set_param( 'context', 'edit' );
602
603
		$response = $this->server->dispatch( $request );
604
		$this->check_get_user_response( $response, 'edit' );
605
	}
606
607
	public function test_get_item_published_author_wrong_context() {
608
		$this->author_id = $this->factory->user->create( array(
609
			'role' => 'author',
610
		) );
611
		$this->post_id = $this->factory->post->create( array(
612
			'post_author' => $this->author_id,
613
		));
614
		wp_set_current_user( 0 );
615
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->author_id ) );
616
		$request->set_param( 'context', 'edit' );
617
		$response = $this->server->dispatch( $request );
618
		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 401 );
619
	}
620
621 View Code Duplication
	public function test_get_current_user() {
622
		wp_set_current_user( $this->user );
623
624
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/me' );
625
626
		$response = $this->server->dispatch( $request );
627
		$this->assertEquals( 302, $response->get_status() );
628
629
		$headers = $response->get_headers();
630
		$this->assertArrayHasKey( 'Location', $headers );
631
		$this->assertEquals( rest_url( 'wp/v2/users/' . $this->user ), $headers['Location'] );
632
	}
633
634 View Code Duplication
	public function test_get_current_user_without_permission() {
635
		wp_set_current_user( 0 );
636
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/me' );
637
		$response = $this->server->dispatch( $request );
638
639
		$this->assertErrorResponse( 'rest_not_logged_in', $response, 401 );
640
	}
641
642
	public function test_create_item() {
643
		$this->allow_user_to_manage_multisite();
644
		wp_set_current_user( $this->user );
645
646
		$params = array(
647
			'username'    => 'testuser',
648
			'password'    => 'testpassword',
649
			'email'       => '[email protected]',
650
			'name'        => 'Test User',
651
			'nickname'    => 'testuser',
652
			'slug'        => 'test-user',
653
			'role'        => 'editor',
654
			'description' => 'New API User',
655
			'url'         => 'http://example.com',
656
		);
657
658
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
659
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
660
		$request->set_body_params( $params );
661
662
		$response = $this->server->dispatch( $request );
663
		$data = $response->get_data();
664
		$this->assertEquals( 'http://example.com', $data['url'] );
665
		$this->check_add_edit_user_response( $response );
666
	}
667
668
	public function test_json_create_user() {
669
		$this->allow_user_to_manage_multisite();
670
		wp_set_current_user( $this->user );
671
672
		$params = array(
673
			'username' => 'testjsonuser',
674
			'password' => 'testjsonpassword',
675
			'email'    => '[email protected]',
676
		);
677
678
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
679
		$request->add_header( 'content-type', 'application/json' );
680
		$request->set_body( wp_json_encode( $params ) );
681
682
		$response = $this->server->dispatch( $request );
683
		$this->check_add_edit_user_response( $response );
684
	}
685
686 View Code Duplication
	public function test_create_user_without_permission() {
687
		wp_set_current_user( $this->editor );
688
689
		$params = array(
690
			'username' => 'homersimpson',
691
			'password' => 'stupidsexyflanders',
692
			'email'    => '[email protected]',
693
		);
694
695
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
696
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
697
		$request->set_body_params( $params );
698
		$response = $this->server->dispatch( $request );
699
700
		$this->assertErrorResponse( 'rest_cannot_create_user', $response, 403 );
701
	}
702
703 View Code Duplication
	public function test_create_user_invalid_id() {
704
		$this->allow_user_to_manage_multisite();
705
		wp_set_current_user( $this->user );
706
707
		$params = array(
708
			'id'       => '156',
709
			'username' => 'lisasimpson',
710
			'password' => 'DavidHasselhoff',
711
			'email'    => '[email protected]',
712
		);
713
714
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
715
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
716
		$request->set_body_params( $params );
717
		$response = $this->server->dispatch( $request );
718
719
		$this->assertErrorResponse( 'rest_user_exists', $response, 400 );
720
	}
721
722 View Code Duplication
	public function test_create_user_invalid_email() {
723
		$this->allow_user_to_manage_multisite();
724
		wp_set_current_user( $this->user );
725
726
		$params = array(
727
			'username' => 'lisasimpson',
728
			'password' => 'DavidHasselhoff',
729
			'email'    => 'something',
730
		);
731
732
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
733
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
734
		$request->set_body_params( $params );
735
		$response = $this->server->dispatch( $request );
736
737
		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
738
	}
739
740 View Code Duplication
	public function test_create_user_invalid_role() {
741
		$this->allow_user_to_manage_multisite();
742
		wp_set_current_user( $this->user );
743
744
		$params = array(
745
			'username' => 'maggiesimpson',
746
			'password' => 'i_shot_mrburns',
747
			'email'    => '[email protected]',
748
			'roles'    => array( 'baby' ),
749
		);
750
751
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
752
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
753
		$request->set_body_params( $params );
754
		$response = $this->server->dispatch( $request );
755
756
		$this->assertErrorResponse( 'rest_user_invalid_role', $response, 400 );
757
	}
758
759
	public function test_update_item() {
760
		$user_id = $this->factory->user->create( array(
761
			'user_email' => '[email protected]',
762
			'user_pass' => 'sjflsfls',
763
			'user_login' => 'test_update',
764
			'first_name' => 'Old Name',
765
			'user_url' => 'http://apple.com',
766
		));
767
		$this->allow_user_to_manage_multisite();
768
		wp_set_current_user( $this->user );
769
770
		$userdata = get_userdata( $user_id );
771
		$pw_before = $userdata->user_pass;
772
773
		$_POST['email'] = $userdata->user_email;
774
		$_POST['username'] = $userdata->user_login;
775
		$_POST['first_name'] = 'New Name';
776
		$_POST['url'] = 'http://google.com';
777
778
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
779
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
780
		$request->set_body_params( $_POST );
781
782
		$response = $this->server->dispatch( $request );
783
		$this->check_add_edit_user_response( $response, true );
784
785
		// Check that the name has been updated correctly
786
		$new_data = $response->get_data();
787
		$this->assertEquals( 'New Name', $new_data['first_name'] );
788
		$user = get_userdata( $user_id );
789
		$this->assertEquals( 'New Name', $user->first_name );
790
791
		$this->assertEquals( 'http://google.com', $new_data['url'] );
792
		$this->assertEquals( 'http://google.com', $user->user_url );
793
794
		// Check that we haven't inadvertently changed the user's password,
795
		// as per https://core.trac.wordpress.org/ticket/21429
796
		$this->assertEquals( $pw_before, $user->user_pass );
797
	}
798
799 View Code Duplication
	public function test_update_item_existing_email() {
800
		$user1 = $this->factory->user->create( array( 'user_login' => 'test_json_user', 'user_email' => '[email protected]' ) );
0 ignored issues
show
Unused Code introduced by
$user1 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
801
		$user2 = $this->factory->user->create( array( 'user_login' => 'test_json_user2', 'user_email' => '[email protected]' ) );
802
		$this->allow_user_to_manage_multisite();
803
		wp_set_current_user( $this->user );
804
805
		$request = new WP_REST_Request( 'PUT', '/wp/v2/users/' . $user2 );
806
		$request->set_param( 'email', '[email protected]' );
807
		$response = $this->server->dispatch( $request );
808
		$this->assertInstanceOf( 'WP_Error', $response->as_error() );
809
		$this->assertEquals( 'rest_user_invalid_email', $response->as_error()->get_error_code() );
810
	}
811
812 View Code Duplication
	public function test_update_item_username_attempt() {
813
		$user1 = $this->factory->user->create( array( 'user_login' => 'test_json_user', 'user_email' => '[email protected]' ) );
0 ignored issues
show
Unused Code introduced by
$user1 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
814
		$user2 = $this->factory->user->create( array( 'user_login' => 'test_json_user2', 'user_email' => '[email protected]' ) );
815
		$this->allow_user_to_manage_multisite();
816
		wp_set_current_user( $this->user );
817
818
		$request = new WP_REST_Request( 'PUT', '/wp/v2/users/' . $user2 );
819
		$request->set_param( 'username', 'test_json_user' );
820
		$response = $this->server->dispatch( $request );
821
		$this->assertInstanceOf( 'WP_Error', $response->as_error() );
822
		$this->assertEquals( 'rest_user_invalid_argument', $response->as_error()->get_error_code() );
823
	}
824
825 View Code Duplication
	public function test_update_item_existing_nicename() {
826
		$user1 = $this->factory->user->create( array( 'user_login' => 'test_json_user', 'user_email' => '[email protected]' ) );
0 ignored issues
show
Unused Code introduced by
$user1 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
827
		$user2 = $this->factory->user->create( array( 'user_login' => 'test_json_user2', 'user_email' => '[email protected]' ) );
828
		$this->allow_user_to_manage_multisite();
829
		wp_set_current_user( $this->user );
830
831
		$request = new WP_REST_Request( 'PUT', '/wp/v2/users/' . $user2 );
832
		$request->set_param( 'slug', 'test_json_user' );
833
		$response = $this->server->dispatch( $request );
834
		$this->assertInstanceOf( 'WP_Error', $response->as_error() );
835
		$this->assertEquals( 'rest_user_invalid_slug', $response->as_error()->get_error_code() );
836
	}
837
838
	public function test_json_update_user() {
839
		$user_id = $this->factory->user->create( array(
840
			'user_email' => '[email protected]',
841
			'user_pass'  => 'sjflsfl3sdjls',
842
			'user_login' => 'test_json_update',
843
			'first_name' => 'Old Name',
844
			'last_name'  => 'Original Last',
845
		));
846
		$this->allow_user_to_manage_multisite();
847
		wp_set_current_user( $this->user );
848
849
		$params = array(
850
			'username'   => 'test_json_update',
851
			'email'      => '[email protected]',
852
			'first_name' => 'JSON Name',
853
			'last_name'  => 'New Last',
854
		);
855
856
		$userdata = get_userdata( $user_id );
857
		$pw_before = $userdata->user_pass;
858
859
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
860
		$request->add_header( 'content-type', 'application/json' );
861
		$request->set_body( wp_json_encode( $params ) );
862
863
		$response = $this->server->dispatch( $request );
864
		$this->check_add_edit_user_response( $response, true );
865
866
		// Check that the name has been updated correctly
867
		$new_data = $response->get_data();
868
		$this->assertEquals( 'JSON Name', $new_data['first_name'] );
869
		$this->assertEquals( 'New Last', $new_data['last_name'] );
870
		$user = get_userdata( $user_id );
871
		$this->assertEquals( 'JSON Name', $user->first_name );
872
		$this->assertEquals( 'New Last', $user->last_name );
873
874
		// Check that we haven't inadvertently changed the user's password,
875
		// as per https://core.trac.wordpress.org/ticket/21429
876
		$this->assertEquals( $pw_before, $user->user_pass );
877
	}
878
879 View Code Duplication
	public function test_update_user_role() {
880
		$user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
881
882
		wp_set_current_user( $this->user );
883
		$this->allow_user_to_manage_multisite();
884
885
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
886
		$request->set_param( 'roles', array( 'editor' ) );
887
		$response = $this->server->dispatch( $request );
888
889
		$new_data = $response->get_data();
890
891
		$this->assertEquals( 'editor', $new_data['roles'][0] );
892
		$this->assertNotEquals( 'administrator', $new_data['roles'][0] );
893
894
		$user = get_userdata( $user_id );
895
		$this->assertArrayHasKey( 'editor', $user->caps );
896
		$this->assertArrayNotHasKey( 'administrator', $user->caps );
897
	}
898
899 View Code Duplication
	public function test_update_user_role_invalid_privilege_escalation() {
900
		wp_set_current_user( $this->editor );
901
902
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $this->editor ) );
903
		$request->set_param( 'roles', array( 'administrator' ) );
904
		$response = $this->server->dispatch( $request );
905
906
		$this->assertErrorResponse( 'rest_cannot_edit_roles', $response, 403 );
907
		$user = get_userdata( $this->editor );
908
		$this->assertArrayHasKey( 'editor', $user->caps );
909
		$this->assertArrayNotHasKey( 'administrator', $user->caps );
910
	}
911
912
	public function test_update_user_role_invalid_privilege_deescalation() {
913
		if ( is_multisite() ) {
914
			return $this->markTestSkipped( 'Test only intended for single site.' );
915
		}
916
917
		$user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
918
919
		wp_set_current_user( $user_id );
920
921
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
922
		$request->set_param( 'roles', array( 'editor' ) );
923
		$response = $this->server->dispatch( $request );
924
925
		$this->assertErrorResponse( 'rest_user_invalid_role', $response, 403 );
926
927
		$user = get_userdata( $user_id );
928
		$this->assertArrayHasKey( 'administrator', $user->caps );
929
		$this->assertArrayNotHasKey( 'editor', $user->caps );
930
	}
931
932
	public function test_update_user_role_privilege_deescalation_multisite() {
933
		if ( ! is_multisite() ) {
934
			return $this->markTestSkipped( 'Test only intended for multisite.' );
935
		}
936
937
		$user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
938
939
		wp_set_current_user( $user_id );
940
		$user = wp_get_current_user();
941
		update_site_option( 'site_admins', array( $user->user_login ) );
942
943
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
944
		$request->set_param( 'roles', array( 'editor' ) );
945
		$response = $this->server->dispatch( $request );
946
947
		$new_data = $response->get_data();
948
		$this->assertEquals( 'editor', $new_data['roles'][0] );
949
		$this->assertNotEquals( 'administrator', $new_data['roles'][0] );
950
	}
951
952
953 View Code Duplication
	public function test_update_user_role_invalid_role() {
954
		wp_set_current_user( $this->user );
955
		$this->allow_user_to_manage_multisite();
956
957
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $this->editor ) );
958
		$request->set_param( 'roles', array( 'BeSharp' ) );
959
		$response = $this->server->dispatch( $request );
960
961
		$this->assertErrorResponse( 'rest_user_invalid_role', $response, 400 );
962
963
		$user = get_userdata( $this->editor );
964
		$this->assertArrayHasKey( 'editor', $user->caps );
965
		$this->assertArrayNotHasKey( 'BeSharp', $user->caps );
966
	}
967
968 View Code Duplication
	public function test_update_user_without_permission() {
969
		wp_set_current_user( $this->editor );
970
971
		$params = array(
972
			'username' => 'homersimpson',
973
			'password' => 'stupidsexyflanders',
974
			'email'    => '[email protected]',
975
		);
976
977
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $this->user ) );
978
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
979
		$request->set_body_params( $params );
980
		$response = $this->server->dispatch( $request );
981
982
		$this->assertErrorResponse( 'rest_cannot_edit', $response, 403 );
983
	}
984
985 View Code Duplication
	public function test_update_user_invalid_id() {
986
		$this->allow_user_to_manage_multisite();
987
		wp_set_current_user( $this->user );
988
989
		$params = array(
990
			'id'       => '156',
991
			'username' => 'lisasimpson',
992
			'password' => 'DavidHasselhoff',
993
			'email'    => '[email protected]',
994
		);
995
996
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $this->editor ) );
997
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
998
		$request->set_body_params( $params );
999
		$response = $this->server->dispatch( $request );
1000
1001
		$this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
1002
	}
1003
1004 View Code Duplication
	public function test_delete_item() {
1005
		$user_id = $this->factory->user->create( array( 'display_name' => 'Deleted User' ) );
1006
1007
		$this->allow_user_to_manage_multisite();
1008
		wp_set_current_user( $this->user );
1009
1010
		$userdata = get_userdata( $user_id ); // cache for later
0 ignored issues
show
Unused Code introduced by
$userdata is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1011
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
1012
		$request['force'] = true;
1013
		$response = $this->server->dispatch( $request );
1014
1015
		$this->assertEquals( 200, $response->get_status() );
1016
		$data = $response->get_data();
1017
		$this->assertEquals( 'Deleted User', $data['name'] );
1018
	}
1019
1020
	public function test_delete_item_no_trash() {
1021
		$user_id = $this->factory->user->create( array( 'display_name' => 'Deleted User' ) );
1022
1023
		$this->allow_user_to_manage_multisite();
1024
		wp_set_current_user( $this->user );
1025
1026
		$userdata = get_userdata( $user_id ); // cache for later
0 ignored issues
show
Unused Code introduced by
$userdata is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1027
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
1028
		$response = $this->server->dispatch( $request );
1029
		$this->assertErrorResponse( 'rest_trash_not_supported', $response, 501 );
1030
1031
		// Ensure the user still exists
1032
		$user = get_user_by( 'id', $user_id );
1033
		$this->assertNotEmpty( $user );
1034
	}
1035
1036
	public function test_delete_user_without_permission() {
1037
		$user_id = $this->factory->user->create();
1038
1039
		$this->allow_user_to_manage_multisite();
1040
		wp_set_current_user( $this->editor );
1041
1042
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
1043
		$request['force'] = true;
1044
		$response = $this->server->dispatch( $request );
1045
1046
		$this->assertErrorResponse( 'rest_user_cannot_delete', $response, 403 );
1047
	}
1048
1049
	public function test_delete_user_invalid_id() {
1050
		$this->allow_user_to_manage_multisite();
1051
		wp_set_current_user( $this->user );
1052
1053
		$request = new WP_REST_Request( 'DELETE', '/wp/v2/users/100' );
1054
		$request['force'] = true;
1055
		$response = $this->server->dispatch( $request );
1056
1057
		$this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
1058
	}
1059
1060
	public function test_delete_user_reassign() {
1061
		$this->allow_user_to_manage_multisite();
1062
1063
		// Test with a new user, to avoid any complications
1064
		$user_id = $this->factory->user->create();
1065
		$reassign_id = $this->factory->user->create();
1066
		$test_post = $this->factory->post->create(array(
1067
			'post_author' => $user_id,
1068
		));
1069
1070
		// Sanity check to ensure the factory created the post correctly
1071
		$post = get_post( $test_post );
1072
		$this->assertEquals( $user_id, $post->post_author );
1073
1074
		// Delete our test user, and reassign to the new author
1075
		wp_set_current_user( $this->user );
1076
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
1077
		$request['force'] = true;
1078
		$request->set_param( 'reassign', $reassign_id );
1079
		$response = $this->server->dispatch( $request );
1080
1081
		$this->assertEquals( 200, $response->get_status() );
1082
1083
		// Check that the post has been updated correctly
1084
		$post = get_post( $test_post );
1085
		$this->assertEquals( $reassign_id, $post->post_author );
1086
	}
1087
1088
	public function test_delete_user_invalid_reassign_id() {
1089
		$user_id = $this->factory->user->create();
1090
1091
		$this->allow_user_to_manage_multisite();
1092
		wp_set_current_user( $this->user );
1093
1094
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
1095
		$request['force'] = true;
1096
		$request->set_param( 'reassign', 100 );
1097
		$response = $this->server->dispatch( $request );
1098
1099
		$this->assertErrorResponse( 'rest_user_invalid_reassign', $response, 400 );
1100
	}
1101
1102 View Code Duplication
	public function test_get_item_schema() {
1103
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users' );
1104
		$response = $this->server->dispatch( $request );
1105
		$data = $response->get_data();
1106
		$properties = $data['schema']['properties'];
1107
1108
		$this->assertEquals( 17, count( $properties ) );
1109
		$this->assertArrayHasKey( 'avatar_urls', $properties );
1110
		$this->assertArrayHasKey( 'capabilities', $properties );
1111
		$this->assertArrayHasKey( 'description', $properties );
1112
		$this->assertArrayHasKey( 'email', $properties );
1113
		$this->assertArrayHasKey( 'extra_capabilities', $properties );
1114
		$this->assertArrayHasKey( 'first_name', $properties );
1115
		$this->assertArrayHasKey( 'id', $properties );
1116
		$this->assertArrayHasKey( 'last_name', $properties );
1117
		$this->assertArrayHasKey( 'link', $properties );
1118
		$this->assertArrayHasKey( 'name', $properties );
1119
		$this->assertArrayHasKey( 'nickname', $properties );
1120
		$this->assertArrayHasKey( 'registered_date', $properties );
1121
		$this->assertArrayHasKey( 'slug', $properties );
1122
		$this->assertArrayHasKey( 'password', $properties );
1123
		$this->assertArrayHasKey( 'url', $properties );
1124
		$this->assertArrayHasKey( 'username', $properties );
1125
		$this->assertArrayHasKey( 'roles', $properties );
1126
1127
	}
1128
1129 View Code Duplication
	public function test_get_item_schema_show_avatar() {
1130
		update_option( 'show_avatars', false );
1131
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users' );
1132
		$response = $this->server->dispatch( $request );
1133
		$data = $response->get_data();
1134
		$properties = $data['schema']['properties'];
1135
1136
		$this->assertArrayNotHasKey( 'avatar_urls', $properties );
1137
	}
1138
1139
	public function test_get_additional_field_registration() {
1140
1141
		$schema = array(
1142
			'type'        => 'integer',
1143
			'description' => 'Some integer of mine',
1144
			'enum'        => array( 1, 2, 3, 4 ),
1145
			'context'     => array( 'embed', 'view', 'edit' ),
1146
		);
1147
1148
		register_rest_field( 'user', 'my_custom_int', array(
1149
			'schema'          => $schema,
1150
			'get_callback'    => array( $this, 'additional_field_get_callback' ),
1151
			'update_callback' => array( $this, 'additional_field_update_callback' ),
1152
		) );
1153
1154
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users' );
1155
1156
		$response = $this->server->dispatch( $request );
1157
		$data = $response->get_data();
1158
1159
		$this->assertArrayHasKey( 'my_custom_int', $data['schema']['properties'] );
1160
		$this->assertEquals( $schema, $data['schema']['properties']['my_custom_int'] );
1161
1162
		wp_set_current_user( 1 );
1163
		if ( is_multisite() ) {
1164
			$current_user = wp_get_current_user( 1 );
1165
			update_site_option( 'site_admins', array( $current_user->user_login ) );
1166
		}
1167
1168
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/1' );
1169
1170
		$response = $this->server->dispatch( $request );
1171
		$this->assertArrayHasKey( 'my_custom_int', $response->data );
1172
1173
		$request = new WP_REST_Request( 'POST', '/wp/v2/users/1' );
1174
		$request->set_body_params(array(
1175
			'my_custom_int' => 123,
1176
		));
1177
1178
		$response = $this->server->dispatch( $request );
0 ignored issues
show
Unused Code introduced by
$response is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1179
		$this->assertEquals( 123, get_user_meta( 1, 'my_custom_int', true ) );
1180
1181
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
1182
		$request->set_body_params(array(
1183
			'my_custom_int' => 123,
1184
			'email' => '[email protected]',
1185
			'username' => 'abc123',
1186
			'password' => 'hello',
1187
		));
1188
1189
		$response = $this->server->dispatch( $request );
1190
1191
		$this->assertEquals( 123, $response->data['my_custom_int'] );
1192
1193
		global $wp_rest_additional_fields;
1194
		$wp_rest_additional_fields = array();
1195
	}
1196
1197
	public function test_additional_field_update_errors() {
1198
		$schema = array(
1199
			'type'        => 'integer',
1200
			'description' => 'Some integer of mine',
1201
			'enum'        => array( 1, 2, 3, 4 ),
1202
			'context'     => array( 'view', 'edit' ),
1203
		);
1204
1205
		register_rest_field( 'user', 'my_custom_int', array(
1206
			'schema'          => $schema,
1207
			'get_callback'    => array( $this, 'additional_field_get_callback' ),
1208
			'update_callback' => array( $this, 'additional_field_update_callback' ),
1209
		) );
1210
1211
		wp_set_current_user( 1 );
1212
		if ( is_multisite() ) {
1213
			$current_user = wp_get_current_user( 1 );
1214
			update_site_option( 'site_admins', array( $current_user->user_login ) );
1215
		}
1216
1217
		// Check for error on update.
1218
		$request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d', $this->user ) );
1219
		$request->set_body_params( array(
1220
			'my_custom_int' => 'returnError',
1221
		) );
1222
1223
		$response = $this->server->dispatch( $request );
1224
1225
		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
1226
1227
		global $wp_rest_additional_fields;
1228
		$wp_rest_additional_fields = array();
1229
	}
1230
1231
	public function additional_field_get_callback( $object ) {
1232
		return get_user_meta( $object['id'], 'my_custom_int', true );
1233
	}
1234
1235
	public function additional_field_update_callback( $value, $user ) {
1236
		if ( 'returnError' === $value ) {
1237
			return new WP_Error( 'rest_invalid_param', 'Testing an error.', array( 'status' => 400 ) );
1238
		}
1239
		update_user_meta( $user->ID, 'my_custom_int', $value );
1240
	}
1241
1242
	public function tearDown() {
1243
		parent::tearDown();
1244
	}
1245
1246
	protected function check_user_data( $user, $data, $context, $links ) {
1247
		$this->assertEquals( $user->ID, $data['id'] );
1248
		$this->assertEquals( $user->display_name, $data['name'] );
1249
		$this->assertEquals( $user->user_url, $data['url'] );
1250
		$this->assertEquals( $user->description, $data['description'] );
1251
		$this->assertEquals( get_author_posts_url( $user->ID ), $data['link'] );
1252
		$this->assertArrayHasKey( 'avatar_urls', $data );
1253
		$this->assertEquals( $user->user_nicename, $data['slug'] );
1254
1255
		if ( 'edit' === $context ) {
1256
			$this->assertEquals( $user->first_name, $data['first_name'] );
1257
			$this->assertEquals( $user->last_name, $data['last_name'] );
1258
			$this->assertEquals( $user->nickname, $data['nickname'] );
1259
			$this->assertEquals( $user->user_email, $data['email'] );
1260
			$this->assertEquals( (object) $user->allcaps, $data['capabilities'] );
1261
			$this->assertEquals( (object) $user->caps, $data['extra_capabilities'] );
1262
			$this->assertEquals( date( 'c', strtotime( $user->user_registered ) ), $data['registered_date'] );
1263
			$this->assertEquals( $user->user_login, $data['username'] );
1264
			$this->assertEquals( $user->roles, $data['roles'] );
1265
		}
1266
1267
		if ( 'edit' !== $context ) {
1268
			$this->assertArrayNotHasKey( 'roles', $data );
1269
			$this->assertArrayNotHasKey( 'capabilities', $data );
1270
			$this->assertArrayNotHasKey( 'registered', $data );
1271
			$this->assertArrayNotHasKey( 'first_name', $data );
1272
			$this->assertArrayNotHasKey( 'last_name', $data );
1273
			$this->assertArrayNotHasKey( 'nickname', $data );
1274
			$this->assertArrayNotHasKey( 'extra_capabilities', $data );
1275
			$this->assertArrayNotHasKey( 'username', $data );
1276
		}
1277
1278
		$this->assertEqualSets( array(
1279
			'self',
1280
			'collection',
1281
		), array_keys( $links ) );
1282
1283
		$this->assertArrayNotHasKey( 'password', $data );
1284
	}
1285
1286 View Code Duplication
	protected function check_get_user_response( $response, $context = 'view' ) {
1287
		$this->assertEquals( 200, $response->get_status() );
1288
1289
		$data = $response->get_data();
1290
		$userdata = get_userdata( $data['id'] );
1291
		$this->check_user_data( $userdata, $data, $context, $response->get_links() );
1292
	}
1293
1294
	protected function check_add_edit_user_response( $response, $update = false ) {
1295
		if ( $update ) {
1296
			$this->assertEquals( 200, $response->get_status() );
1297
		} else {
1298
			$this->assertEquals( 201, $response->get_status() );
1299
		}
1300
1301
		$data = $response->get_data();
1302
		$userdata = get_userdata( $data['id'] );
1303
		$this->check_user_data( $userdata, $data, 'edit', $response->get_links() );
1304
	}
1305
1306
	protected function allow_user_to_manage_multisite() {
1307
		wp_set_current_user( $this->user );
1308
		$user = wp_get_current_user();
1309
1310
		if ( is_multisite() ) {
1311
			update_site_option( 'site_admins', array( $user->user_login ) );
1312
		}
1313
1314
		return;
1315
	}
1316
}
1317