Completed
Branch develop (21297d)
by
unknown
02:41
created

test_additional_field_update_errors()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 33
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 21
nc 2
nop 0
dl 0
loc 33
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() {
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
	public function test_get_items_offset() {
263
		wp_set_current_user( $this->user );
264
		// 2 users created in __construct(), plus default user
265
		$this->factory->user->create();
266
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
267
		$request->set_param( 'offset', 1 );
268
		$response = $this->server->dispatch( $request );
269
		$this->assertCount( 3, $response->get_data() );
270
		// 'offset' works with 'per_page'
271
		$request->set_param( 'per_page', 2 );
272
		$response = $this->server->dispatch( $request );
273
		$this->assertCount( 2, $response->get_data() );
274
		// 'offset' takes priority over 'page'
275
		$request->set_param( 'page', 3 );
276
		$response = $this->server->dispatch( $request );
277
		$this->assertCount( 2, $response->get_data() );
278
	}
279
280
	public function test_get_items_include_query() {
281
		wp_set_current_user( $this->user );
282
		$id1 = $this->factory->user->create();
283
		$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...
284
		$id3 = $this->factory->user->create();
285
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
286
		// Orderby=>asc
287
		$request->set_param( 'include', array( $id3, $id1 ) );
288
		$response = $this->server->dispatch( $request );
289
		$data = $response->get_data();
290
		$this->assertEquals( 2, count( $data ) );
291
		$this->assertEquals( $id1, $data[0]['id'] );
292
		// Orderby=>include
293
		$request->set_param( 'orderby', 'include' );
294
		$response = $this->server->dispatch( $request );
295
		$data = $response->get_data();
296
		$this->assertEquals( 2, count( $data ) );
297
		$this->assertEquals( $id3, $data[0]['id'] );
298
		// No privileges
299
		wp_set_current_user( 0 );
300
		$response = $this->server->dispatch( $request );
301
		$data = $response->get_data();
302
		$this->assertEquals( 0, count( $data ) );
303
304
	}
305
306 View Code Duplication
	public function test_get_items_exclude_query() {
307
		wp_set_current_user( $this->user );
308
		$id1 = $this->factory->user->create();
309
		$id2 = $this->factory->user->create();
310
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
311
		$response = $this->server->dispatch( $request );
312
		$data = $response->get_data();
313
		$this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ) ) );
314
		$this->assertTrue( in_array( $id2, wp_list_pluck( $data, 'id' ) ) );
315
		$request->set_param( 'exclude', array( $id2 ) );
316
		$response = $this->server->dispatch( $request );
317
		$data = $response->get_data();
318
		$this->assertTrue( in_array( $id1, wp_list_pluck( $data, 'id' ) ) );
319
		$this->assertFalse( in_array( $id2, wp_list_pluck( $data, 'id' ) ) );
320
	}
321
322
	public function test_get_items_search() {
323
		wp_set_current_user( $this->user );
324
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
325
		$request->set_param( 'search', 'yololololo' );
326
		$response = $this->server->dispatch( $request );
327
		$this->assertEquals( 0, count( $response->get_data() ) );
328
		$yolo_id = $this->factory->user->create( array( 'display_name' => 'yololololo' ) );
329
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
330
		$request->set_param( 'search', (string) $yolo_id );
331
		$response = $this->server->dispatch( $request );
332
		$this->assertEquals( 1, count( $response->get_data() ) );
333
		// default to wildcard search
334
		$adam_id = $this->factory->user->create( array(
335
			'role'          => 'author',
336
			'user_nicename' => 'adam',
337
		) );
338
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
339
		$request->set_param( 'search', 'ada' );
340
		$response = $this->server->dispatch( $request );
341
		$data = $response->get_data();
342
		$this->assertEquals( 1, count( $data ) );
343
		$this->assertEquals( $adam_id, $data[0]['id'] );
344
	}
345
346 View Code Duplication
	public function test_get_items_slug_query() {
347
		wp_set_current_user( $this->user );
348
		$this->factory->user->create( array( 'display_name' => 'foo', 'user_login' => 'bar' ) );
349
		$id2 = $this->factory->user->create( array( 'display_name' => 'Moo', 'user_login' => 'foo' ) );
350
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
351
		$request->set_param( 'slug', 'foo' );
352
		$response = $this->server->dispatch( $request );
353
		$data = $response->get_data();
354
		$this->assertEquals( 1, count( $data ) );
355
		$this->assertEquals( $id2, $data[0]['id'] );
356
	}
357
358
	// 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.
359
	public function test_get_items_roles() {
360
		wp_set_current_user( $this->user );
361
		$tango = $this->factory->user->create( array( 'display_name' => 'tango', 'role' => 'subscriber' ) );
362
		$yolo  = $this->factory->user->create( array( 'display_name' => 'yolo', 'role' => 'author' ) );
363
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
364
		$request->set_param( 'roles', 'author,subscriber' );
365
		$response = $this->server->dispatch( $request );
366
		$data = $response->get_data();
367
		$this->assertEquals( 2, count( $data ) );
368
		$this->assertEquals( $tango, $data[0]['id'] );
369
		$this->assertEquals( $yolo, $data[1]['id'] );
370
		$request->set_param( 'roles', 'author' );
371
		$response = $this->server->dispatch( $request );
372
		$data = $response->get_data();
373
		$this->assertEquals( 1, count( $data ) );
374
		$this->assertEquals( $yolo, $data[0]['id'] );
375
		wp_set_current_user( 0 );
376
		$request->set_param( 'roles', 'author' );
377
		$response = $this->server->dispatch( $request );
378
		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 401 );
379
		wp_set_current_user( $this->editor );
380
		$request->set_param( 'roles', 'author' );
381
		$response = $this->server->dispatch( $request );
382
		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 403 );
383
	}
384
385
	public function test_get_items_invalid_roles() {
386
		wp_set_current_user( $this->user );
387
		$lolz = $this->factory->user->create( array( 'display_name' => 'lolz', 'role' => 'author' ) );
388
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
389
		$request->set_param( 'roles', 'ilovesteak,author' );
390
		$response = $this->server->dispatch( $request );
391
		$data = $response->get_data();
392
		$this->assertEquals( 1, count( $data ) );
393
		$this->assertEquals( $lolz, $data[0]['id'] );
394
		$request = new WP_REST_Request( 'GET', '/wp/v2/users' );
395
		$request->set_param( 'roles', 'steakisgood' );
396
		$response = $this->server->dispatch( $request );
397
		$data = $response->get_data();
398
		$this->assertEquals( 0, count( $data ) );
399
		$this->assertEquals( array(), $data );
400
	}
401
402
	public function test_get_item() {
403
		$user_id = $this->factory->user->create();
404
		wp_set_current_user( $this->user );
405
406
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $user_id ) );
407
408
		$response = $this->server->dispatch( $request );
409
		$this->check_get_user_response( $response, 'embed' );
410
	}
411
412
	public function test_prepare_item() {
413
		wp_set_current_user( $this->user );
414
		$request = new WP_REST_Request;
415
		$request->set_param( 'context', 'edit' );
416
		$user = get_user_by( 'id', get_current_user_id() );
417
		$data = $this->endpoint->prepare_item_for_response( $user, $request );
418
		$this->check_get_user_response( $data, 'edit' );
419
	}
420
421 View Code Duplication
	public function test_get_user_avatar_urls() {
422
		wp_set_current_user( $this->user );
423
424
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->editor ) );
425
426
		$response = $this->server->dispatch( $request );
427
428
		$data = $response->get_data();
429
		$this->assertArrayHasKey( 24,  $data['avatar_urls'] );
430
		$this->assertArrayHasKey( 48,  $data['avatar_urls'] );
431
		$this->assertArrayHasKey( 96,  $data['avatar_urls'] );
432
433
		$user = get_user_by( 'id', $this->editor );
434
		/**
435
		 * Ignore the subdomain, since 'get_avatar_url randomly sets the Gravatar
436
		 * server when building the url string.
437
		 */
438
		$this->assertEquals( substr( get_avatar_url( $user->user_email ), 9 ), substr( $data['avatar_urls'][96], 9 ) );
439
	}
440
441 View Code Duplication
	public function test_get_user_invalid_id() {
442
		wp_set_current_user( $this->user );
443
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/100' );
444
		$response = $this->server->dispatch( $request );
445
446
		$this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
447
	}
448
449
	public function test_get_user_empty_capabilities() {
450
		wp_set_current_user( $this->user );
451
		$this->allow_user_to_manage_multisite();
452
453
		$lolz = $this->factory->user->create( array( 'display_name' => 'lolz', 'roles' => '' ) );
454
		delete_user_option( $lolz, 'capabilities' );
455
		delete_user_option( $lolz, 'user_level' );
456
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/' . $lolz );
457
		$request->set_param( 'context', 'edit' );
458
		$response = $this->server->dispatch( $request );
459
		$data = $response->get_data();
460
461
		$this->assertEquals( $data['capabilities'], new stdClass() );
462
		$this->assertEquals( $data['extra_capabilities'], new stdClass() );
463
	}
464
465
	public function test_get_item_without_permission() {
466
		wp_set_current_user( $this->editor );
467
468
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->user ) );
469
		$response = $this->server->dispatch( $request );
470
471
		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 403 );
472
	}
473
474
	public function test_get_item_published_author_post() {
475
		$this->author_id = $this->factory->user->create( array(
476
			'role' => 'author',
477
		) );
478
		$this->post_id = $this->factory->post->create( array(
479
			'post_author' => $this->author_id,
480
		));
481
		wp_set_current_user( 0 );
482
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->author_id ) );
483
		$response = $this->server->dispatch( $request );
484
		$this->check_get_user_response( $response, 'embed' );
485
	}
486
487
	public function test_get_item_published_author_pages() {
488
		$this->author_id = $this->factory->user->create( array(
489
			'role' => 'author',
490
		) );
491
		wp_set_current_user( 0 );
492
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->author_id ) );
493
		$response = $this->server->dispatch( $request );
494
		$this->assertEquals( 401, $response->get_status() );
495
		$this->post_id = $this->factory->post->create( array(
496
			'post_author' => $this->author_id,
497
			'post_type'   => 'page',
498
		));
499
		$response = $this->server->dispatch( $request );
500
		$this->check_get_user_response( $response, 'embed' );
501
	}
502
503 View Code Duplication
	public function test_get_user_with_edit_context() {
504
		$user_id = $this->factory->user->create();
505
		$this->allow_user_to_manage_multisite();
506
507
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $user_id ) );
508
		$request->set_param( 'context', 'edit' );
509
510
		$response = $this->server->dispatch( $request );
511
		$this->check_get_user_response( $response, 'edit' );
512
	}
513
514
	public function test_get_item_published_author_wrong_context() {
515
		$this->author_id = $this->factory->user->create( array(
516
			'role' => 'author',
517
		) );
518
		$this->post_id = $this->factory->post->create( array(
519
			'post_author' => $this->author_id,
520
		));
521
		wp_set_current_user( 0 );
522
		$request = new WP_REST_Request( 'GET', sprintf( '/wp/v2/users/%d', $this->author_id ) );
523
		$request->set_param( 'context', 'edit' );
524
		$response = $this->server->dispatch( $request );
525
		$this->assertErrorResponse( 'rest_user_cannot_view', $response, 401 );
526
	}
527
528 View Code Duplication
	public function test_get_current_user() {
529
		wp_set_current_user( $this->user );
530
531
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/me' );
532
533
		$response = $this->server->dispatch( $request );
534
		$this->assertEquals( 302, $response->get_status() );
535
536
		$headers = $response->get_headers();
537
		$this->assertArrayHasKey( 'Location', $headers );
538
		$this->assertEquals( rest_url( 'wp/v2/users/' . $this->user ), $headers['Location'] );
539
	}
540
541 View Code Duplication
	public function test_get_current_user_without_permission() {
542
		wp_set_current_user( 0 );
543
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/me' );
544
		$response = $this->server->dispatch( $request );
545
546
		$this->assertErrorResponse( 'rest_not_logged_in', $response, 401 );
547
	}
548
549
	public function test_create_item() {
550
		$this->allow_user_to_manage_multisite();
551
		wp_set_current_user( $this->user );
552
553
		$params = array(
554
			'username'    => 'testuser',
555
			'password'    => 'testpassword',
556
			'email'       => '[email protected]',
557
			'name'        => 'Test User',
558
			'nickname'    => 'testuser',
559
			'slug'        => 'test-user',
560
			'role'        => 'editor',
561
			'description' => 'New API User',
562
			'url'         => 'http://example.com',
563
		);
564
565
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
566
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
567
		$request->set_body_params( $params );
568
569
		$response = $this->server->dispatch( $request );
570
		$data = $response->get_data();
571
		$this->assertEquals( 'http://example.com', $data['url'] );
572
		$this->check_add_edit_user_response( $response );
573
	}
574
575
	public function test_json_create_user() {
576
		$this->allow_user_to_manage_multisite();
577
		wp_set_current_user( $this->user );
578
579
		$params = array(
580
			'username' => 'testjsonuser',
581
			'password' => 'testjsonpassword',
582
			'email'    => '[email protected]',
583
		);
584
585
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
586
		$request->add_header( 'content-type', 'application/json' );
587
		$request->set_body( wp_json_encode( $params ) );
588
589
		$response = $this->server->dispatch( $request );
590
		$this->check_add_edit_user_response( $response );
591
	}
592
593 View Code Duplication
	public function test_create_user_without_permission() {
594
		wp_set_current_user( $this->editor );
595
596
		$params = array(
597
			'username' => 'homersimpson',
598
			'password' => 'stupidsexyflanders',
599
			'email'    => '[email protected]',
600
		);
601
602
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
603
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
604
		$request->set_body_params( $params );
605
		$response = $this->server->dispatch( $request );
606
607
		$this->assertErrorResponse( 'rest_cannot_create_user', $response, 403 );
608
	}
609
610 View Code Duplication
	public function test_create_user_invalid_id() {
611
		$this->allow_user_to_manage_multisite();
612
		wp_set_current_user( $this->user );
613
614
		$params = array(
615
			'id'       => '156',
616
			'username' => 'lisasimpson',
617
			'password' => 'DavidHasselhoff',
618
			'email'    => '[email protected]',
619
		);
620
621
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
622
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
623
		$request->set_body_params( $params );
624
		$response = $this->server->dispatch( $request );
625
626
		$this->assertErrorResponse( 'rest_user_exists', $response, 400 );
627
	}
628
629 View Code Duplication
	public function test_create_user_invalid_email() {
630
		$this->allow_user_to_manage_multisite();
631
		wp_set_current_user( $this->user );
632
633
		$params = array(
634
			'username' => 'lisasimpson',
635
			'password' => 'DavidHasselhoff',
636
			'email'    => 'something',
637
		);
638
639
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
640
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
641
		$request->set_body_params( $params );
642
		$response = $this->server->dispatch( $request );
643
644
		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
645
	}
646
647 View Code Duplication
	public function test_create_user_invalid_role() {
648
		$this->allow_user_to_manage_multisite();
649
		wp_set_current_user( $this->user );
650
651
		$params = array(
652
			'username' => 'maggiesimpson',
653
			'password' => 'i_shot_mrburns',
654
			'email'    => '[email protected]',
655
			'roles'    => array( 'baby' ),
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
		$response = $this->server->dispatch( $request );
662
663
		$this->assertErrorResponse( 'rest_user_invalid_role', $response, 400 );
664
	}
665
666
	public function test_update_item() {
667
		$user_id = $this->factory->user->create( array(
668
			'user_email' => '[email protected]',
669
			'user_pass' => 'sjflsfls',
670
			'user_login' => 'test_update',
671
			'first_name' => 'Old Name',
672
			'user_url' => 'http://apple.com',
673
		));
674
		$this->allow_user_to_manage_multisite();
675
		wp_set_current_user( $this->user );
676
677
		$userdata = get_userdata( $user_id );
678
		$pw_before = $userdata->user_pass;
679
680
		$_POST['email'] = $userdata->user_email;
681
		$_POST['username'] = $userdata->user_login;
682
		$_POST['first_name'] = 'New Name';
683
		$_POST['url'] = 'http://google.com';
684
685
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
686
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
687
		$request->set_body_params( $_POST );
688
689
		$response = $this->server->dispatch( $request );
690
		$this->check_add_edit_user_response( $response, true );
691
692
		// Check that the name has been updated correctly
693
		$new_data = $response->get_data();
694
		$this->assertEquals( 'New Name', $new_data['first_name'] );
695
		$user = get_userdata( $user_id );
696
		$this->assertEquals( 'New Name', $user->first_name );
697
698
		$this->assertEquals( 'http://google.com', $new_data['url'] );
699
		$this->assertEquals( 'http://google.com', $user->user_url );
700
701
		// Check that we haven't inadvertently changed the user's password,
702
		// as per https://core.trac.wordpress.org/ticket/21429
703
		$this->assertEquals( $pw_before, $user->user_pass );
704
	}
705
706 View Code Duplication
	public function test_update_item_existing_email() {
707
		$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...
708
		$user2 = $this->factory->user->create( array( 'user_login' => 'test_json_user2', 'user_email' => '[email protected]' ) );
709
		$this->allow_user_to_manage_multisite();
710
		wp_set_current_user( $this->user );
711
712
		$request = new WP_REST_Request( 'PUT', '/wp/v2/users/' . $user2 );
713
		$request->set_param( 'email', '[email protected]' );
714
		$response = $this->server->dispatch( $request );
715
		$this->assertInstanceOf( 'WP_Error', $response->as_error() );
716
		$this->assertEquals( 'rest_user_invalid_email', $response->as_error()->get_error_code() );
717
	}
718
719 View Code Duplication
	public function test_update_item_username_attempt() {
720
		$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...
721
		$user2 = $this->factory->user->create( array( 'user_login' => 'test_json_user2', 'user_email' => '[email protected]' ) );
722
		$this->allow_user_to_manage_multisite();
723
		wp_set_current_user( $this->user );
724
725
		$request = new WP_REST_Request( 'PUT', '/wp/v2/users/' . $user2 );
726
		$request->set_param( 'username', 'test_json_user' );
727
		$response = $this->server->dispatch( $request );
728
		$this->assertInstanceOf( 'WP_Error', $response->as_error() );
729
		$this->assertEquals( 'rest_user_invalid_argument', $response->as_error()->get_error_code() );
730
	}
731
732 View Code Duplication
	public function test_update_item_existing_nicename() {
733
		$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...
734
		$user2 = $this->factory->user->create( array( 'user_login' => 'test_json_user2', 'user_email' => '[email protected]' ) );
735
		$this->allow_user_to_manage_multisite();
736
		wp_set_current_user( $this->user );
737
738
		$request = new WP_REST_Request( 'PUT', '/wp/v2/users/' . $user2 );
739
		$request->set_param( 'slug', 'test_json_user' );
740
		$response = $this->server->dispatch( $request );
741
		$this->assertInstanceOf( 'WP_Error', $response->as_error() );
742
		$this->assertEquals( 'rest_user_invalid_slug', $response->as_error()->get_error_code() );
743
	}
744
745
	public function test_json_update_user() {
746
		$user_id = $this->factory->user->create( array(
747
			'user_email' => '[email protected]',
748
			'user_pass'  => 'sjflsfl3sdjls',
749
			'user_login' => 'test_json_update',
750
			'first_name' => 'Old Name',
751
			'last_name'  => 'Original Last',
752
		));
753
		$this->allow_user_to_manage_multisite();
754
		wp_set_current_user( $this->user );
755
756
		$params = array(
757
			'username'   => 'test_json_update',
758
			'email'      => '[email protected]',
759
			'first_name' => 'JSON Name',
760
			'last_name'  => 'New Last',
761
		);
762
763
		$userdata = get_userdata( $user_id );
764
		$pw_before = $userdata->user_pass;
765
766
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
767
		$request->add_header( 'content-type', 'application/json' );
768
		$request->set_body( wp_json_encode( $params ) );
769
770
		$response = $this->server->dispatch( $request );
771
		$this->check_add_edit_user_response( $response, true );
772
773
		// Check that the name has been updated correctly
774
		$new_data = $response->get_data();
775
		$this->assertEquals( 'JSON Name', $new_data['first_name'] );
776
		$this->assertEquals( 'New Last', $new_data['last_name'] );
777
		$user = get_userdata( $user_id );
778
		$this->assertEquals( 'JSON Name', $user->first_name );
779
		$this->assertEquals( 'New Last', $user->last_name );
780
781
		// Check that we haven't inadvertently changed the user's password,
782
		// as per https://core.trac.wordpress.org/ticket/21429
783
		$this->assertEquals( $pw_before, $user->user_pass );
784
	}
785
786 View Code Duplication
	public function test_update_user_role() {
787
		$user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
788
789
		wp_set_current_user( $this->user );
790
		$this->allow_user_to_manage_multisite();
791
792
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
793
		$request->set_param( 'roles', array( 'editor' ) );
794
		$response = $this->server->dispatch( $request );
795
796
		$new_data = $response->get_data();
797
798
		$this->assertEquals( 'editor', $new_data['roles'][0] );
799
		$this->assertNotEquals( 'administrator', $new_data['roles'][0] );
800
801
		$user = get_userdata( $user_id );
802
		$this->assertArrayHasKey( 'editor', $user->caps );
803
		$this->assertArrayNotHasKey( 'administrator', $user->caps );
804
	}
805
806 View Code Duplication
	public function test_update_user_role_invalid_privilege_escalation() {
807
		wp_set_current_user( $this->editor );
808
809
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $this->editor ) );
810
		$request->set_param( 'roles', array( 'administrator' ) );
811
		$response = $this->server->dispatch( $request );
812
813
		$this->assertErrorResponse( 'rest_cannot_edit_roles', $response, 403 );
814
		$user = get_userdata( $this->editor );
815
		$this->assertArrayHasKey( 'editor', $user->caps );
816
		$this->assertArrayNotHasKey( 'administrator', $user->caps );
817
	}
818
819
	public function test_update_user_role_invalid_privilege_deescalation() {
820
		if ( is_multisite() ) {
821
			return $this->markTestSkipped( 'Test only intended for single site.' );
822
		}
823
824
		$user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
825
826
		wp_set_current_user( $user_id );
827
828
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
829
		$request->set_param( 'roles', array( 'editor' ) );
830
		$response = $this->server->dispatch( $request );
831
832
		$this->assertErrorResponse( 'rest_user_invalid_role', $response, 403 );
833
834
		$user = get_userdata( $user_id );
835
		$this->assertArrayHasKey( 'administrator', $user->caps );
836
		$this->assertArrayNotHasKey( 'editor', $user->caps );
837
	}
838
839
	public function test_update_user_role_privilege_deescalation_multisite() {
840
		if ( ! is_multisite() ) {
841
			return $this->markTestSkipped( 'Test only intended for multisite.' );
842
		}
843
844
		$user_id = $this->factory->user->create( array( 'role' => 'administrator' ) );
845
846
		wp_set_current_user( $user_id );
847
		$user = wp_get_current_user();
848
		update_site_option( 'site_admins', array( $user->user_login ) );
849
850
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $user_id ) );
851
		$request->set_param( 'roles', array( 'editor' ) );
852
		$response = $this->server->dispatch( $request );
853
854
		$new_data = $response->get_data();
855
		$this->assertEquals( 'editor', $new_data['roles'][0] );
856
		$this->assertNotEquals( 'administrator', $new_data['roles'][0] );
857
	}
858
859
860 View Code Duplication
	public function test_update_user_role_invalid_role() {
861
		wp_set_current_user( $this->user );
862
		$this->allow_user_to_manage_multisite();
863
864
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $this->editor ) );
865
		$request->set_param( 'roles', array( 'BeSharp' ) );
866
		$response = $this->server->dispatch( $request );
867
868
		$this->assertErrorResponse( 'rest_user_invalid_role', $response, 400 );
869
870
		$user = get_userdata( $this->editor );
871
		$this->assertArrayHasKey( 'editor', $user->caps );
872
		$this->assertArrayNotHasKey( 'BeSharp', $user->caps );
873
	}
874
875 View Code Duplication
	public function test_update_user_without_permission() {
876
		wp_set_current_user( $this->editor );
877
878
		$params = array(
879
			'username' => 'homersimpson',
880
			'password' => 'stupidsexyflanders',
881
			'email'    => '[email protected]',
882
		);
883
884
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $this->user ) );
885
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
886
		$request->set_body_params( $params );
887
		$response = $this->server->dispatch( $request );
888
889
		$this->assertErrorResponse( 'rest_cannot_edit', $response, 403 );
890
	}
891
892 View Code Duplication
	public function test_update_user_invalid_id() {
893
		$this->allow_user_to_manage_multisite();
894
		wp_set_current_user( $this->user );
895
896
		$params = array(
897
			'id'       => '156',
898
			'username' => 'lisasimpson',
899
			'password' => 'DavidHasselhoff',
900
			'email'    => '[email protected]',
901
		);
902
903
		$request = new WP_REST_Request( 'PUT', sprintf( '/wp/v2/users/%d', $this->editor ) );
904
		$request->add_header( 'content-type', 'application/x-www-form-urlencoded' );
905
		$request->set_body_params( $params );
906
		$response = $this->server->dispatch( $request );
907
908
		$this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
909
	}
910
911 View Code Duplication
	public function test_delete_item() {
912
		$user_id = $this->factory->user->create( array( 'display_name' => 'Deleted User' ) );
913
914
		$this->allow_user_to_manage_multisite();
915
		wp_set_current_user( $this->user );
916
917
		$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...
918
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
919
		$request['force'] = true;
920
		$response = $this->server->dispatch( $request );
921
922
		$this->assertEquals( 200, $response->get_status() );
923
		$data = $response->get_data();
924
		$this->assertEquals( 'Deleted User', $data['name'] );
925
	}
926
927
	public function test_delete_item_no_trash() {
928
		$user_id = $this->factory->user->create( array( 'display_name' => 'Deleted User' ) );
929
930
		$this->allow_user_to_manage_multisite();
931
		wp_set_current_user( $this->user );
932
933
		$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...
934
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
935
		$response = $this->server->dispatch( $request );
936
		$this->assertErrorResponse( 'rest_trash_not_supported', $response, 501 );
937
938
		// Ensure the user still exists
939
		$user = get_user_by( 'id', $user_id );
940
		$this->assertNotEmpty( $user );
941
	}
942
943
	public function test_delete_user_without_permission() {
944
		$user_id = $this->factory->user->create();
945
946
		$this->allow_user_to_manage_multisite();
947
		wp_set_current_user( $this->editor );
948
949
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
950
		$request['force'] = true;
951
		$response = $this->server->dispatch( $request );
952
953
		$this->assertErrorResponse( 'rest_user_cannot_delete', $response, 403 );
954
	}
955
956
	public function test_delete_user_invalid_id() {
957
		$this->allow_user_to_manage_multisite();
958
		wp_set_current_user( $this->user );
959
960
		$request = new WP_REST_Request( 'DELETE', '/wp/v2/users/100' );
961
		$request['force'] = true;
962
		$response = $this->server->dispatch( $request );
963
964
		$this->assertErrorResponse( 'rest_user_invalid_id', $response, 404 );
965
	}
966
967
	public function test_delete_user_reassign() {
968
		$this->allow_user_to_manage_multisite();
969
970
		// Test with a new user, to avoid any complications
971
		$user_id = $this->factory->user->create();
972
		$reassign_id = $this->factory->user->create();
973
		$test_post = $this->factory->post->create(array(
974
			'post_author' => $user_id,
975
		));
976
977
		// Sanity check to ensure the factory created the post correctly
978
		$post = get_post( $test_post );
979
		$this->assertEquals( $user_id, $post->post_author );
980
981
		// Delete our test user, and reassign to the new author
982
		wp_set_current_user( $this->user );
983
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
984
		$request['force'] = true;
985
		$request->set_param( 'reassign', $reassign_id );
986
		$response = $this->server->dispatch( $request );
987
988
		$this->assertEquals( 200, $response->get_status() );
989
990
		// Check that the post has been updated correctly
991
		$post = get_post( $test_post );
992
		$this->assertEquals( $reassign_id, $post->post_author );
993
	}
994
995
	public function test_delete_user_invalid_reassign_id() {
996
		$user_id = $this->factory->user->create();
997
998
		$this->allow_user_to_manage_multisite();
999
		wp_set_current_user( $this->user );
1000
1001
		$request = new WP_REST_Request( 'DELETE', sprintf( '/wp/v2/users/%d', $user_id ) );
1002
		$request['force'] = true;
1003
		$request->set_param( 'reassign', 100 );
1004
		$response = $this->server->dispatch( $request );
1005
1006
		$this->assertErrorResponse( 'rest_user_invalid_reassign', $response, 400 );
1007
	}
1008
1009 View Code Duplication
	public function test_get_item_schema() {
1010
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users' );
1011
		$response = $this->server->dispatch( $request );
1012
		$data = $response->get_data();
1013
		$properties = $data['schema']['properties'];
1014
1015
		$this->assertEquals( 17, count( $properties ) );
1016
		$this->assertArrayHasKey( 'avatar_urls', $properties );
1017
		$this->assertArrayHasKey( 'capabilities', $properties );
1018
		$this->assertArrayHasKey( 'description', $properties );
1019
		$this->assertArrayHasKey( 'email', $properties );
1020
		$this->assertArrayHasKey( 'extra_capabilities', $properties );
1021
		$this->assertArrayHasKey( 'first_name', $properties );
1022
		$this->assertArrayHasKey( 'id', $properties );
1023
		$this->assertArrayHasKey( 'last_name', $properties );
1024
		$this->assertArrayHasKey( 'link', $properties );
1025
		$this->assertArrayHasKey( 'name', $properties );
1026
		$this->assertArrayHasKey( 'nickname', $properties );
1027
		$this->assertArrayHasKey( 'registered_date', $properties );
1028
		$this->assertArrayHasKey( 'slug', $properties );
1029
		$this->assertArrayHasKey( 'password', $properties );
1030
		$this->assertArrayHasKey( 'url', $properties );
1031
		$this->assertArrayHasKey( 'username', $properties );
1032
		$this->assertArrayHasKey( 'roles', $properties );
1033
1034
	}
1035
1036 View Code Duplication
	public function test_get_item_schema_show_avatar() {
1037
		update_option( 'show_avatars', false );
1038
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users' );
1039
		$response = $this->server->dispatch( $request );
1040
		$data = $response->get_data();
1041
		$properties = $data['schema']['properties'];
1042
1043
		$this->assertArrayNotHasKey( 'avatar_urls', $properties );
1044
	}
1045
1046
	public function test_get_additional_field_registration() {
1047
1048
		$schema = array(
1049
			'type'        => 'integer',
1050
			'description' => 'Some integer of mine',
1051
			'enum'        => array( 1, 2, 3, 4 ),
1052
			'context'     => array( 'embed', 'view', 'edit' ),
1053
		);
1054
1055
		register_rest_field( 'user', 'my_custom_int', array(
1056
			'schema'          => $schema,
1057
			'get_callback'    => array( $this, 'additional_field_get_callback' ),
1058
			'update_callback' => array( $this, 'additional_field_update_callback' ),
1059
		) );
1060
1061
		$request = new WP_REST_Request( 'OPTIONS', '/wp/v2/users' );
1062
1063
		$response = $this->server->dispatch( $request );
1064
		$data = $response->get_data();
1065
1066
		$this->assertArrayHasKey( 'my_custom_int', $data['schema']['properties'] );
1067
		$this->assertEquals( $schema, $data['schema']['properties']['my_custom_int'] );
1068
1069
		wp_set_current_user( 1 );
1070
		if ( is_multisite() ) {
1071
			$current_user = wp_get_current_user( 1 );
1072
			update_site_option( 'site_admins', array( $current_user->user_login ) );
1073
		}
1074
1075
		$request = new WP_REST_Request( 'GET', '/wp/v2/users/1' );
1076
1077
		$response = $this->server->dispatch( $request );
1078
		$this->assertArrayHasKey( 'my_custom_int', $response->data );
1079
1080
		$request = new WP_REST_Request( 'POST', '/wp/v2/users/1' );
1081
		$request->set_body_params(array(
1082
			'my_custom_int' => 123,
1083
		));
1084
1085
		$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...
1086
		$this->assertEquals( 123, get_user_meta( 1, 'my_custom_int', true ) );
1087
1088
		$request = new WP_REST_Request( 'POST', '/wp/v2/users' );
1089
		$request->set_body_params(array(
1090
			'my_custom_int' => 123,
1091
			'email' => '[email protected]',
1092
			'username' => 'abc123',
1093
			'password' => 'hello',
1094
		));
1095
1096
		$response = $this->server->dispatch( $request );
1097
1098
		$this->assertEquals( 123, $response->data['my_custom_int'] );
1099
1100
		global $wp_rest_additional_fields;
1101
		$wp_rest_additional_fields = array();
1102
	}
1103
1104
	public function test_additional_field_update_errors() {
1105
		$schema = array(
1106
			'type'        => 'integer',
1107
			'description' => 'Some integer of mine',
1108
			'enum'        => array( 1, 2, 3, 4 ),
1109
			'context'     => array( 'view', 'edit' ),
1110
		);
1111
1112
		register_rest_field( 'user', 'my_custom_int', array(
1113
			'schema'          => $schema,
1114
			'get_callback'    => array( $this, 'additional_field_get_callback' ),
1115
			'update_callback' => array( $this, 'additional_field_update_callback' ),
1116
		) );
1117
1118
		wp_set_current_user( 1 );
1119
		if ( is_multisite() ) {
1120
			$current_user = wp_get_current_user( 1 );
1121
			update_site_option( 'site_admins', array( $current_user->user_login ) );
1122
		}
1123
1124
		// Check for error on update.
1125
		$request = new WP_REST_Request( 'POST', sprintf( '/wp/v2/users/%d', $this->user ) );
1126
		$request->set_body_params( array(
1127
			'my_custom_int' => 'returnError',
1128
		) );
1129
1130
		$response = $this->server->dispatch( $request );
1131
1132
		$this->assertErrorResponse( 'rest_invalid_param', $response, 400 );
1133
1134
		global $wp_rest_additional_fields;
1135
		$wp_rest_additional_fields = array();
1136
	}
1137
1138
	public function additional_field_get_callback( $object ) {
1139
		return get_user_meta( $object['id'], 'my_custom_int', true );
1140
	}
1141
1142
	public function additional_field_update_callback( $value, $user ) {
1143
		if ( 'returnError' === $value ) {
1144
			return new WP_Error( 'rest_invalid_param', 'Testing an error.', array( 'status' => 400 ) );
1145
		}
1146
		update_user_meta( $user->ID, 'my_custom_int', $value );
1147
	}
1148
1149
	public function tearDown() {
1150
		parent::tearDown();
1151
	}
1152
1153
	protected function check_user_data( $user, $data, $context, $links ) {
1154
		$this->assertEquals( $user->ID, $data['id'] );
1155
		$this->assertEquals( $user->display_name, $data['name'] );
1156
		$this->assertEquals( $user->user_url, $data['url'] );
1157
		$this->assertEquals( $user->description, $data['description'] );
1158
		$this->assertEquals( get_author_posts_url( $user->ID ), $data['link'] );
1159
		$this->assertArrayHasKey( 'avatar_urls', $data );
1160
		$this->assertEquals( $user->user_nicename, $data['slug'] );
1161
1162
		if ( 'edit' === $context ) {
1163
			$this->assertEquals( $user->first_name, $data['first_name'] );
1164
			$this->assertEquals( $user->last_name, $data['last_name'] );
1165
			$this->assertEquals( $user->nickname, $data['nickname'] );
1166
			$this->assertEquals( $user->user_email, $data['email'] );
1167
			$this->assertEquals( (object) $user->allcaps, $data['capabilities'] );
1168
			$this->assertEquals( (object) $user->caps, $data['extra_capabilities'] );
1169
			$this->assertEquals( date( 'c', strtotime( $user->user_registered ) ), $data['registered_date'] );
1170
			$this->assertEquals( $user->user_login, $data['username'] );
1171
			$this->assertEquals( $user->roles, $data['roles'] );
1172
		}
1173
1174
		if ( 'edit' !== $context ) {
1175
			$this->assertArrayNotHasKey( 'roles', $data );
1176
			$this->assertArrayNotHasKey( 'capabilities', $data );
1177
			$this->assertArrayNotHasKey( 'registered', $data );
1178
			$this->assertArrayNotHasKey( 'first_name', $data );
1179
			$this->assertArrayNotHasKey( 'last_name', $data );
1180
			$this->assertArrayNotHasKey( 'nickname', $data );
1181
			$this->assertArrayNotHasKey( 'extra_capabilities', $data );
1182
			$this->assertArrayNotHasKey( 'username', $data );
1183
		}
1184
1185
		$this->assertEqualSets( array(
1186
			'self',
1187
			'collection',
1188
		), array_keys( $links ) );
1189
1190
		$this->assertArrayNotHasKey( 'password', $data );
1191
	}
1192
1193 View Code Duplication
	protected function check_get_user_response( $response, $context = 'view' ) {
1194
		$this->assertEquals( 200, $response->get_status() );
1195
1196
		$data = $response->get_data();
1197
		$userdata = get_userdata( $data['id'] );
1198
		$this->check_user_data( $userdata, $data, $context, $response->get_links() );
1199
	}
1200
1201
	protected function check_add_edit_user_response( $response, $update = false ) {
1202
		if ( $update ) {
1203
			$this->assertEquals( 200, $response->get_status() );
1204
		} else {
1205
			$this->assertEquals( 201, $response->get_status() );
1206
		}
1207
1208
		$data = $response->get_data();
1209
		$userdata = get_userdata( $data['id'] );
1210
		$this->check_user_data( $userdata, $data, 'edit', $response->get_links() );
1211
	}
1212
1213
	protected function allow_user_to_manage_multisite() {
1214
		wp_set_current_user( $this->user );
1215
		$user = wp_get_current_user();
1216
1217
		if ( is_multisite() ) {
1218
			update_site_option( 'site_admins', array( $user->user_login ) );
1219
		}
1220
1221
		return;
1222
	}
1223
}
1224